亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MyBatis連接池的深入和動態(tài)SQL詳解

 更新時間:2022年02月09日 08:48:09   作者:MAX--李  
這篇文章主要介紹了MyBatis連接池的深入和動態(tài)SQL詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一,Mybatis 連接池與事務(wù)深入

1.1 Mybatis 的連接池技術(shù)

Mybatis 中連接池技術(shù),它采用的是自己的連接池技術(shù)。在 Mybatis 的 SqlMapConfig.xml 配置文件中,通過來實現(xiàn) Mybatis 中連接池的配置。

1.1.1 Mybatis 連接池的分類

在 Mybatis 中我們將它的數(shù)據(jù)源 dataSource 分為以下幾類:

可以看出 Mybatis 將它自己的數(shù)據(jù)源分為三類: 

  • UNPOOLED 不使用連接池的數(shù)據(jù)源 
  • POOLED 使用連接池的數(shù)據(jù)源 
  • JNDI 使用 JNDI 實現(xiàn)的數(shù)據(jù)源

具體結(jié)構(gòu)如下:

相應(yīng)地,MyBatis 內(nèi)部分別定義了實現(xiàn)了 java.sql.DataSource 接口的 UnpooledDataSource,PooledDataSource 類來表示 UNPOOLED、POOLED 類型的數(shù)據(jù)源。

在這三種數(shù)據(jù)源中,我們一般采用的是 POOLED 數(shù)據(jù)源(很多時候我們所說的數(shù)據(jù)源就是為了更好的管理數(shù)據(jù)庫連接,也就是我們所說的連接池技術(shù))。

1.1.2 Mybatis 中數(shù)據(jù)源的配置

MyBatis 在初始化時,根據(jù)的 type 屬性來創(chuàng)建相應(yīng)類型的的數(shù)據(jù)源 DataSource,即:

  • type=”POOLED”:MyBatis 會創(chuàng)建 PooledDataSource 實例
  • type=”UNPOOLED” : MyBatis 會創(chuàng)建 UnpooledDataSource 實例
  • type=”JNDI”:MyBatis 會從 JNDI 服務(wù)上查找 DataSource 實例,然后返回使用

我們的數(shù)據(jù)源配置就是在 SqlMapConfig.xml 文件中,具體配置如下:

<!-- 配置數(shù)據(jù)源(連接池)信息 -->?
<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>

1.2 Mybatis 的事務(wù)控制

1.2.1 JDBC 中事務(wù)的回顧

在 JDBC 中我們可以通過手動方式將事務(wù)的提交改為手動方式,通過 setAutoCommit()方法就可以調(diào)整。

通過 JDK 文檔,我們找到該方法如下:

在這里插入圖片描述

那么我們的 Mybatis 框架因為是對 JDBC 的封裝,所以 Mybatis 框架的事務(wù)控制方式,本身也是用 JDBC 的setAutoCommit()方法來設(shè)置事務(wù)提交方式的。

1.2.2 Mybatis 中事務(wù)提交方式

Mybatis 中事務(wù)的提交方式,本質(zhì)上就是調(diào)用 JDBC 的 setAutoCommit()來實現(xiàn)事務(wù)控制。

我們運行之前所寫的代碼:

@Test
public void testSaveUser() throws Exception {
User user = new User();
user.setUsername("mybatis user09");
//6.執(zhí)行操作
int res = userDao.saveUser(user);
System.out.println(res);
System.out.println(user.getId());
}
@Before//在測試方法執(zhí)行之前執(zhí)行
public void init()throws Exception {
//1.讀取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.創(chuàng)建構(gòu)建者對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.創(chuàng)建 SqlSession 工廠對象
factory = builder.build(in);
//4.創(chuàng)建 SqlSession 對象
session = factory.openSession();
//5.創(chuàng)建 Dao 的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After//在測試方法執(zhí)行完成之后執(zhí)行
public void destroy() throws Exception{
//7.提交事務(wù)
session.commit();
//8.釋放資源
session.close();
in.close();
}

默認 setAutoCommit()方法,在執(zhí)行時它的值被設(shè)置為 false 了,所以我們在 CUD 操作中,必須通過 sqlSession.commit()方法來執(zhí)行提交操作。

1.2.3 Mybatis 自動提交事務(wù)的設(shè)置

通過上面的研究和分析,現(xiàn)在我們一起思考,為什么 CUD 過程中必須使用 sqlSession.commit()提交事務(wù)?主要原因就是在連接池中取出的連接,都會將調(diào)用 connection.setAutoCommit(false)方法,這樣我們就必須使用 sqlSession.commit()方法,相當(dāng)于使用了 JDBC 中的 connection.commit()方法實現(xiàn)事務(wù)提交。

明白這一點后,我們現(xiàn)在一起嘗試不進行手動提交,一樣實現(xiàn) CUD 操作。

@Before//在測試方法執(zhí)行之前執(zhí)行
public void init()throws Exception {
//1.讀取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.創(chuàng)建構(gòu)建者對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.創(chuàng)建 SqlSession 工廠對象
factory = builder.build(in);
//4.創(chuàng)建 SqlSession 對象
**session = factory.openSession(true);**
//5.創(chuàng)建 Dao 的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After//在測試方法執(zhí)行完成之后執(zhí)行
public void destroy() throws Exception{
//7.釋放資源
session.close();
in.close();
}

事務(wù)就設(shè)置為自動提交了,同樣可以實現(xiàn)CUD操作時記錄的保存。雖然這也是一種方式,但就編程而言,設(shè)置為自動提交方式為 false 再根據(jù)情況決定是否進行提交,這種方式更常用。因為我們可以根據(jù)業(yè)務(wù)情況來決定提交是否進行提交。

二.Mybatis 的動態(tài) SQL 語句

Mybatis 的映射文件中,前面我們的 SQL 都是比較簡單的,有些時候業(yè)務(wù)邏輯復(fù)雜時,我們的 SQL 是動態(tài)變化的,此時在前面的學(xué)習(xí)中我們的 SQL 就不能滿足要求了。

參考的官方文檔,描述如下:

2.1 動態(tài) SQL 之標(biāo)簽

我們根據(jù)實體類的不同取值,使用不同的 SQL 語句來進行查詢。比如在 id 如果不為空時可以根據(jù) id 查詢,如果 username 不同空時還要加入用戶名作為條件。這種情況在我們的多條件組合查詢中經(jīng)常會碰到。

2.1.1 持久層 Dao 接口

/**
* 根據(jù)用戶信息,查詢用戶列表
* @param user
* @return
*/
List<User> findByUser(User user);

2.1.2 持久層 Dao 映射配置

<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if> <if test="address != null">
and address like #{address}
</if>
</select>

注意:<if>標(biāo)簽的 test 屬性中寫的是對象的屬性名,如果是包裝類的對象要使用 OGNL 表達式的寫法。

另外要注意 where 1=1 的作用~! 

2.1.3 測試

@Test
public void testFindByUser() {
User u = new User();
u.setUsername("%王%");
u.setAddress("%順義%");
//6.執(zhí)行操作
List<User> users = userDao.findByUser(u);
for(User user : users) {
System.out.println(user);
} }

2.2 動態(tài) SQL 之標(biāo)簽

為了簡化上面 where 1=1 的條件拼裝,我們可以采用標(biāo)簽來簡化開發(fā)。

2.2.1 持久層 Dao 映射配置

<!-- 根據(jù)用戶信息查詢 --> 
<select id="findByUser" resultType="user" parameterType="user"> <include refid="defaultSql">
</include> <where> <if test="username!=null and username != '' ">
and username like #{username}
</if> <if test="address != null">
and address like #{address}
</if>
</where>
</select>

2.3 動態(tài)標(biāo)簽之標(biāo)簽

需求

傳入多個 id 查詢用戶信息,用下邊兩個 sql 實現(xiàn):

SELECT * FROM USERS WHERE username LIKE ‘%張%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE ‘%張%' AND id IN (10,89,16)

這樣我們在進行范圍查詢時,就要將一個集合中的值,作為參數(shù)動態(tài)添加進來。

這樣我們將如何進行參數(shù)的傳遞?

2.3.1 在 QueryVo 中加入一個 List 集合用于封裝參數(shù)

/**
* 
* <p>Title: QueryVo</p>
* <p>Description: 查詢的條件</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public class QueryVo implements Serializable {
private List<Integer> ids;
public List<Integer> getIds() {
return ids; }
public void setIds(List<Integer> ids) {
this.ids = ids; } }

2.3.2 持久層 Dao 接口

/**
* 根據(jù) id 集合查詢用戶
* @param vo
* @return
*/
List<User> findInIds(QueryVo vo);

2.3.3 持久層 Dao 映射配置

<!-- 查詢所有用戶在 id 的集合之中 -->
?<select id="findInIds" resultType="user" parameterType="queryvo">
<!-- select * from user where id in (1,2,3,4,5); -->
?<include refid="defaultSql"></include>?
?<where>
? ? ? ? ? ? <if test="list != null and list.size() > 0">
? ? ? ? ? ? ? ? <foreach collection="list" open="id in ( " close=")" item="uid"
? ? ? ? ? ? ? ? ? ? ? ? ?separator=",">
? ? ? ? ? ? ? ? ? ? #{uid}
? ? ? ? ? ? ? ? </foreach>
? ? ? ? ? ? </if>
? ? ? ? </where>
</select>

SQL 語句:

select 字段 from user where id in (?)

<foreach>標(biāo)簽用于遍歷集合,它的屬性:

  • collection:代表要遍歷的集合元素,注意編寫時不要寫#{}
  • open:代表語句的開始部分
  • close:代表結(jié)束部分
  • item:代表遍歷集合的每個元素,生成的變量名
  • sperator:代表分隔符

2.3.4 編寫測試方法

@Test
public void testFindInIds() {
QueryVo vo = new QueryVo();
List<Integer> ids = new ArrayList<Integer>();
ids.add(41);
ids.add(42);
ids.add(43);
ids.add(46);
ids.add(57);
vo.setIds(ids);
//6.執(zhí)行操作
List<User> users = userDao.findInIds(vo);
for(User user : users) {
System.out.println(user);
} }

2.4 Mybatis 中簡化編寫的 SQL 片段

Sql 中可將重復(fù)的 sql 提取出來,使用時用 include 引用即可,最終達到 sql 重用的目的。

2.4.1 定義代碼片段

<!-- 抽取重復(fù)的語句代碼片段 -->
 <sql id="defaultSql">
	select * from user
</sql>

2.4.2 引用代碼片段

<!-- 配置查詢所有操作 --> 
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
<!-- 根據(jù) id 查詢 --> <select id="findById" resultType="UsEr" parameterType="int">
<include refid="defaultSql"></include>
where id = #{uid}
</select>

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Maven實現(xiàn)項目構(gòu)建工具

    Maven實現(xiàn)項目構(gòu)建工具

    本文主要介紹了Maven實現(xiàn)項目構(gòu)建工具,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Spring Boot打包部署和環(huán)境配置詳解

    Spring Boot打包部署和環(huán)境配置詳解

    這篇文章主要介紹了Spring Boot打包部署和環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點解析

    Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點解析

    樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點)按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機構(gòu)都可用樹形象表示
    2021-10-10
  • Java程序中實現(xiàn)調(diào)用Python腳本的方法詳解

    Java程序中實現(xiàn)調(diào)用Python腳本的方法詳解

    這篇文章主要介紹了Java程序中實現(xiàn)調(diào)用Python腳本的方法,結(jié)合實例形式分析了eclipse環(huán)境中使用Java調(diào)用Python腳本的相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2018-03-03
  • 一文詳解Java如何創(chuàng)建和銷毀對象

    一文詳解Java如何創(chuàng)建和銷毀對象

    Java由Sun Microsystems發(fā)明并在1995年發(fā)布,是世界上使用最廣泛的編程語言之一。本文主要和大家介紹一下Java是如何創(chuàng)建和銷毀對象的,希望對大家有所幫助
    2022-11-11
  • Java找出兩個大數(shù)據(jù)量List集合中的不同元素的方法總結(jié)

    Java找出兩個大數(shù)據(jù)量List集合中的不同元素的方法總結(jié)

    本文將帶大家了解如何快速的找出兩個相似度非常高的List集合里的不同元素。主要通過Java API、List集合雙層遍歷比較不同、借助Map集合查找三種方式,需要的可以參考一下
    2022-10-10
  • 簡單了解Java關(guān)鍵字throw和throws的區(qū)別

    簡單了解Java關(guān)鍵字throw和throws的區(qū)別

    這篇文章主要介紹了簡單了解Java關(guān)鍵字throw和throws的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Java利用POI實現(xiàn)導(dǎo)入導(dǎo)出Excel表格示例代碼

    Java利用POI實現(xiàn)導(dǎo)入導(dǎo)出Excel表格示例代碼

    最近工作中遇到一個需求,是需要導(dǎo)出數(shù)據(jù)到Excel表格里,所以寫個Demo測試一下,還是比較簡單的,現(xiàn)在分享給大家,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-10-10
  • springboot程序啟動慢-未配置hostname的解決

    springboot程序啟動慢-未配置hostname的解決

    這篇文章主要介紹了springboot程序啟動慢-未配置hostname的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 淺談java封裝

    淺談java封裝

    封裝封裝就是將屬性私有化,提供公有的方法訪問私有的屬性。*實現(xiàn)封裝的步驟:(1)修改屬性的可見性來限制對屬性的訪問。(2)為每個屬性創(chuàng)建一對賦值方法和取值方法,用于對這些屬性的訪問。(3)在賦值和取值方法中,加入對屬性的存取限制。
    2015-03-03

最新評論