【MyBatis学习笔记】延迟加载、查询缓存(一级缓存、二级缓存)

延迟加载

在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>
发布了46 篇原创文章 · 获赞 1 · 访问量 2404

猜你喜欢

转载自blog.csdn.net/weixin_43708069/article/details/104420094