Mybatis連接池與事務深入
- Mybatis的連接池技術
- Mybatis連接池的分類
- Mybatis中資料源的配置
- Mybatis中DataSource的存取
- Mybatis中連接的獲取程序分析
- Mybatis的事務控制
- JDBC中事務的回顧
- Mybatis中事務提交方式
- Mybatis自動提交事務的設定
Mybatis的連接池技術
在 Mybatis 中有連接池技術,它采用的是自己的連接池技術,配置位置是在 Mybatis 的 SqlMapConfig.xml 組態檔中,通過
<dataSource type=”pooled”>來實作 Mybatis 中連接池的配置,
很多時候我們所說的資料源就是為了更好的管理資料庫連接,也就是我們所說的連接池技術,連接池的使用是因為它可以減少我們獲取連接所消耗的時間,

Mybatis連接池的分類
Mybatis 將它自己的資料源分為下面三類:
| 取值 | 說明 |
|---|---|
| POOLED | 采用傳統的javax.sql.DataSource規范中的連接池,mybatis中有針對規范的實作 |
| UNPOOLED | 采用傳統的獲取連接的方式,雖然也實作Javax.sql.DataSource介面,但是并沒有使用池的思想 |
| JNDI | 采用服務器提供的JNDI技術實作,來獲取DataSource物件,不同的服務器所能拿到DataSource是不一樣,注意:如果不是web或者maven的war工程,是不能使用的, |
MyBatis 內部分別定義了實作了 java.sql.DataSource 介面的 UnpooledDataSource,
PooledDataSource 類來表示 UNPOOLED、POOLED 型別的資料源,
Mybatis中資料源的配置
我們的資料源配置就是在 SqlMapConfig.xml 檔案中,具體配置如下:
<!-- 配置資料源(連接池)資訊 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
MyBatis 在初始化時,根據的 type 屬性來創建相應型別的的資料源 DataSource,即:
type=“POOLED”:MyBatis 會創建 PooledDataSource 實體
type=“UNPOOLED” : MyBatis 會創建 UnpooledDataSource 實體
type=“JNDI”:MyBatis 會從 JNDI 服務上查找 DataSource 實體,然后回傳使用
Mybatis中DataSource的存取
MyBatis 是 通 過 工 廠 模 式 來 創 建 數 據 源 DataSource 對 象 的 , MyBatis 定 義 了 抽 象 的 工 廠 介面:org.apache.ibatis.datasource.DataSourceFactory,通過其getDataSource()方法回傳資料源DataSource,
Mybatis中連接的獲取程序分析
當我們需要創建 SqlSession 物件并需要執行 SQL 陳述句時,這時候 MyBatis 才會去呼叫 dataSource 物件來創建java.sql.Connection物件,也就是說,java.sql.Connection物件的創建一直延遲到執行SQL陳述句的時候,
真正連接打開的時間點,只是在我們執行SQL陳述句時,才會進行,其實這樣做我們也可以進一步發現,資料庫連接是我們最為寶貴的資源,只有在要用到的時候,才去獲取并打開連接,當我們用完了就再立即將資料庫連接歸還到連接池中,
Mybatis的事務控制
JDBC中事務的回顧
在 JDBC 中我們可以通過手動方式將事務的提交改為手動方式,通過 setAutoCommit()方法就可以調整,
Mybatis 框架因為是對 JDBC 的封裝,所以 Mybatis 框架的事務控制方式,本身也是用 JDBC 的setAutoCommit()方法來設定事務提交方式的,
它是通過sqlsession物件的commit方法和rollback方法實作事務的提交和回滾,
Mybatis中事務提交方式
Mybatis 中事務的提交方式,本質上就是呼叫 JDBC 的 setAutoCommit()來實作事務控制,
運行測驗代碼:
package com.keafmd.test;
import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* Keafmd
*
* @ClassName: MybatisTest
* @Description: 測驗類,測驗crud操作
* @author: 牛哄哄的柯南
* @date: 2021-02-08 15:24
*/
public class MybatisTest {
private InputStream in;
private SqlSession sqlsession;
private IUserDao userDao;
@Before // 用于在測驗方法執行前執行
public void init()throws Exception{
//1.讀取組態檔,生成位元組輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.創建SqlSessionFactory工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工廠生產SqlSession物件
sqlsession = factory.openSession(); //里面寫個true,下面每次就不用了寫 sqlsession.commit(); 了
//4.使用SqlSession創建Dao介面的代理物件
userDao = sqlsession.getMapper(IUserDao.class);
}
@After // 用于在測驗方法執行后執行
public void destory() throws Exception{
//提交事務
sqlsession.commit();
//6.釋放資源
sqlsession.close();
in.close();
}
/**
* 測驗保存操作
*/
@Test
public void testSave() throws Exception {
User user = new User();
user.setUsername("Keafmd laset insertid");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("XXXXXXX");
System.out.println("保存操作前:"+user);
//5.執行保存方法
userDao.saveUser(user);
System.out.println("保存操作后:"+user);
}
}
控制臺資訊:

這是我們的 Connection 的整個變化程序,通過分析我們能夠發現之前的 CUD 操作程序中,我們都要手動進行事務的提交,原因是 setAutoCommit()方法,在執行時它的默認值被設定為 false 了,所以我們在 CUD 操作中,必須通過 sqlSession.commit()方法來執行提交操作,
Mybatis自動提交事務的設定
在連接池中取出的連接,都會將呼叫 connection.setAutoCommit(false)方法,這樣我們就必須使用 sqlSession.commit()方法,相當于使用了 JDBC 中的 connection.commit()方法實作事務提交,
我們設定session = factory.openSession(true);,同時去掉destory()中的session.commit();提交陳述句,這樣就成了自動提交事務了,
運行測驗代碼:
package com.keafmd.test;
import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* Keafmd
*
* @ClassName: MybatisTest
* @Description: 測驗類,測驗crud操作
* @author: 牛哄哄的柯南
* @date: 2021-02-08 15:24
*/
public class MybatisTest {
private InputStream in;
private SqlSession sqlsession;
private IUserDao userDao;
@Before // 用于在測驗方法執行前執行
public void init()throws Exception{
//1.讀取組態檔,生成位元組輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.創建SqlSessionFactory工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工廠生產SqlSession物件
sqlsession = factory.openSession(true); //里面寫個true,下面每次就不用了寫 sqlsession.commit(); 了
//4.使用SqlSession創建Dao介面的代理物件
userDao = sqlsession.getMapper(IUserDao.class);
}
@After // 用于在測驗方法執行后執行
public void destory() throws Exception{
//提交事務
//sqlsession.commit();
//6.釋放資源
sqlsession.close();
in.close();
}
/**
* 測驗保存操作
*/
@Test
public void testSave() throws Exception {
User user = new User();
user.setUsername("Keafmd laset insertid");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("XXXXXXX");
System.out.println("保存操作前:"+user);
//5.執行保存方法
userDao.saveUser(user);
System.out.println("保存操作后:"+user);
}
}
DefaultSqlSessionFactory 類的源代碼:
public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
控制臺資訊:

我們可以發現,此時事務就設定為自動提交了,同樣可以實作CUD操作時記錄的保存,雖然這也是一種方式,但就編程而言,設定為自動提交方式為 false 再根據情況決定是否進行提交,這種方式更常用,因為我們可以根據業務情況來決定提交是否進行提交,
以上就是Mybatis連接池與事務深入的全部內容,
看完如果對你有幫助,感謝點贊支持!
如果你是電腦端的話,看到右下角的 “一鍵三連” 了嗎,沒錯點它[哈哈]

加油!
共同努力!
Keafmd
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/259282.html
標籤:其他
上一篇:SVG中顯示一個表格
