【笔记】mybatis的sqlSession和Mapper详解
文章目錄
- SqlSession介紹和使用
- Mapper映射器
- 總結
SqlSession介紹和使用
SqlSession是一個接口類,它類似于你們公司前臺的美女客服,它扮演著門面的作用,而真正干活的是Executor接口,你可以認為它是公司的工程師。假設我是客戶找你們公司干活,我只需要告訴前臺的美女客服(SqlSession)我要什么信息(參數),要做什么東西,過段時間,她會將結果給我。在這個過程中,作為用戶的我所關心的是:
1)要給美女客服(SqlSession)什么信息(功能和參數)。
2)美女客服會返回什么結果(Result)。
而我不關心工程師(Executor)是怎么為我工作的,只要前臺告訴工程師(Executor),工程師就知道如何為我工作,這個步驟對我而言是個黑箱操作。 在MyBatis中SqlSession接口的實現類有兩個,分別是DefaultSqlSession和SqlSession Manager。這里我們暫時不深入討論Executor接口及其涉及的其他類,只關心SqlSession的用法就好。
我們構建了SqlSessionFactory,然后生成MyBatis的門面接口SqlSession。SqlSession接口類似于一個JDBC中的Connection接口對象,我們需要保證每次用完正常關閉它,所以正確的做法是把關閉SqlSession接口的代碼寫在finally語句中保證每次都會關閉SqlSession,讓連接資源歸還給數據庫。如果我們不及時關閉資源,數據庫的連接將很快被耗盡,系統很快因為數據庫資源的匱乏而癱瘓。
SqlSession是一個會話,相當于JDBC的一個Connection對象,它的生命周期應該是在請求數據庫處理事務的過程中。它是一個線程不安全的對象,在涉及多線程的時候我們需要特別的當心,操作數據庫需要注意其隔離級別,數據庫鎖等高級特性。此外,每次創建的SqlSession都必須及時關閉它,它長期存在就會使數據庫連接池的活動資源減少,對系統性能的影響很大。正如前面的代碼一樣,我們往往通過finally語句塊保證我們正確的關閉SqlSession。它存活于一個應用的請求和操作,可以執行多條SQL,保證事務的一致性。
讓我們看看實現的偽代碼,如代碼所示。
標準SqlSession使用方法 :
這樣SqlSession就被我們創建出來了,在finally語句中我們保證了它的合理關閉,讓連接資源歸還給數據庫連接池,以便后續使用。
SqlSession的用途主要有兩種。
(1)獲取映射器,讓映射器通過命名空間和方法名稱找到對應的SQL,發送給數據庫執行后返回結果。
(2)直接通過命名信息去執行SQL返回結果,這是iBatis版本留下的方式。在SqlSession層我們可以通過update、insert、select、delete等方法,帶上SQL的id來操作在XML中配置好的SQL,從而完成我們的工作,與此同時它也支持事務,通過commit、rollback方法提交或者回滾事務。 關于這兩種用途我們會在映射器里面進行討論,這兩種用途的優劣我們也會進行研討。
Mapper映射器
Mapper是一個接口,而沒有任何實現類,它的作用是發送SQL,然后返回我們需要的結果,或者執行SQL從而修改數據庫的數據,因此它應該在一個SqlSession事務方法之內,是一個方法級別的東西。它就如同JDBC中的一條SQL語句的執行,它最大的范圍和SqlSession是相同的。盡管我們想一直保存著Mapper,但是你會發現它很難控制,所以盡量在一個SqlSession事務的方法中使用它們,然后廢棄掉。
映射器是由Java接口和XML文件(或注解)共同組成的,它的作用如下。
● 定義參數類型。
● 描述緩存。
● 描述SQL語句。
● 定義查詢結果和POJO的映射關系。
一個映射器的實現方式有兩種,一種是通過XML文件方式實現,如在mybatis-config.xml文件中寫一個XML文件,它是用來生成Mapper的。
mybatis-config.xml:(一個基礎的mybatis配置文件)
其次是一個簡單的映射文件:
role.xml:
再者,我們還需要一個接口,注意僅僅是接口,而無需實現類
public interface RoleMapper{ public Role getRole(Long id) }這里我們給出了SQL,但是并沒有給出映射規則,因為這里我們使用的SQL列名和POJO的屬性名保持一致,這個時候MyBatis會自動提供映射規則,所以省去了這部分的配置工作。
描述一下上面的role.xml文件做了什么:
● 這個文件是我們在配置文件mybatis-config.xml中配置了的,所以MyBatis會讀取這個配置文件,生成映射器。
● 定義了一個命名空間為com.learn.chapter2.mapper.RoleMapper的SQL Mapper,這個命名空間和我們定義的接口的全限定名是一致的。
● 用一個select元素定義了一個查詢SQL,id為getRole,和我們接口方法是一致的,而parameterType則表示我們傳遞給這條SQL的是一個java.lang.Long型參數,而resultType則定義我們需要返回的數據類型,這里為role,而role是我們之前注冊com.learn.chapter2.po.Role的別名。
#{id}為這條SQL的參數。而SQL列的別名和POJO的屬性名稱保持一致。那么MyBatis就會把這條語句查詢的結果自動映射到我們需要的POJO屬性上,這就是自動映射。我們可以用SqlSession來獲取這個Mapper:
//用sqlSession來獲取Mapper RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); Role role = roleMappler.getRole(1L);//執行查詢方法 System.out.println(role.getRoleName());//打印角色名稱另外一種就是通過代碼方式實現,在Configuration里面注冊Mapper接口,但是更建議使用xml文件配置方式,原因:
● Java注解是受限的,功能較少,而MyBatis的Mapper內容相當多,而且相當復雜,功能很強大,使用XML文件方式可以帶來更為靈活的空間,顯示出MyBatis功能的強大和靈活。
● 如果你的SQL很復雜,條件很多,尤其是存在動態SQL的時候,寫在Java文件里面可讀性較差,增加了維護的成本。
如果上面的xml配置改為注解的方式:
public interface RoleMapper2{ @Select(value = "select id,role_name as roleName.note from t_role where id = #{id}") public Role getRole(Long id) }我們使用了@Select注解,注入了和XML一樣的select元素,這樣MyBatis就會讀取這條SQL,并將參數id傳遞進SQL。同樣使用了別名,這樣MyBatis會為我們自動映射,得到Role對象。
同時我們需要加入
configuration.addMapper(RoleMapper2.class);
注冊這個接口為映射器。
一些其他疑惑:
我們使用的僅僅是Java接口和一個XML文件(或者注解)去實現Mapper,Java接口不是實現類,對于Java語言不熟悉的讀者肯定會十分疑惑,一個沒有實現類的接口怎么能夠運行呢?其實它需要運用到Java語言的動態代理去實現,而實現Java語言的動態代理的方式有多種。這里我們還是集中于它的用法,所以可以這樣理解:我們會在MyBatis上下文中描述這個接口,而MyBatis會為這個接口生成代理類對象,代理對象會根據“接口全路徑+方法名”去匹配,找到對應的XML文件(或注解)去完成它所需要的任務,返回我們需要的結果。
總結
SqlSessionFactory一般是一個全局單例,對應一個數據庫連接池,用它來創建SqlSession
SqlSession相當于一個JDBC的Connection對象,在一次請求事務會話后,我們會將它關閉。它可以為我們獲得Mapper
Mapper相當于執行一條條SQL,由于它們難以控制,當SqlSession銷毀的時候也會銷毀它
總結
以上是生活随笔為你收集整理的【笔记】mybatis的sqlSession和Mapper详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载】一文彻底拿下Java异常
- 下一篇: springboot进行图片上传并访问资