【Java从0到架构师】MyBatis - 缓存_构造方法

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

Gitee 代码:mybatis_缓存

缓存

一级缓存 - SqlSession

一级缓存默认开启,缓存内容存放到了 SqlSession 对象中

  • 同一个 SqlSession 的 select 共享缓存
  • 所以当关闭 SqlSession 时,缓存也就失效了
  • 执行 insert、update、delete、commit 等方法时,会自动清理一级缓存
  • 由于在很多时候,每次查询用的都是不同的 SqlSession,所以一级缓存的命中率并不高

二级缓存

为了提高缓存的命中率,可以考虑开启 MyBatis 二级缓存,它是 namespace (mapper) 级别的缓存

  • 同一个 namespace 下的 select 共享缓存
  • 默认情况,namespace 下 update,insert,delete 执行成功时,会自动清理二级缓存
  • 当调用 SqlSession 的 close 方法时,会将查询结果放进二级缓存

开启二级缓存

注意区分二级缓存延迟加载

  • 延迟加载可以全局配置,在 mapper 中覆盖全局的配置
  • 二级缓存必须配置全局开始,在 mapper 中再配置是否使用

mybatis-config.xml 中配置:

<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>

在映射文件的 mapper 中添加 cache 标签,默认会缓存映射文件中的所有 select 的结果

<!-- readonly 默认是 false -->
<cache />
<!-- <cache readOnly="false"/> -->

cache 标签的常用属性有:

  • size:缓存多少个存储结果(单个对象或一个列表)的引用,默认值是 1024

    一个 List 里如果装了多个对象,只算作一个引用

  • eviction:当缓存数量超过 size 时的清除策略
    可选值有 LRU(默认值)、FIFO、SOFT、WEAK
  • flushInterval:每隔多少毫秒清除一次缓存,默认不会定时清除缓存
  • readonly:true 代表缓存的是对原对象的引用,false 代表缓存的是原对象序列化后的拷贝对象
    所以 false 时要求实现 Serializable 接口;默认值是 false

readonly 为 false 时,sqlSession.commit() 时才会将数据放入二级缓存,放入二级缓存之前修改对象的值,和放入二级缓存之后,再去修改对象的值效果是不同的。

useCache - 是否开启二级缓存

可以通过设置 useCache 属性来决定某个 select 是否需要开启二级缓存

<select id="get"
		useCache="false"
		parameterType="int"
		resultType="com.mj.bean.Skill">
	SELECT * FROM skill WHERE id = #{id} 
</SELECT>

flushCache - 是否需要清楚缓存

可以通过设置 flushCache 属性来决定某个操作之后,是否需要清除缓存

<insert id="save"
		flushCache="false"
		parameterType="com.mj.bean.Skill">
	INSERT INTO skill(name, level) VALUES (#{name}, #{level})
</insert>

指定构造方法

XML 中指定构造方法

构造方法的参数顺序与 XML 中可以对应上:

public class Student {
	private Integer id; 
	private String name; 
	public Student() {}
	public Student(Integer id, String name) {
		this.id = id;
		this.name = name;
	}
}
<resultMap id="rm" type="com.mj.bean.Student">
	<constructor>
		<idArg column="id" javaType="int"/>
		<arg column="name" javaType="String"/>
	</constructor>
</resultMap>

<select id="get" parameterType="int" resultMap="rm">
	SELECT * FROM student WHERE id = #{id}
</select>

也可以通过 @Param 指定构造方法的参数名:

public class Student {
	private Integer id; 
	private String name; 
	public Student() {}
	public Student(@Param("id") Integer id, 
				   @Param("name") String name) {
		this.id = id;
		this.name = name;
	}
}
<resultMap id="rm" type="com.mj.bean.Student">
	<constructor>
		<idArg column="id" javaType="int"/>
		<arg column="name" javaType="String"/>
	</constructor>
</resultMap>

<select id="get" parameterType="int" resultMap="rm">
	SELECT * FROM student WHERE id = #{id}
</select>

注解指定构造方法

public class Student {
	private Integer id; 
	private String name; 
	public Student() {}
	public Student(Integer id, String name) {
		this.id = id;
		this.name = name;
	}
}
@Select("SELECT * FROM student WHERE id = #{id}")
@ConstructorArgs({
	@Arg(column = "id", javaType = Integer.class, id = true),
	@Arg(column = "name", javaType = String.class)
})
Student get(Integer id);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌宅鹿同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值