Eight years ago in 2002, I created the iBATIS Data Mapper and introduced SQL Mapping as an approach to persistence layer development. Shortly thereafter, I donated the iBATIS name and code to the Apache Software Foundation. The ASF has been the home of iBATIS for the past six years.
A lot changes in six years. By 2010 we’ve seen a great deal of innovation and change in the areas of development methodology, source control, social networking and open-source infrastructure.
……
Therefore, the entire core development team of iBATIS has decided to continue the development of the framework at a new home and with a new name(mybatis).
一、单独使用ibatis
ibatis全部只有一个几百k的jar:ibatis-sqlmap-2.3.4.726.jar
还需要数据库驱动,这里用MySQL:mysql-connector-java-5.1.46.jar
以下代码基于两个思路:
1、把平时直接写在dao层的sql抽离,写在配置文件中
2、把pojo对象的属性值拼接到sql,执行,把结果封装到pojo对象
pojo实体类:
public class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
实体类的sqlMap配置文件Student.xml
:
<sqlMap>
<typeAlias alias="Student" type="com.lwr.ibatis.bean.Student" />
<select id="selectAllStudent" resultClass="Student">
select * from
student
select>
<select id="selectStudentById" parameterClass="int" resultClass="Student">
select * from student where id=#id#
select>
<select id="selectStudentByName" parameterClass="String"
resultClass="Student">
select name,age,id from student where name like
'%$name$%'
select>
<insert id="addStudent" parameterClass="Student">
insert into
student(name,age) values
(#name#,#age#);
<selectKey resultClass="int" keyProperty="id">
SELECT LAST_INSERT_ID() AS VALUE
selectKey>
insert>
<delete id="deleteStudentById" parameterClass="int">
delete from student where id=#id#
delete>
<update id="updateStudent" parameterClass="Student">
update student set
name=#name#,age=#age# where id=#id#
update>
sqlMap>
ibatis配置文件sqlMapConfig.xml
:
<sqlMapConfig>
<properties resource="SqlMap.properties" />
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${username}" />
<property name="JDBC.Password" value="${password}" />
dataSource>
transactionManager>
<sqlMap resource="com/lwr/ibatis/sqlmap/Student.xml" />
sqlMapConfig>
dao实现类,通过ibatis执行sql:
public class StudentDaoImpl {
private static SqlMapClient sqlMapClient = null;
// 读取配置文件SqlMapConfig.xml,解读Student.xml
static {
try {
Reader reader = Resources
.getResourceAsReader("SqlMapConfig.xml");
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public List selectAllStudent() {
List students = null;
try {
/*
* selectAllStudent是Student.xml配置中的id
*/
students = sqlMapClient.queryForList("selectAllStudent");
} catch (SQLException e) {
e.printStackTrace();
}
return students;
}
public Student selectStudentById(int id) {
Student student = null;
try {
/*
* Student.xml中parameterClass="int",也就是需要一个int参数
* Student.xml中resultClass="Student",也就是查询结果封装到Student类
*/
student = (Student) sqlMapClient.queryForObject(
"selectStudentById", id);
} catch (SQLException e) {
e.printStackTrace();
}
return student;
}
public boolean updateStudent(Student student) {
boolean flag = false;
Object object = false;
try {
/*
* student对象作为参数,会对应Student.xml中配置的参数,通过getter取值
*/
object = sqlMapClient.update("updateStudent", student);
System.out.println("更新学生信息的返回值:" + object + ",返回影响的行数");
} catch (SQLException e) {
e.printStackTrace();
}
if (object != null) {
flag = true;
}
return flag;
}
}
二、spring整合ibatis
由于spring-orm-4版本已经不再集成ibatis,改为使用mybatis-spring的独立orm映射包。
所以,demo项目使用spring3整合ibatis。
概要:整合之后的不同之处在于,ibatis的bean生成和事务管理交由spring容器处理。ibatis的配置文件中的数据源给到spring来注入。
项目结构:
maven导入的包:
web.xml
:略
springmvc-servlet.xml
:略
jdbc.properties
:略.
applicationContext.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:annotation-config />
<context:component-scan base-package="com.lwr.ibatis">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
bean>
beans>
SqlMapConfig.xml
:
<sqlMapConfig>
<sqlMap resource="com/lwr/ibatis/sqlmap/User.xml" />
sqlMapConfig>
User.xml
:
<sqlMap>
<typeAlias alias="User" type="com.lwr.ibatis.bean.User" />
<select id="selectAllUser" resultClass="User">
select * from user
select>
<select id="selectUserById" parameterClass="int" resultClass="User">
select * from user where id=#id#
select>
<select id="selectUserByName" parameterClass="String"
resultClass="User">
select name,age,id from user where name like '%$name$%'
select>
<insert id="addUser" parameterClass="User">
insert into user(name,age) values(#name#,#age#);
<selectKey resultClass="int" keyProperty="id">
SELECT LAST_INSERT_ID() AS VALUE
selectKey>
insert>
<delete id="deleteUserById" parameterClass="int">
delete from user where id=#id#
delete>
<update id="updateUser">
update user set name=#name# where name=#name1# or name=#name2#
update>
sqlMap>
Dao实现类UserDaoImpl.java
package com.lwr.ibatis.dao.impl;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.lwr.ibatis.bean.User;
import com.lwr.ibatis.dao.UserDao;
@Transactional
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Autowired
private SqlMapClient sqlMapClient;
//@Autowired
//private JdbcTemplate jdbcTemplate;
public List selectAllStudent() {
List list = null;
try {
list = sqlMapClient.queryForList("selectAllUser");
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
@Override
public String addUser(String name, int age) {
try {
User user = new User();
user.setName(name);
user.setAge(age);
Object result = sqlMapClient.insert("addUser", user);
return result.toString();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public String updateUser(String param1, String param2, String param3) {
try {
Map map = new HashMap();
map.put("name", param1);
map.put("name1", param2);
map.put("name2", param3);
Object result = sqlMapClient.update("updateUser", map);
return result.toString();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List selecAllUser() {
try {
List list = sqlMapClient.queryForList("selectAllUser");
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
解读:
从上面代码可见:
1、spring整合ibatis,sqlMapClient对象由spring的bean工厂生成。
2、spring的事务管理器transactionManager配置了sqlMapClient的数据源dataSource,sqlMapClient对象的CUID操作的事务由spring管理。
3、sql语句、参数、返回结果配置在User.xml中,每个id都是一个statement。
ibatis是个“半自动化”的关系映射ORM框架。
它把写在dao层的sql语句全部放到一个sqlMap配置文件中,并给每条sql配置一个id,在执行sqlMapClient对象的增删查改时通过id找到对应sql。
其实每个id和sql会被解析成一个MappedStatement对象,Dao层的sqlMapClient方法是通过id查找对应MappedStatement对象来执行的。
在sqlMap配置文件中,parameterClass和resultClass是配置sql中的参数类型和查询结果类型。参数类型对应有个ParameterMap存储、查询结果类型对应有个ResultMap存储。
每次执行sql,拿到当前id的MappedStatement对象,拿到对应参数ParameterMap,拿到结果类型映射ResultMap;
通过MappedStatement的内容,执行connection的prepareStatement()方法;
然后通过PrepareStatement对象的参数设置方法(setString,setInt…),把ParameterMap内容按顺序设置;
执行完毕后,把执行结果resultSet按ResultMap内容封装到pojo对象(如果返回pojo)中并返回。