延迟加载
在conf.xml中配置延迟加载:
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnable" value="true"/>
<!-- 关闭立即加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
一对一查询学生时延迟加载学生证信息:
i.创建StudentCardMapper.xml:
<mapper namespace="cn.mybatis.mapper.StudentCardMapper">
<select id="queryStudent" resultType="StudentCard" parameterType="int">
select * from studentcard where cid = #{cid}
</select>
</mapper>
ii.将StudentCardMapper.xml添加到conf.xml中:
<mappers>
<mapper resource="cn/mybatis/mapper/StudentCardMapper.xml"/>
</mappers>
iii.配置StudentMapper.xml:
<select id="queryStudentWithLay" resultMap="card_student_map">
select * from student s
</select>
<resultMap id="card_student_map" type="student" >
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="sage" column="sage"/>
<result property="sgender" column="sgender"/>
<result property="gname" column="gname"/>
<!--
延迟加载studentcard
column参数关联主键
select延迟加载Mapper路径
-->
<association property="studentCard" javaType="StudentCard" column="cid" select="cn.mybatis.mapper.StudentCardMapper.queryStudent"/>
<!-- 立即加载地址 -->
<association property="address" javaType="Address">
<result property="homeAddress" column="homeaddress"/>
<result property="schoolAddress" column="schooladdress"/>
</association>
</resultMap>
iv.测试类:
@Test
public void test(){
SqlSession session = Utils.getSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List<student> students = studentMapper.queryStudentWithLay();
for (student stu : students){
System.out.println(stu.getSid()+" "+stu.getSname());
System.out.println(stu.getStudentCard().getCid() + stu.getStudentCard().getInfo());
}
session.close();
}
一对多查询班级信息延迟加载学生信息:
i.创建ClassMapper.xml:
<mapper namespace="cn.mybatis.mapper.ClassMapper">
<!-- 一对多 延迟加班级里的学生 -->
<select id="queryStudentOTMWithLazy" resultMap="map_student_class">
select * from class
</select>
<resultMap id="map_student_class" type="Class">
<id property="classid" column="classid"/>
<result property="classname" column="classname"/>
<!-- 延迟加载学生信息 -->
<collection property="students" ofType="student" select="cn.mybatis.mapper.StudentMapper.queryStudentInClassByLazy" column="classid"/>
</resultMap>
</mapper>
ii.创建接口ClassMapper:
public interface ClassMapper { List<Class> queryStudentOTMWithLazy();}
iii.在conf.xml中添加ClassMapper.xml映射:
<mappers>
<mapper resource="cn/mybatis/mapper/ClassMapper.xml"/>
</mappers>
iv.编写StudentMapper:
<select id="queryStudentInClassByLazy" resultType="student">
select * from student where classid = #{classid};
</select>
v.测试类:
@Test
public void test(){
SqlSession session = Utils.getSession();
ClassMapper classMapper = session.getMapper(ClassMapper.class);
List<Class> classes = classMapper.queryStudentOTMWithLazy();
for (Class cls : classes){
System.out.println(cls.getClassid()+" "+cls.getClassname());
List<student> students = cls.getStudents();
System.out.println(students);
}
session.close();
}
查询缓存
一级缓存(同一个SqlSession对象):
MyBatis默认开启一级缓存
a.第一次查询对象A,先去数据库查询对象A
b.然后将对象A放入内存(缓存),SqlSession对象中
c.若后面再次查询对象A,则会直接从缓存中获取,不会再到数据库中查询
d.若执行session.commit(),则会清理所有的缓存对象,将zs从SqlSession对象中移出
二级缓存:
MyBatis自带的二级缓存(同一个namespace生成的mapper对象):
MyBatis默认关闭二级缓存,需手动打开
a.如果是同一个SqlSession对象进行多次相同的查询,则直接进入一级缓存查询
b.如果不是同一个SqlSession对象进行多次相同的查询(但均来自同一个namespace),则进入二级缓存查询
c.若两个缓存都没有,就去数据库查
d.MyBatis二级缓存是将对象放入硬盘文件中,所以需要实现序列化接口, 将namespace对应的对象进行序列化,即实现Serializable接口,注意该对象级联属性和父类也全部需要实现序列化(序列化:内容→硬盘, 反序列换:硬盘→内存)
e.当执行session.close()进行二级缓存操作,将一级缓存对象放入二级缓存中(将内存中数据写入硬盘)
手动打开二级缓存:
a.在conf.xml中配置:
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
b.在对应namespace声明此namespace开启二级缓存
<mapper namespace="cn.mybatis.mapper.ClassMapper">
<!-- 声明此namespace开启二级缓存 -->
<cache/>
</mapper>
局部禁用某个方法二级缓存:
在xxxMapper.xml的select标签中增加属性useCache=“false"
<select id="xxxxxx" resultType="xxx" parameterType="xxx" useCache="false">
select * from xxxx where xx = #{xx}
</select>
清理二级缓存:
a.调用增删改session的commit()方法,不能调用查询自身的commit()方法(与一级缓存稍有区别)
b.在xxxMapper.xml的select标签中增加属性flushCache=“true”
<select id="xxxxxx" resultType="xxx" parameterType="xxx" flushCache="true">
select * from xxxxx where xx = #{xx}
</select>
**三方提供的二级缓存:**
常见的三方二级缓存:ehcache,memcache
整合三方提供的二级缓存(或自定义缓存),必须实现org.apache.ibatis.cache.Cache接口,该接口的默认实现类是PerpetualCache
整合ehcache二级缓存:
a.导入jar包 Ehcache-core.jar、mybatis-Ehcache.jar、slf4j-api.jar
b.编写Ehcache.xml配置文件
c.在xxxMapper.xml中开启Ehcache二级缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!-- 通过property覆盖Ehacache.xml中的值 -->
<property name="maxElementsInMemory" value="2000"/>
</cache>