mybatis的延迟加载&缓存
一、延迟加载:在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
-
assocation 实现延迟加载
1. **账户的持久层 DAO 接口** :List<Account> findAll(); 2. **账户的持久层映射文件**
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ityouxin.dao.IAccountDao"> <!-- 建立对应关系 --> <resultMap type="account" id="accountMap"> <id column="aid" property="id"/> <result column="uid" property="uid"/> <result column="money" property="money"/> <!-- 它是用于指定从表方的引用实体属性的 --> <association property="user" javaType="user" select="com.ityouxin.dao.IUserDao.findById" column="uid"> </association> </resultMap> <select id="findAll" resultMap="accountMap"> select * from account </select> </mapper> select: 填写我们要调用的 select 映射的 id column : 填写我们要传递给 select 映射的参数
3. 用户的持久层接口和映射文件
public interface IUserDao { /** * 根据 id 查询 * @param userId * @return */ User findById(Integer userId); } <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ityouxin.dao.IUserDao"> <!-- 根据 id 查询 --> <select id="findById" resultType="user" parameterType="int" > select * from user where id = #{uid} </select> </mapper>
- 开启Mybatis的延迟加载
<!-- 开启延迟加载的支持 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
-
使用Collection实现延迟加载
- 在User实体类中加入List accounts 属性
- 编写用户和账户持久层接口的的方法:List findAll();
- 编写用户持久层的映射配置
<resultMap type="user" id="userMap"> <id column="id" property="id"></id> <result column="username" property="username"/> <result column="address" property="address"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型 select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称) column 是用于指定使用哪个字段的值作为条件查询 --> <collection property="accounts" ofType="account" select="com.ityouxin.dao.IAccountDao.findByUid" column="id"> </collection> </resultMap> <!-- 配置查询所有操作 --> <select id="findAll" resultMap="userMap"> select * from user </select> <collection>标签: 主要用于加载关联的集合对象 select 属性: 用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id column 属性: 用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,所以就写成 id 这一个字段名了
- 编写账户持久层映射配置
<!-- 根据用户 id 查询账户信息 --> <select id="findByUid" resultType="account" parameterType="int"> select * from account where uid = #{uid} </select>
二、Mybatis缓存:
-
证明一级缓存的存在:一般一级缓存是sqlsession级别的缓存,只要Sqlsession没有flush或者close,一级缓存就存在
-
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。 /** * 测试一级缓存 */ @Test public void testFirstLevelCache(){ User user1 = userDao.findById(41); System.out.println(user1); // sqlSession.close(); //再次获取 SqlSession 对象 // sqlSession = factory.openSession(); sqlSession.clearCache();//此方法也可以清空缓存 userDao = sqlSession.getMapper(IUserDao.class); User user2 = userDao.findById(41); System.out.println(user2); System.out.println(user1 == user2); } /** * 测试缓存的同步 */ @Test public void testClearlCache(){ //1.根据 id 查询用户 User user1 = userDao.findById(41); System.out.println(user1); //2.更新用户信息 user1.setUsername("update user clear cache"); user1.setAddress("北京市海淀区"); userDao.updateUser(user1); //3.再次查询 id 为 41 的用户 User user2 = userDao.findById(41); System.out.println(user2); System.out.println(user1 == user2); } 当执行sqlSession.close()后,再次获取sqlSession并查询id=41的User对象时,又重新执行了sql语句,从数据库进行了查询操作。
-
Mybatis二级缓存:二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
- 二级缓存的开启和关闭
第一步:在 SqlMapConfig.xml 文件开启二级缓存 <settings> <!-- 开启二级缓存的支持 --> <setting name="cacheEnabled" value="true"/> </settings> 因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为false 代表不开启二级缓存。 2.2.2.2 第二步:配置相关的 Mapper 映射文件 <cache>标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ityouxin.dao.IUserDao"> <!-- 开启二级缓存的支持 --> <cache></cache> </mapper> 2.2.2.3 第三步:配置 statement 上面的 useCache 属性 <!-- 根据 id 查询 --> <select id="findById" resultType="user" parameterType="int" useCache="true"> select * from user where id = #{uid} </select> 将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用 二级缓存,如果不使用二级缓存可以设置为 false。 注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
-
二级缓存的注意事项
当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这样就可以使用序列化方式来保存对象。:public class User implements Serializable { }
-