mybatis快取之一級快取(一)
阿新 • • 發佈:2020-06-26
> 對於mybatis框架。彷彿工作中一直是在copy著使用。對於mybatis快取。並沒有一個準確的認知。趁著假期。學習下mybatis的快取。這篇主要學習mybatis的一級快取。
## 為什麼使用快取
![](https://img2020.cnblogs.com/blog/891580/202006/891580-20200626084633286-2077751812.png)
其實,大家工作久了,就知道很多瓶頸就是在資料庫上。
## 初識mybatis一級快取
當然我們還是通過程式碼來認識下mybatis的一級快取
### 程式碼演示
詳細程式碼見github,這裡只展示重要的程式碼片段
1. tempMapper.xml
```
```
2. TempTest
```
public class TempTest {
Logger logger = Logger.getLogger(this.getClass());
@Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.TempDao.getById", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.TempDao.getById", 1);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}
}
```
3.執行結果
```
2020-06-26 08:57:37,453 DEBUG [dao.TempDao.getById] - ==> Preparing: select * from temp where id = ?
2020-06-26 08:57:37,513 DEBUG [dao.TempDao.getById] - ==> Parameters: 1(Integer)
2020-06-26 08:57:37,538 DEBUG [dao.TempDao.getById] - <== Total: 1
2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 08:57:37,538 INFO [TempTest] - true
```
4. 總結
4.1 從上面的結果,我們可以看到,第二次查詢的時候,就直接沒有查詢資料庫,並且返回的是同一個物件。證明第二次走的就是快取。
4.2 一級快取是預設開啟的。我們並沒有在程式碼中配置任何關於快取的配置
4.3 程式碼回顧
![](https://img2020.cnblogs.com/blog/891580/202006/891580-20200626090214931-1016839645.png)
## mybatis一級快取命中原則
mybatis是怎麼樣判斷某兩次查詢是完全相同的查詢?
### 1.statementId
1.1 mapper.xml
```
```
1.2 test
```
@Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById2", 1);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}
```
1.3 結果
```
2020-06-26 09:19:09,926 DEBUG [dao.Temp2Dao.getById1] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:19:09,957 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:19:09,969 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById2] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - ==> Parameters: 1(Integer)
2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - <== Total: 1
2020-06-26 09:19:09,971 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
```
1.4 總結
要求查詢的statementId必須完全相同,否則無法命中快取,即時兩個查詢語句、引數完全相同
### 2.查詢引數
我們用不同的引數查詢,一個傳1 一個傳2
2.1 test
```
@Test
public void testParam() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById1", 2);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}
```
2.2 結果
```
2020-06-26 09:24:33,107 DEBUG [dao.Temp2Dao.getById1] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:24:33,148 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:24:33,162 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:24:33,163 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 2(Integer)
2020-06-26 09:24:33,164 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:24:33,164 INFO [TempTest] - TempEntity{id=2, value1='22222', value2='bbbb'}
2020-06-26 09:24:33,164 INFO [TempTest] - false
```
2.3 總結
要求傳遞給sql的傳遞引數相同,否則不會命中快取
### 3.分頁引數
3.1 傳不同的分頁引數
```
@Test
public void testPage() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
RowBounds rowBounds1 = new RowBounds(0,1);
List tempEntity1 = sqlSession.selectList("dao.Temp2Dao.getList", null,rowBounds1);
logger.info(tempEntity1);
RowBounds rowBounds2 = new RowBounds(0,2);
List tempEntity2 = sqlSession.selectList("dao.Temp2Dao.getList",null, rowBounds2);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}
```
3.2 結果
```
2020-06-26 10:10:33,060 DEBUG [dao.Temp2Dao.getList] - ==> Preparing: select * from temp where 1=1
2020-06-26 10:10:33,101 DEBUG [dao.Temp2Dao.getList] - ==> Parameters:
2020-06-26 10:10:33,116 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}]
2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==> Preparing: select * from temp where 1=1
2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==> Parameters:
2020-06-26 10:10:33,118 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}, TempEntity{id=2, value1='22222', value2='bbbb'}]
2020-06-26 10:10:33,118 INFO [TempTest] - false
```
3.3 總結
要求分頁引數必須相同,否則無法命中快取。快取的粒度是整個分頁查詢結果,而不是結果中的每個物件
### 4. sql語句
4.1 mapper檔案
```
```
這個就不測試了。
4.2 總結
要求傳遞給jdbc的sql 必須完全相同。就算是1=1 不起作用 也不行
### 5.環境
這裡的環境指的的是`` 和 `` 也是會影響的
```
```
### 總結
![](https://img2020.cnblogs.com/blog/891580/202006/891580-20200626102819520-21063689