關於mybatis基礎咱們前面幾篇博客已經介紹了不少了,今天咱們來講一個簡單的問題,那就是mybatis中的緩存問題。mybatis自己對緩存提供了支持,可是若是咱們沒有進行任何配置,那麼默認狀況下系統只開啓了一級緩存,一級緩存就是同一個SqlSession執行的相同查詢是會進行緩存的,OK,那麼今天咱們就來看看這些緩存,並簡單驗證下。java
這個緩存系統默認狀況下是開啓的,當咱們獲取到一個SqlSession對象以後,若是調用SqlSession中的同一個方法查詢同一條數據,那麼第二次查詢將不會去數據庫中查詢,由於第一次查詢有緩存,直接調用緩存數據便可,除非緩存超時或者咱們明確聲明數據要刷新,不然都是直接調用緩存數據。OK,咱們來看一個簡單的案例。
查詢代碼以下:git
SqlSession sqlSession = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查詢同一條數據時會緩存
User user = mapper.getUser(1l);
User user2 = mapper.getUser(1l);
System.out.println(user.toString());
System.out.println(user2.toString());
sqlSession.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
咱們來看看日誌:
小夥伴們看到,我這裏執行了兩次查詢,但實際上只執行了一次SQL語句。github
上面的緩存是由系統默認配置的,這個有必定的侷限性,就是隻能在同一個SqlSession中有效,脫離了同一個SqlSession就無法使用這個緩存了,有的時候咱們可能但願可以跨SqlSession進行數據緩存。那麼這個時候須要咱們進行手動開啓二級緩存。
二級緩存的開啓方式其實很簡單,只須要咱們在userMapper.xml中配置<cache/>
節點便可。以下:算法
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.sang.db.UserMapper">
<cache/>
<select id="getUser" resultType="org.sang.bean.User" parameterType="Long">
select * from user where id = #{id}
</select>
<insert id="insertUser" parameterType="org.sang.bean.User">
INSERT INTO user(username,password,address) VALUES (#{username},#{password},#{address})
</insert>
<delete id="deleteUser" parameterType="Long">
DELETE FROM user where id=#{id}
</delete>
<select id="getAll" resultType="u">
SELECT * from user
</select>
</mapper>
這樣簡單配置以後,二級緩存就算開啓了,這樣的配置中,許多東西都是默認的,好比全部的select語句都會被緩存,全部的delete、insert和update則都會將緩存刷新,還好比緩存將使用LRU算法進行內存回收等。那麼這些東西若是須要配置的話,咱們能夠按以下方式進行配置:
<cache eviction="LRU" flushInterval="20000" size="1024" readOnly="true"/>
,這裏的eviction表示緩存策略,除了LRU以外還有先進先出(FIFO)、軟引用(SOFT)、弱引用(WEAK)等,flushInterval則表示刷新時間,表示緩存的對象個數,readOnly爲true則表示緩存只能夠讀取不能夠修改。
OK,作了如上配置以後還不夠,開啓二級緩存還要求咱們的實體類能夠序列化,實現Serializable接口便可,以下:sql
public class User implements Serializable{
private Long id;
private String username;
private String password;
private String address;
...
}
如此以後,咱們的二級緩存就算成功開啓了,OK,我麼來測試下:數據庫
SqlSession sqlSession = null;
SqlSession sqlSession2 = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUser(1l);
System.out.println(user.toString());
sqlSession.commit();
sqlSession2 = DBUtils.openSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUser(1l);
System.out.println(user2.toString());
sqlSession2.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
sqlSession2.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
if (sqlSession2 != null) {
sqlSession2.close();
}
}
打印日誌以下:
OK,小夥伴們看到SQL語句實際上只執行了一次。緩存
OK,以上就是對mybatis中緩存的一個簡單介紹。markdown
本文案例下載:
本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis8mybatis
參考資料:
《深刻淺出MyBatis 技術原理與實戰》app