【Mybatis】Day 04 -- 缓存和注解开发

加载时机(检索策略)

  • 当一个用户下有非常多的账户时,我们查询一个用户后,其实体类中账户集合会非常的大,那么在查询的时候,应该是什么时候用到其账户信息,什么时候获取
  • 当我们在查询账户的时候,需要一同得到其账户所属的用户信息,那么在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来

延迟加载

  • 在真正使用数据时才发起查询,不用的时候不查,按需加载,也叫懒加载
  • 适用范围:一对多,多对多

立即加载

  • 不管用不用,只要一调用方法,就立刻发起查询
  • 适用范围:多对一,一对一

Mybatis 实现延迟加载

  • 实现思想:都是在用的时候才通过对方的根据id查询的配置来实现

  • 使用 Assocation 实现延迟加载

    <!-- select 属性指定的内容:查询用户的唯一标识: -->
    <!-- column 属性指定的内容:用户根据id查询时所需要的参数的值 -->
    <association property="user" column="uid" javaType="user" select="com.learn.dao.IUserDao.selectById"></association>
    

    (1)当以上的设置配置好了过后还不能实现延迟加载,还要在主配置文件中添加设置,查看官网关于setting的介绍
    在这里插入图片描述

    <settings>
      <setting name="lazyLoadingEnabled" value="true"/>
      <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    
  • 使用 Collection 实现延迟加载
    (1)先实现通过用户id查询账户列表这个配置,再实现以下配置,最后将主配置文件的setting配置好即可实现延迟加载

    <collection property="accounts" ofType="account"  select="com.learn.dao.IAccountDao.findAccountByUId"></collection>
    

Mybatis中的一级缓存和二级缓存

  • 缓存:即存在于内存的临时数据
  • 使用缓存:可减少和数据库的交互次数,提高执行效率
  • 适用于缓存:经常查询并且不经常改变的;数据的正确与否对结果影响不大的。避免缓存中的数据与数据库中的不一致导致异常。
  • 不适用缓存:数据的正确与否对结果影响很大(商品的库存,银行的汇款,股市的牌价等)
  • Mybatis 中的一级缓存:指的是Mybatis中SqlSession对象的缓存
    ❤ 当我们执行查询之后,查询结果会同时存入到SqlSession为我们提供的一块区域中,该区域是一个Map,当我们再次查询的时候,会先在SqlSwssion对象中查询是否有,有就直接读取使用;
    ❤ 当SqlSession对象关闭时,mybatis的一级缓存就清空了,因此可以通过关闭再开启SqlSession的方法来清空一级缓存
    ❤ 当调用SqlSession的修改、添加、删除、提交、关闭、clearCache()等方法时就会清空一级缓存,因此可通过这些操作来同步刷新一级缓存
  • Mybatis 中的二级缓存:指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存
    ❤ 使用步骤:
    (1)让Mybatis支持二级缓存 ---- 在SqlMapConfig.xml中配置
    (2)让当前的映射文件支持二级缓存 ---- 在IUserDao.xml中配置
    (3)让当前的操作中支持二级缓存 ---- 在<select>标签中配置
    ❤ 代码实现:
SqlMapConfig.xml
<settings>
	<setting name="cacheEnable" value="true"/>
</settings>
IUserDao.xml
<!-- 开启user支持二级缓存 -->
<cache/>
<!-- select标签中开启 -->
<select id="findAll" resultType="user" useCache="true">
    select * from user
</select>

在这里插入图片描述

Mybatis的注解开发

环境搭建

  • 注解开发只是代替了映射配置文件,主配置文件还是需要的
  • 先创建工程,导入依赖,再创建实体类和Dao接口以及主配置文件
  • 只要使用了注解开发,同时也有配置文件,不管用不用到这个配置文件,都会报错;因此要不将映射配置文件删除,要不换到别的地方,才可以继续。也就意味着:不能在同一个Dao中采用两种方式开发,只能二选一

单表CRUD操作

  • Mybatis中针对CRUD一共有4个注释:@SELECT @INSERT @UPDATE @DELETE
  • 注解中的括号中写入SQL语句即可当注解中的value只有一个时可以直接写value,否则需要写(value={"..."}),即标准格式为@Select(value={"select * from user"})
  • 使用方法:
@Select("select * from user")
List<User> findAll();
@Insert("insert into user(userName,age) values(#{userName},#{age})")
void saveUser(User user);
@Update("update user set userName=#{userName},age=#{age} where id=#{id}")
void updateUser(User user);
@Delete("delete from user where id=#{id}")
void deleteUser(Integer id);
@Select("select * from user where id=#{id}")
User selectUserById(Integer id);
@Select("select * from user where userName like #{userName} ")
User selectUserLikeName(String userName);
@Select("select count(*) from user")
int findTotal();

建立实体类属性与数据库表列的对应关系

  • 当实体类属性名与数据库列名不一致的时候,Mybatis就无法完成自动的对应关系映射那么查询结果就不能实现自动封装
  • 最简单的方法是在sql语句中配置别名,传统方法是在映射配置文件中配置,注解也可以配置别名
  • 当配置好一个过后,可以指定一个id,这样后面的方法就可以通过这个 id 查找到这个配置
@Select("select * from user")
@Results(id="userMap", value={
		 @Result(id=true, column="id", property="userId"),
		 @Result(column="name", property="userName",
		 @Result(column="age", property="userAge"
		 })
List<User> findAll();

@Select("select * from user where id=#{id}")
@ResultMap("userMap")
User selectUserById(Integer id);

多表查询操作

  • 实现步骤
    (1)建立数据库表并配置表间联系
    (2)建立实体类并表示出实体类之间的联系
    (3)配置封装结果映射
    (4)FetchType的属性即为检索策略,对应立即加载和延时加载
  • 多对一 (Mybatis中也称之为一对一)
//一个账户只能属于一个用户
@Select("select * from account")
@Results(id="accountMap", value={
		 @Result(id=true, column="id", property="id"),
		 @Result(column="uid", property="uid",
		 @Result(column="money", property="money",
		 @Result(property="user", column="uid", one=@One(select="com.learn.dao.IUserDao.selectById", fetchType=FetchType.EAGER))
		 })
List<User> findAccountAndUser();
  • 一对多
@Select("select * from user")
@Results(id="userMap", value={
		 @Result(id=true, column="id", property="userId"),
		 @Result(column="name", property="userName",
		 @Result(column="age", property="userAge"
		 @Result(property="accounts", column="id", many=@Many(select="com.learn.dao.IAccountDao.selectAccountByUId", fetchType=FetchType.LAZY))
		 })
List<User> findAll();

缓存的配置

  • 一级缓存是自动开启的,无需手动开启
  • 二级缓存的需要配置
    (1)先在主配置文件配置,但是现在的版本默认是开启的
    (2)在Dao接口类中配置
    在这里插入图片描述
//开启二级缓存
@CacheNameSpace(blocking=true)
public interface IUserDao{
	...
}
发布了27 篇原创文章 · 获赞 12 · 访问量 5179

猜你喜欢

转载自blog.csdn.net/Kobe_k/article/details/104062290