- 十、連線池
- 10.1連線池
- 10.2、mybatis連線池的分類
- 十一、mybatis的快取
- 一級快取和二級快取
- 使用一級快取失效的四種情況:
- 11.1、不同的SqlSession對應不同的一級快取。
- 11.2、MyBatis的二級快取
- 二級快取開啟的條件:
- 11、3二級快取的相關配置
- 11.4、mybatis快取查詢的順序
- 11.5整合第三方的快取EhCache
十、連線池
10.1連線池
-
連線池是什麼:儲存連線的容器
-
解決了什麼問題
- 如果沒有連線池,每次執行sql語句都需要建立connection的連線,會浪費時間,影響程式的效能。
-
提前建立一些連線,儲存到連線池中,使用的時候從連線池獲取連線即可
-
常用的連線池
-
c3p0
-
dbcp
-
druid(阿里)
-
-
連線池有歸還的操作,已經對close方法進行了增強,原來是關閉連線,現在是歸還
10.2、mybatis連線池的分類
-
在解析mybatis-config.xml配置檔案的時候,建立dataSource物件,存入到Environment物件中。
-
當執行SQL語句的時候,準備從dataSource物件中獲取連結。
十一、mybatis的快取
一級快取和二級快取
一級快取是SqlSession級別的,透過同一個SqlSession查詢的資料會被快取,下次查詢相同的資料,就會從一級快取中直接獲取,不會從資料庫重新查詢。一級快取預設是開啟
使用一級快取失效的四種情況:
11.1、不同的SqlSession對應不同的一級快取。
@Test
public void testGetEmpById(){
SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
System.out.println(sqlSession1);
SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
System.out.println(sqlSession2);
EmpMapper empMapper1 = sqlSession1.getMapper(EmpMapper.class);
Emp emp1 = empMapper1.getEmpById(1);
System.out.println(emp1);
System.out.println("-----------------------------------");
EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);
Emp emp2 = empMapper2.getEmpById(1);
System.out.println(emp2);
}
2、同一個SqlSession但是查詢條件不同。
3、同一個SqlSession兩次查詢之間,執行了任何一次增刪改操作
Emp emp1 = empMapper.getEmpById(1);
System.out.println(emp1);
empMapper.insertEmp(new Emp(null,"小張",23,"男"));
Emp emp2 = empMapper.getEmpById(1);
System.out.println(emp2);
4、同一個SqlSession兩次查詢之間,手動清空了快取
//手動清空一級快取
sqlSession.clearCache();
11.2、MyBatis的二級快取
二級快取是SqlSessionFactory級別的,透過同一個SqlSessionFactory建立的SqlSession查詢的結果都會被快取;下次查詢相同的資料,就會從二級快取中直接獲取,不會從資料庫重新查詢。二級快取預設是不開啟的
二級快取開啟的條件:
1、在核心配置檔案中,設定全域性配置屬性cacheEnabled=”true” ,預設為true。所以不需要設定
2、在對映檔案中設定標籤
3、二級快取必須在SqlSession關閉之後生效
4、查詢的資料所轉換的實體類型別必須實現序列化的介面
public class Emp implements Serializable
@Test
public void testCache() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
/*sqlSession1和sqlSession2都是sqlSessionFactory建立的*/
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
EmpMapper empMapper1 = sqlSession1.getMapper(EmpMapper.class);
Emp emp1 = empMapper1.getEmpById(1);
System.out.println(emp1);
sqlSession1.close();
System.out.println("-----------------------");
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);
Emp emp2 = empMapper2.getEmpById(1);
System.out.println(emp2);
sqlSession2.close();
}
Cache Hit Ratio:二級快取命中率,不為0,說明程式直接從二級快取中獲取了資料
使二級快取失效的情況:
兩次查詢之間執行了任意的增刪改,會使一級和二級快取同時失效
11、3二級快取的相關配置
在mapper配置檔案中新增的cache標籤可以設定一些屬性:
①eviction屬性:快取回收策略,預設的是 LRU。
LRU(Least Recently Used) – 最近最少使用的:移除最長時間不被使用的物件。
FIFO(First in First out) – 先進先出:按物件進入快取的順序來移除它們。
SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的物件。
WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的物件。
②flushInterval屬性:重新整理間隔,單位毫秒
預設情況是不設定,也就是沒有重新整理間隔,快取僅僅呼叫語句時重新整理
③size屬性:引用數目,正整數代表快取最多可以儲存多少個物件,太大容易導致記憶體溢位
④readOnly屬性:只讀, true/false
true:只讀快取;會給所有呼叫者返回快取物件的相同例項。因此這些物件不能被修改。這提供了很重要的效能優勢。
false:讀寫快取;會返回快取物件的複製(透過序列化)。這會慢一些,但是安全,因此預設是false。
11.4、mybatis快取查詢的順序
先查詢二級快取,因為二級快取中可能會有其他程式已經查出來的資料,可以拿來直接使用。
如果二級快取沒有命中,再查詢一級快取
如果一級快取也沒有命中,則查詢資料庫
SqlSession關閉之後,一級快取中的資料會寫入二級快取
11.5整合第三方的快取EhCache
11.5.1新增依賴
<!-- Mybatis EHCache整合包 -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
<!-- slf4j日誌門面的一個具體實現 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
11.5.2各jar的功能
jar包名稱 | 作用 |
---|---|
mybatis-ehcache | Mybatis和EHCache的整合包 |
ehcache | EHCache核心包 |
slf4j-api | SLF4J日誌門面包 |
logback-classic | 支援SLF4J門面介面的一個具體實現 |
11.5.3建立EHCache配置檔案ehcache.xml
<?xml version="1.0" encoding="utf-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 磁碟儲存路徑 -->
<diskStore path="D:\qingcheng\ehcache"/>
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
11.5.4設定二級快取的型別
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
11.5.5加入logback日誌
存在SLF4J時,作為簡易日誌的log4j將失效,此時需要藉助SLF4J的具體實現logback來列印日誌,建立logback的配置檔案logback.xml
11.5.6EHCache配置檔案說明
屬性名 | 是否必須 | 作用 |
---|---|---|
maxElementsInMemory | 是 | 在記憶體中快取的element的最大數目 |
maxElementsOnDisk | 是 | 在磁碟上快取的element的最大數目,若是0表示無窮大 |
eternal | 是 | 設定快取的elements是否永遠不過期。如果為true,則快取的資料始終有效,如果為false那麼還要根據timeToIdleSeconds、timeToLiveSeconds判斷 |
overflowToDisk | 是 | 設定當記憶體快取溢位的時候是否將過期的element快取到磁碟上 |
timeToIdleSeconds | 否 | 當快取在EhCache中的資料前後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些資料便會刪除,預設值是0,也就是可閒置時間無窮大 |
timeToLiveSeconds | 否 | 快取element的有效生命期,預設是0.,也就是element存活時間無窮大 |
diskSpoolBufferSizeMB | 否 | DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區 |
diskPersistent | 否 | 在VM重啟的時候是否啟用磁碟儲存EhCache中的資料,預設是false。 |
diskExpiryThreadIntervalSeconds | 否 | 磁碟快取的清理執行緒執行間隔,預設是120秒。每個120s,相應的執行緒會進行一次EhCache中資料的清理工作 |
memoryStoreEvictionPolicy | 否 | 當記憶體快取達到最大,有新的element加入的時候,移除快取中element的策略。預設是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出) |
11.5.7 測試還用之前的測試方法即可