20201120+袁鑫

学习日志

知识总结

Mybatis延迟加载

延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.

好处: 先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张 表速度要快。

坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。

Mybatis 缓存

缓存(也称作cache)的作用是为了减去数据库的压力,提高数据库的性能。缓存实现的原理是从数据 库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直 接从内存(缓存)中直接获取,不再向数据库执行select语句,从而减少了对数据库的查询次数,因此 提高了数据库的性能。缓存是使用Map集合缓存数据的。(非关系型数据库 Redis key-value)

Mybatis有一级缓存和二级缓存。一级缓存的作用域是同一个SqlSession,在同一个sqlSession中 两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓 存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一 级缓存也就不存在了。Mybatis默认开启一级缓存(本地的会话缓存)。

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次 执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完 毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而 提高查询效率。

Mybatis 一级缓存

一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush、close或提交事务,它就存在。

一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方 法时,就会清空一级缓存。防止后续查询发生脏读(脏读:查询到过期的数据)

Mybatis内部存储缓存使用一个HashMap缓存数据,key为hashCode+sqlId+Sql语句。value为从查询 出来映射生成的java对象。

一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一 级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除。

需要注意的是

当Mybatis整合Spring后,直接通过Spring注入Mapper(Dao)的形式,如果不是在同一个事务中每个 Mapper的每次查询操作都对应一个全新的SqlSession实例,这个时候就不会有一级缓存的命中,但是 在同一个事务中时共用的是同一个SqlSession。如有需要可以启用二级缓存。

Mybatis 二级缓存

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询的数据缓存在同一 个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域 是根据mapper划分。

每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。Mybatis内部 存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对 象。

sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域,防止脏读。

Mybatis 注解开发

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
等同于xml 的 ResultMap
@Results(id = "userMap",
    value = {
        @Result(id = true, column = "id", property = "id"),
        @Result(column = "name", property = "userName"),
        @Result(column = "password", property = "passWord")
    })
@SelectKey(keyColumn = "id", keyProperty = "id", resultType =
Integer.class, before =false, statement = {"select last_insert_id()"})

获取主键

keyColumn:主键在数据库中的列名;

keyProperty : 主键在实例模型对象中的属性;

resultType:返回的类型;

before = false; 在sql语句执行之后执行;

statement = {"select last_insert_id()"} 查询出刚刚新增加的主键;

一对一注解核心
@Results(id="accountMap",
    value= {
        @Result(id=true,column="id",property="id"),
        @Result(column="uid",property="uid"),
        @Result(column="money",property="money"),
        @Result(column="uid",
            property="user",one=@One(select="com.itlaobing.dao.IUserDao.findById",
            fetchType= FetchType.LAZY)
        )
    })

一对多注解核心
@Results(id="userMap",
    value= {
        @Result(id=true,column="id",property="id"),
        @Result(column="name",property="userName"),
        @Result(column="password",property="passWord"),
        @Result(column="id",property="accounts",
            many=@Many(
                select="com.itlaobing.dao.IAccountDao.findByUid",
                fetchType= FetchType.LAZY
                ))
    })
注解配置二级缓存
//mybatis 基于注解方式实现配置二级缓存
@CacheNamespace(blocking=true)
public interface IUserDao {
}

心得

mybatis的学习算是告一段落了,这几天的学习还行,基本上都学会了,但是代码这个东西,有时候你看着他你就认识他,但你要凭空写出来就有点困难,所以还需要很多练习。

标签

评论

© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1