MyBatis配置详解(二)
1.配置内容和顺序
MybatisConfig.xml是Mybatis的全局配置文件,其配置的内容和顺序如下:
1:properties(属性)
2:settings(全局配置参数)
3:typeAliases(类型别名)
4:typeHandlers(类型处理器)
5:objectFactory(对象工厂)
6:plugins(插件)
7:environments(环境集合属性对象)
8: environment(环境子属性对象)
9: transactionManager(事务管理)
10: dataSource(数据源)
11:mappers(映射器)
1.1. properties(属性)
- properties属性
可以加载数据库配置信息。在src/main/resources中创建db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
在MybatisConfig.xml中加载db.properties
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 读取数据库配置信息 -->
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
</configuration>
- mappers(映射器)
mappers用于加载映射文件到全局配置文件中,Mybatis有四种加载映射文件的方法。本别是resource、url、class、package。参考配置如下:
<mappers>
<mapper resource="userInfoMapper.xml" />
<mapper url="file:///D:\mybatis-1\config\userInfoMapper.xml" />
<mapper class="cn.it.mapper.IUsersMapper"/>
<package name="cn.it.mapper"/>
</mappers>
resource
使用相对于类路径的资源,如:
<mapper resource="userInfoMapper.xml" />
这种方法一次加载一个映射文件。
url
使用完全限定路径,如:
<mapper url="file:///D:\mybatis-1\config\userInfoMapper.xml" />
这种方法一次加载一个映射文件。由于使用了绝对路径,不建议使用这种方式。
class
使用mapper接口路径,如
<mapper class="cn.itlaobing.mybatis.mapper.IUserInfoMapper"/>
注意:这种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
package
注册指定包下的所有mapper接口,如:
<package name="cn.itlaobing.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。这种方式可以实现批量加载,推荐使用。
2. 输入映射parameterType
输入映射是由Mapper Statement 的parameterType属性设置的。所有的输入映射都需要以下两步来完成:
- Mapper映射配置
- Mapper接口定义
Mybatis的输入映射就是将Java的对象映射为SQL语句中列的值。Mybatis的输入映射形式包括简单类型输入映射、POJO类型输入 映射、VO类型输入映射、HashMap输入映射。
- 简单类型输入映射
需求:根据id查询指定的用户
- Mapper映射配置
<select id="findUserInfoById" parameterType="int" resultType="cn.it.model.UsersModel"> select * from userInfo where userid=#{userid}
</select>
- Mapper接口定义
public UsersModel findUsersById(int userid);
- POJO类型输入映射
需求:添加用户
- Mapper映射配置
<insert id="insertUsers" parameterType="cn.it.model.UsersModel">
<selectKey keyProperty="userid" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
insert into users(username,password,createtime) values(#{username},#{password},#{createtime});
</insert>
- Mapper接口定义
public void insertUsers(UsersModel model);
- HashMap类型输入映射
需求:根据用户名和性别查询用户
- Mapper映射配置
<select id="findByHashMap" parameterType="hashmap" resultType="cn.it.model.UsersModel"> SELECT * FROM users WHERE username =#{username} AND password=#{password}
</select>
- Mapper接口定义
public List<UsersModel> findByHashMap(HashMap<String, String> hashMap) ;
3. 输出映射resultType
输入映射是由Mapper Statement 的resultType属性设置的。所有的输出映射都需要以下两步来完成:
- Mapper映射配置
- Mapper接口定义
Mybatis的输出映射就是将查询的结果映射为Java的对象。Mybatis可以将查询出的单个数据(如聚合查询)映射为Java的简单类型,将查询出的单条记录映射为POJO对象,将查询出的多条记录映射为集合。
如果查询单条记录,Mybatis调用selectOne()方法,并将查询结果映射为POJO对象。如果查询多条记录,Mybatis调用selectList()方法,并将查询结果映射为POJO的集合。Mybatis调用selectOne()还是selectList()是根据Mapper接口中方法的返回值决定的,如果返回值是集合类型,则调用selectList()方法,如果返回值是POJO对象,则调用selectOne()方法。
- 简单类型输出映射
需求:查询userInfo表的记录数量
- Mapper映射配置
<select id="findUsersCount" resultType="int">
select count(1) from userInfo
</select>
- Mapper接口定义
public int findUsersCount();
- POJO对象输出映射
需求:根据id查询指定的用户,本例同findUserInfoById。
- Mapper映射配置
<select id="findUsersById" parameterType="int" resultType="cn.it.model.UsersModel"> select * from users where userid=#{userid}
</select>
- Mapper接口定义
public UsersModel findUsersById(int id);
- HashMap类型输出映射
需求:查询所有的用户。
- Mapper映射配置
<select id="findToHashMap" resultType="hashmap">
select * from users
</select>
- Mapper接口定义
public List<Map<String, String>> findToHashMap() throws Exception;
4.动态sql
输入用户名、用户性别和订单号
select * from userInfos where username=#{username}
and gender=#{gender}and id
in(select userId from userorders where orderid=#{orderId})
像这种多条件查询,其中的where子句部分需要根据用户选择的查询条件动态拼接。Mybatis提供了动态SQL,动态SQL是指通过Mybatis提供的各种标签实现动态拼接SQL语句。
- Mapper映射配置
<!-- 动态SQL-多条件查询 -->
<select id="findUsersCondition" parameterType="hashmap"resultType="cn.it.model.UsersModel">
select * from users
<!-- where标签自动去掉满足条件的第一个and -->
<where>
<!-- 如果userName不为空,则将userName拼接到查询条件中 -->
<if test="username!=null">
and userName=#{username}
</if>
<!-- 如果gender不为空,则将gender拼接到查询条件中 -->
<if test="password!=null">
and password=#{password}
</if>
<!-- 如果orderId不为空,则将orderId拼接到查询条件中 -->
<if test="orderId!=null">
and id in(select userId from orders where id=#{orderId})
</if>
</where>
</select>
- Mapper接口定义
public List<UserInfosModel> findUserInfosCondition(HashMap<String, String> condition);
5.懒加载
需要查询关联信息时,使用Mybatis懒加载特性可有效的减少数据库压力,首次查询只查询主表信息,关联表的信息在用户获取时再加载。
Mybatis一对一关联的association和一对多的collection可以实现懒加载。懒加载时要使用resultMap,不能使用resultType。
- 启动懒加载
Mybatis默认没有打开懒加载配置,需要在SqlMapperConfig.xml中通过settings配置lazyLoadingEnabled、aggressiveLazyLoading来开启懒加载。
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
6. 缓存
- 为什么使用缓存
缓存(也称作cache)的作用是为了减去数据库的压力,提高数据库的性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库执行select语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。缓存是使用Map集合缓存数据的。
Mybatis有一级缓存和二级缓存。一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
- 一级缓存介绍
一级缓存区域是根据SqlSession为单位划分的。每次查询会先从缓存区域查找,如果找不到则从数据库查询,从数据库查询后将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap缓存数据,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。
- 二级缓存原理介绍
二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询的数据缓存在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。
每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。
- 配置二级缓存配置
第一步:启用二级缓存
在SqlMapperConfig.xml中启用二级缓存,如下代码所示,当cacheEnabled设置为true时启用二级缓存,设置为false时禁用二级缓存。
<setting name="cacheEnabled" value="true"/>
第二步:POJO序列化
将所有的POJO类实现序列化接口Java.io. Serializable。
第三步:配置映射文件
先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。
- 配置二级缓存配置
第一步:启用二级缓存
在SqlMapperConfig.xml中启用二级缓存,如下代码所示,当cacheEnabled设置为true时启用二级缓存,设置为false时禁用二级缓存。
<setting name="cacheEnabled" value="true"/>
第二步:POJO序列化
将所有的POJO类实现序列化接口Java.io. Serializable。
第三步:配置映射文件
在Mapper映射文件中添加,表示此mapper开启二级缓存。