MyBatis是一款优秀的持久层框架,支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取数据集。MyBatis使用简单的XML或注解来配置和映射原生类型、接口和JAVA的POJO。
实际开发中mybaits通常是在Spring环境中使用的,这样能大大提高开发效率。
myBatis的开发和执行流程如下:
Mapper接口映射成SQL语句:
myBatis的注解和XML本身是一个元数据的载体,最终起作用的是myBatis的核心类。其中比较重要的几个:
1. SqlSessionFactoryBuilder:用来创建SqlSessionFactory的实例,一旦创建了SqlSessionFactory,就不再需要它了。
2. SqlSessionFactory:最基础的一个类,用来创建会话(即SqlSession的实例),其生命周期与整个系统的生命周期相同,在系统运行的任何时候都可以使用它查询大当前数据库的配置信息等。SqlSessionFactory的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
3. SqlSession:真正的和数据库之间的会话,线程不安全,其生命周期与使用它的线程相同。
SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。这个对象包括:SQL语句,输入参数映射信息,输出结果集映射信息。
4.各种Mapper:承载了实际的业务逻辑,生命周期较短,由SqlSession创建。
看一下具体的使用方式:
先在数据库中新建表user:
create table users (
id int primary key auto_increment,
name varchar(20),
age int
);
insert into users (name, age) values('Tom', 12);
insert into users (name, age) values('Jack', 11);
实体类:
public class User {
private int id;
private String name;
private int age;
//get和set方法
}
1.表映射配置文件userDao.xml
<mapper namespace="com.luoxn28.test.UserDao">
<insert id="insert" parameterType="com.luoxn28.test.User">
INSERT users (name, age) VALUES (#{name}, #{age})
insert>
<update id="update" parameterType="com.luoxn28.test.User">
UPDATE users set name=#{name}, age=#{age} where id=#{id}
update>
<delete id="delete" parameterType="int">
DELETE FROM users where id=#{id}
delete>
<select id="getById" parameterType="int" resultType="com.luoxn28.test.User">
SELECT * FROM users WHERE id=#{id}
select>
<select id="getAll" resultType="com.luoxn28.test.User">
SELECT * FROM users
select>
mapper>
上面主要由四个标签select,insert,delete,update,每个标签中还对应着一些属性:
属性 | 描述 |
---|---|
id | sql操作的名称 |
parameterType | 传入参数的类型 |
resultType | 返回结果类型 |
resultMap | 使用指定的resultMap来映射结果集。resultMap 和 resultType只能二选一 |
flushCache | 如果为true,每次调用,一级缓存和二级缓存都会回写。select语句中默认为false |
useCache | 如果为true,结果将在二级缓存中缓存。select语句中默认为true |
timeout | 设置超时,若超时则抛出异常 |
fetchSize | 尝试在获取数据时分批获取 |
statementType | STATEMENT,PREPARED或者CALLABLE. 分别对应JDBC中的Statement,PreparedStatement和CallableStatement respectively。默认PREPARED |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE或者SCROLL_INSENSITIVE。默认为空 |
databaseId | 使用特定的databaseIdProvider |
resultOrdered | 嵌套查询时使用 |
resultSets | 多返回集合时使用 |
2.MyBatis配置文件mybatisConfig.xml
<configuration>
<mappers>
<mapper resource="com/luoxn28/test/userMapper.xml"/>
mappers>
configuration>
这里也可以用
批量定义别名。
<configuration>
<typeAliases>
<typeAlias type="com/luoxn28/test/userMapper.xml" alias="user"/>
<package name="com/luoxn28/test"/>
typeAliases>
<mappers>
<mapper resource="sqlmap/User.xml" />
<mapper resource="mapper/UserMapper.xml" />
mappers>
configuration>
3.Spring的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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClassName" value="${driverClass}"/>
<property name="url" value="${jdbcUrl}"/>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.luoxn28.test"/>
<property name="configLocation" value="classpath:mybatisConfig.xml"/>
bean>
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.luoxn28.test.UserDao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
bean>
beans>
4.创建接口和实现类
public interface UserDao {
public int insert(User user);
public int update(User user);
public int delete(int id);
public User getById(int id);
public List<User> getAll();
}
测试:
public class SMTest {
private ApplicationContext context = null;
private UserDao userDao = null;
@BeforeTest
public void init() {
context = new ClassPathXmlApplicationContext("applicationContext.xml");
userDao = (UserDao) context.getBean("userDao");
}
@Test
public void testInsert() {
System.out.println(userDao.insert(new User("luoxn28", 23)));
}
@Test
public void testUpdate() {
System.out.println(userDao.update(new User(10, "luoxn28", 22)));
}
@Test
public void testDelete() {
System.out.println(userDao.delete(10));
}
@Test
public void testGetById() {
System.out.println(userDao.getById(10));
}
@Test
public void getGetAll() {
System.out.println(userDao.getAll());
}
}