Mybatis-04 懒加载&缓存&注解开发

1.Mybatis延迟加载策略

1.1 什么是延迟加载(懒加载)?

简单的说,就是要用到数据时才加载,否则不加载。
好处:先单表查询,要用时才去关联查询,提高数据库性能。
坏处:大批量数据查询的时候,查询可能消耗时间,影响用户体验。

1.2 Mybatis的延迟加载

上一个文章说要,association、collection实现了一对一及一对多的映射,他们时具有延迟加载功能的。
一般一对一用立即加载,一对多用延迟加载。

1.2.1 使用assocation实现延迟加载

需求如:查询账户(Account)信息并且关联查询用户(User)信息。如果先查询账户(Account)信息即可满足要求,当我们需要查询用户(User)信息时再查询用(User)信息。把对用户(User)信息的按需去查询就是延迟加载。
1.映射文件的配置
在association标签添加select属性,指定查找的方法唯一表示。
column属性,传递的参数
 <!-- 定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一对一的关系映射:配置封装user的内容
        select属性指定的内容:查询用户的唯一标识:
        column属性指定的内容:用户根据id查询时,所需要的参数的值
        -->
        <association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById"></association>
    </resultMap>
2.主配置文件的配置
 <!--配置参数-->
    <settings>
        <!--开启Mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

1.2.2 使用collection实现延迟加载

<collection>结点中也有select属性,column属性。
和上类似:
    1.配置主配置文件
    2.配置映射文件

    <!-- 定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一对一的关系映射:配置封装user的内容
        select属性指定的内容:查询用户的唯一标识:
        column属性指定的内容:用户根据id查询时,所需要的参数的值
        -->
        <association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById"></association>
    </resultMap>

2.Mybatis缓存

2.1 一级缓存

一级缓存时sqlSession级别的缓存,只要sqlSession没有flush或close,就存在。


可以发现,查询了2次,但最后一次执行并没有向数据库查询,这就是一级缓存的作用了,而是从一级缓存中查询。

2.1.1 一级缓存分析

1. 是SqlSession范围的缓存,当条用了SqlSession的修改,添加,删除,commit(),close()等方法,缓存就会清空。
很好理解,是为了防止数据库的数据和缓存的数据不一致。
流程,如查询id为1的用户信息,先去缓存查找id为1的信息,如果有就读取,如果没有,从数据库中查询,得到用户信息,存入缓存。
如果sqlSession去执行了commit操作(增删改),清空一级缓存,避免脏读。

PS: sqlSession.clearCache();这个方法也可清除缓存。

2.2 二级缓存

二级缓存是mapper映射级别的缓存,多个sqlSession去操作同一个Mapper映射的sql语句,多个sqlSession共用二级缓存,是跨越sqlSession的。
![](https://img2018.cnblogs.com/blog/1882316/202002/1882316-20200210154006177-132709407.png)

2.2.1 流程分析

sqlSession1查询信息,存入二级缓存。
sqlSession2如果执行相同mapper映射下的sql,执行commit,会清空缓存。
sqlSession2如果查询sqlSession1相同的信息,会看缓存是否存在数据,有就从缓存中去数据。

2.2.2 二级缓存的使用

1. 在全局配置文件开启二级缓存  默认值为true 这一步可省略不写

     <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
2. 相关的映射文件
    <cache>标签表示当前这个mapper映射将使用二级缓存,区分的标准就看 mapper的namespace值。

<mapper namespace="com.itheima.dao.IUserDao">
    <!--开启user支持二级缓存-->
    <cache/>
</mapper>
3. 添加useCache属性
将UserDao.xml映射文件中的<select>标签中设置useCache=”true”代表当前这个 statement要使用二级缓存,如果不使用二级缓存可以设置为false。
  <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultType="user" useCache="true">
        select * from user where id = #{uid}
    </select>

2.2.3 注意事项

使用二级缓存的实体类一定要实现 java.io.Serializable 接口。

3.Mybatis注解开发

3.1 常用注解

@Insert 新增
@Update 更新
@Delete 删除
@Select 查询
@Result 封装结果集
@Results 和@Result一起使用,封装多个结果集
@ResultMap 引用封装
@One 一对一结果集封装
@Many 一对多结果集封装
@SelectProvider 动态SQL映射
@CacheNamespace 二级缓存使用

3.2 注解

SqlMapConfig.xml还是用xml配置的。
或者用package标签..
![](https://img2018.cnblogs.com/blog/1882316/202002/1882316-20200210193208224-928423688.png)

xml和注解的mapper属性不一样,如下:

在接口中配置使用@Insert 新增 @Update 更新 @Delete 删除  @Select 查询配置相应的方法。
属性里面写sql语句。
如 @Select("select * from user")
注意:如果使用注解开发,就不能有对应的xml配置文件,不管mapper中用的是class还是什么,否则就会报错。

3.2.1 注解建立实体类和数据库表的对应关系即 ResultMap

@Results 注解:  代替的是<resultMap>
    使用:Results({@Result(),@Result()})
@Result 注解:
    带起的是<resultMap> 中的<result>和<id>标签
    id是否是主键字段
    column 数据库的列名
    property 需要装配的属性名
    one  需要使用的@One注解
        select 指定用来查询的sqlmapper:使用的全限定类名,包类名+方法名
        fetchType 会覆盖全局的配置参数lazyLoadingEnabled
       使用格式:@Result(column="",property="",[email protected](select=""    ))

    many 需要使用的@Many注解

@One注解:(一对一)
    代替的是<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@Many注解:(多对一)
代替了<collection>标签,在注解中用来指定子查询返回的对象集合。
注解:聚集元素用来处理一对多的关系,需要指定映射的java实体类属性,属性的JavaType(一般为ArrayList)但注解中可以不定义。
格式:@Result(property="",column="",[email protected](select=""))

案例:

注解的关系如下:

3.3 注解开启缓存

在接口上使用@CacheNamespace注解就可以了
有一个blocking属性,改为true

原文地址:https://www.cnblogs.com/sweetbetter/p/12291280.html

时间: 2024-08-30 03:33:20

Mybatis-04 懒加载&缓存&注解开发的相关文章

关于 Mybatis 设置懒加载无效的问题

看了 mybatis 的教程,讲到关于mybatis 的懒加载的设置: 只需要在 mybatis 的配置文件中设置两个属性就可以了: <settings> <!-- 打开延迟加载的开关 --> <setting name="lazyLoadingEnabled" value="true" /> <!-- 将积极加载改为消息加载即按需加载 --> <setting name="aggressiveLazy

ionic3 懒加载在微信上缓存的问题

1.懒加载是什么? 在ionic2中所有的组件.模块.服务.管道等都堆积在app.module.ts模块中,在页面初始化的时候会一次性加载所有的资源,导致资源过大,页面渲染缓慢,也导致app.module.ts混乱,不美观,不易维护,不适用于结构繁多.业务复杂的项目. 懒加载的出现,使得在跳转到对应页面的时候加载对应页面的js.css.html,这样每个页面都是一个模块,只有在需要的时候才会加载,大大缓解了首屏的压力. 2.懒加载的使用: https://ionicframework.com/d

mybatis懒加载特性详解,以及多对多映射详解

注意讲解都在代码中 准备数据库,测试数据,各位自己添加,因为是多对多,所以使用中间表: 用到的实体: 学生类: public class Student { private Integer sid; private String name; private Integer age; //一个学生有多个老师,一个老师有多个学生 private List<Teacher> teachers=new ArrayList<Teacher>(); setter.. getter.... to

mybatis中的懒加载

知识点:mybatis中的懒加载的使用 参考:https://www.cnblogs.com/ysocean/p/7336945.html?utm_source=debugrun&utm_medium=referral (1)什么是mybatis的懒加载 通俗的讲就是按需加载,我们需要什么的时候再去进行什么操作.而且先从单表查询,需要时再从关联表去关联查询,能大大提高数据库性能, 因为查询单表要比关联查询多张表速度要快. 在mybatis中,resultMap可以实现高级映射(使用associa

Mybatis懒加载

一.需求:查询用户信息,有时候需要关联查出部门信息. 第一种方法:我们直接关联查询出所有用户和部门的信息 select * from tb_user u ,tb_department d where u.dep_id = d.dep_id; 分析: ①这里我们一次查询出所有用户信息,需要什么部门信息的时候直接从查询的结果中筛选.但是如果部门和用户表都比较大的时候,这种关联查询肯定比较耗时. ②我们的需求是有时候需要关联查询部门信息.这里不是一定需要部门信息的.即有时候不需要查询部门信息,我们也查

八、懒加载

1.需求:查询订单信息,有时候需要关联查出用户信息. 第一种方法:我们直接关联查询出所有订单和用户的信息 1 select * from orders o ,user u where o.user_id = u.id; 分析: ①.这里我们一次查询出所有的信息,需要什么信息的时候直接从查询的结果中筛选.但是如果订单和用户表都比较大的时候,这种关联查询肯定比较耗时. ②.我们的需求是有时候需要关联查询用户信息,这里不是一定需要用户信息的.即有时候不需要查询用户信息,我们也查了,程序进行了多余的耗时

Swift的懒加载和只读属性的介绍

懒加载 在 iOS 开发中,懒加载是无处不在的 懒加载的格式如下: lazy var person: Person = { print("懒加载") return Person() }() 懒加载本质上是一个闭包 以上代码可以改写为以下格式 let personFunc = { () -> Person in print("懒加载") return Person() } lazy var demoPerson: Person = self.personFunc

关于swift中的懒加载

懒加载 在 iOS 开发中,懒加载是无处不在的 懒加载的格式如下: lazy var person: Person = { print("懒加载") return Person() }() 懒加载本质上是一个闭包 以上代码可以改写为以下格式 let personFunc = { () -> Person in print("懒加载") return Person() } lazy var demoPerson: Person = self.personFunc

mybatis(三)懒加载

懒加载的好处: 所谓懒加载(lazy)就是延时加载,延迟加载.什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载.至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,我们让数据在需要的时候才进行加载,这时我们就用到了懒加载.总结为: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强,层次感很强. 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强