概述
延迟加载
- 延迟加载:在真正使用数据时才发起查询,不用的时候不查询,按需加载,也称懒加载)
- 立即加载:不管用不用,只要一调用方法,马上就发起查询
- 使用时机:一般的在表关系中一对多、多对多时我们会使用延迟加载;多对一、一对一:通常采用立即加载。
- 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速 度要快。
- 坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。
使用步骤
首先我们要开启延迟加载,根据mybatis文档介绍,我们需要在主配置文件中配置这两个标签进行开启。
- lazyLoadingEnabled:延迟加载的全局开关,当开启时,所有关联对象都会延迟加载,特定关联关系中可以通过设置fetchType属性来覆盖该项的开关状态。默认值为false
- aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性,否则每个属性会按需求加载。默认值false
<!--配置参数-->
<settings>
<!--开启Mybatis支持延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
以教师、课程为例,一个教师可以带多门课,一门课可有多个教师带,明显示多对多关系,所以还存在一张关系表。
教师对应的xml映射文件:
<?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="cn.bjwlxy.dao.TeacherDao">
<resultMap id="teacherMap" type="teacher">
<id property="tid" column="tid"/>
<result property="tnum" column="tnum"></result>
<result property="tname" column="tname"></result>
<result property="tpassword" column="tpassword"></result>
<result property="tdept" column="tdept"></result>
</resultMap>
<!--查询所有教师-->
<select id="findAll" resultType="teacher">
select * from t_teacher
</select>
<!--根据id查询教师-->
<select id="findTeacherByTid" parameterType="int" resultType="teacher">
select * from t_teacher where tid=#{tid}
</select>
</mapper>
课程对应的xml映射文件:
<?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="cn.bjwlxy.dao.CourseDao">
<resultMap id="courseMap" type="course">
<id property="cid" column="cid"/>
<result property="cname" column="cname"></result>
<result property="ctype" column="ctype"></result>
<result property="ccredit" column="ccredit"></result>
<result property="ctime" column="ctime"></result>
</resultMap>
<!--查询所有课程-->
<select id="findAll" resultType="course">
select * from t_course
</select>
<!--根据id查询课程-->
<select id="findCourseByCid" resultType="course" parameterType="int">
select * from t_course where cid=#{cid}
</select>
</mapper>
教师和课程的关系对应的xml映射文件:
在没有使用延迟加载时,我们要查询教师课程的关系时,必须使用连接查询,而且是用一次就的查一次,效率低对数据库的压力也较大。使用了延迟加载,我们可以通过类似传参的方式,按需查询。
例如: < collection property=“teachers” ofType=“teacher” select=“cn.itcast.dao.TeacherDao.findTeacherByTid” column=“tid” >< /collection>
select属性就相当于是调用了cn.itcast.dao.TeacherDao接口中的findTeacherByTid(),而且传了一个 column="tid值tid。
在我们需要使用这些数据的时候就去“调用这个方法”进行查询。
<?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="cn.bjwlxy.dao.TeacherAndCourseDao">
<!--定义使用懒加载的结果封装类型-->
<resultMap id="lazyMap" type="teacherandcourse">
<id property="tcid" column="tcid"></id>
<result property="cid" column="cid"></result>
<result property="tid" column="tid"></result>
<result property="tcplace" column="tcplace"></result>
<result property="tctime" column="tctime"></result>
<result property="tcgrade" column="tcgrade"></result>
<!--select属性: 唯一标识 column属性:是用于指定使用哪个字段的值作为条件查询 -->
<collection property="courses" ofType="course" select="cn.bjwlxy.dao.CourseDao.findCourseByCid" column="cid"></collection>
<collection property="teachers" ofType="teacher" select="cn.bjwlxy.dao.TeacherDao.findTeacherByTid" column="tid"></collection>
</resultMap>
<!--没有使用懒加载:返回结果类型仍然是teacherandcourse实体类-->
<select id="findAll" resultType="teacherandcourse">
select * from t_tc
</select>
<!--使用了懒加载:返回类型是上面定义的lazyMap-->
<select id="findAllByLazyLoad" resultMap="lazyMap">
select * from t_tc
</select>
</mapper>
<!--可以发现不管有没有使用懒加载,我们的sql语句是一样的,这就避免的我们对数据库的压力,也同时提高了效率-->
可以发现不管有没有使用懒加载,我们的sql语句是一样的,这就避免的我们对数据库的压力,也同时提高了效率
缓存
什么是缓存:存在于内存中的临时数据
为什么使用缓存:减少和数据库的交互次数,提高执行效率
- 为什么样的数据可以使用缓存,什么样的数据不能使用?
适用于缓存:
经常查询并且不经常改变的
数据的正确与否对最终结果影响不大的
不适用缓存:
经常改变的数据
数据的正确与否对最终结果影响很大的,例如:商品的库存、银行的汇率、股市的牌价
mybatis的一级缓存
他指的是mybatis中sqlseesion对象的缓存。
当我们执行查询之后,查询的记过会同时存入到sqlseesion为我们提供的一块区域中,该区域的结构是一个map,当我们再次查询同样的数据,mybatis会先去sqlseesion中查询是否有,有的话会直接拿出来用。
当sqlseesion对象消失时,mybatis的一级缓存也就消失了.
注意:
mybatis中的一级缓存是sqlseesion范围的缓存,当调用sqlseesion的修改、添加、删除、commit()、close()、clearCache()等方法就会清空一级缓存。
二级缓存
mybatis的二级缓存:指的是mybatis中sqlseesionfactory对象的缓存,由同一个sqlseesionfactory对象创建的sqlseesion对象共享其缓存。
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
二级缓存使用步骤
让mybatis框架支持二级缓存,根据mybatis的文档,我们应该在主配置xml文件中配置。其实不用配也可,因为mybatis默认是开启二级缓存的
<!--配置支持二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
然后应该让当前的映射文件支持二级缓存,在对应的UseDao.xml文件配置
<!--开启user支持二级缓存-->
<cache/>
最后让当前操作支持二级缓存即可,在select标签中配置
增加属性:useCache=“true”
<!--配置查询所有-->
<select id="findAll" resultType="cn.itcast.domain.User">
select * from user
</select>
<select id="findById" resultType="cn.itcast.domain.User" useCache="true">
select * from user where id=#{uid}
</select>
注意:
二级缓存缓存的是数据不是对象,再次从二级缓存中获取时,只是再创建一个对象,把数据封装给这个对象,并不是返回原对象
第一个sqlSession去查询用户信息,查询到用户信息会将查询数据存储到二级缓存中。
第二个sqlSession 再去查询与第一个 sqlSession相同的用户信息,首先会去缓存中找是否存在数据,如果存在直接从缓存中取出数据
如果第三个SqlSession 去执行相同 mapper 映射下 sql,执行 commit 提交,将会清空该 mapper 映射下的二级缓存区域的数据。
最后
以上就是简单奇迹为你收集整理的mybatis的延迟加载、缓存机制简单用延迟加载缓存的全部内容,希望文章能够帮你解决mybatis的延迟加载、缓存机制简单用延迟加载缓存所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复