标签:mapper 缓存 UserMapper sqlSession 详解 user Mybatis User
缓存:
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存中,再次查询时无需访问磁盘,提高效率。解决高并发问题。
- 可以减少IO。
- 经常查询且不常改变的数据适合使用缓存。
(注意:读数据才走缓存)
Mybatis缓存
官方文档:
https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
-
Mybatis有着非常强大的缓存特性,可以非常方便地定制和配置缓存。
-
Mybatis中定义了两级缓存:一级缓存和二级缓存
一级缓存:默认情况下一级。SqlSession级别,也称为本地缓存。
二级缓存: 需要手动开启和配置,namespace级别 -
自定义缓存:Mybatis定义了缓存接口Cache,可以通过实现Cache接口来自定义二级缓存。
Cache接口实现类
示例
获得SqlSession的工具类,openSession为true时自动提交事务
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
String resource = "mybatis-config.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession sqlSession = sqlSessionFactory.openSession(true); //自动提交事务
return sqlSession;
}
}
UserMapper接口
import org.apache.ibatis.annotations.Param;
public interface UserMapper {
//根据id查询用户
User queryUserById(@Param("id") int id);
//修改用户
int updateUser(User user);
}
xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jacob.dao.UserMapper">
<select id="queryUserById" parameterType="_int" resultType="user">
select * from user where user = #{id}
</select>
<update id="updateUser" parameterType="user">
update user set pwd=#{pwd} where user=#{user}
</update>
</mapper>
测试类MyTest
- 一级缓存
import com.jacob.dao.UserMapper;
import com.jacob.pojo.User;
import com.jacob.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class MyTest {
@Test
public void test() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
User user1 = mapper.queryUserById(1); //只查询一次
System.out.println(user == user1); //从缓存拿到user1, true
sqlSession1.close();
}
}
增删改可能会改变原来数据, 所以会刷新缓存
public class MyTest {
@Test
public void test() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
mapper.updateUser(new User(4, "jj", "14")); //刷新了缓存
User user1 = mapper.queryUserById(1); //查询第二次
System.out.println(user == user1); //false
sqlSession1.close();
}
}
执行结果如下:
利用sqlSession.clearCache()清理缓存
public class MyTest {
@Test
public void test() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
sqlSession.clearCache(); //清理缓存
User user1 = mapper.queryUserById(1); //查询第二次
System.out.println(user == user1); //false
sqlSession1.close();
}
}
- 二级缓存
namespace级别
工作机制:- 一个会话查询一条数据,数据会存放在当前会话的一级缓存中
- 若当前会话关闭,这个会话的一级缓存消失, 开启二级缓存后,一级缓存的数据保存至二级缓存
- 新的会话可在二级缓存获取数据
在Mapper中开启
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jacob.dao.UserMapper">
<cache readOnly="true"/>
<select id="queryUserById" parameterType="_int" resultType="user" useCache="true">
select * from user where user = #{id}
</select>
<update id="updateUser" parameterType="user">
update user set pwd=#{pwd} where user=#{user}
</update>
</mapper>
public class MyTest {
@Test
public void test() {
//两个 sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
sqlSession.close(); //sqlSession关闭了数据进入二级缓存
User user1 = mapper1.queryUserById(1);
System.out.println(user == user1); //从缓存拿到user1, true
sqlSession1.close();
}
}
若sqlSession 后关闭,查询了两次
public class MyTest {
@Test
public void test() {
//两个 sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
User user1 = mapper1.queryUserById(1);
System.out.println(user == user1); //false, sqlSession未关闭,二级缓存中没有数据,不同sqlSession,一级缓存不同
sqlSession.close();
sqlSession1.close();
}
}
查询了两次
- 缓存原理(来自狂神说Java)
标签:mapper,缓存,UserMapper,sqlSession,详解,user,Mybatis,User 来源: https://blog.csdn.net/qq_29216163/article/details/117921928
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。