您好,登錄后才能下訂單哦!
最近在休陪產假,時間比較零碎,準備看2本書充實下,一本是「深入淺出MyBatis:技術原理與實踐」,一本是「RabbitMQ實戰:高效部署分布式消息隊列」,為了加深記憶和理解,會進行整理、擴展和記錄。
看書的目標不是把所有的細節都記住,而是從整體上了解一個技術能做什么,包含的特性、基本模塊,實現原理和常見使用場景。
本篇分享MyBatis書籍的第一篇,首先回憶下JDBC的相關概念,了解Java提供的訪問數據庫最基本的方式,然后介紹下MyBatis的基本特性和核心組件,最后說下書的整體結構,了解后續文章的大致內容。
Java程序都是通過JDBC連接數據庫的,通過SQL對數據庫編程,JDBC是由SUN公司提出的一些列規范,只定義了接口規范,具體實現由各個數據庫廠商去實現,它是一種典型的橋接模式。
橋接模式是一種結構型設計模式,它的主要特點是把抽象與行為實現分離開來,分別定義接口,可以保持各部分的獨立性以及應對他們的功能擴展。
所謂規范,就是自己定義了標準接口,做了如下抽象:用Connection代表和數據庫的連接,用Statement執行SQL,用ResultSet表示SQL返回的結果,提供了對數據的便利。從Connection可以創建Statement,Statement執行查詢得到ResultSet。
上面說的Connection、Statement、ResultSet都應該是接口,具體實現由各個數據庫提供商提供。有了規范,可以通過統一的接口,訪問多種類型的數據庫,可隨便切換數據庫。
上面提到,接口的實現由各個廠商提供,那么實現類的類名就會不統一,去創建Connection對象時,代碼就會寫死某個實現類,切換數據庫時,就需要修改代碼,這樣不太好。為了解決這個問題,抽象了Driver驅動的概念。
Connection con=MySqlConnectionImpl("127.0.0.1",3306,"mi_user",userName,pwd);
每個數據庫都需要實現Driver接口,通過Driver可獲得數據庫連接Connection,通過反射機制動態創建。
Class.forName("com.mysql.jdbc.Drier");
同一個程序可能訪問不同的數據庫,通過DriverManager來管理驅動,Driver在初始化的時候,需要注冊到DriverManager中。
DriverManager提供了一個getConnection方法,用于建立數據庫Connection:
Connection con=DriverManager.getConnection("127.0.0.1",3306,"mi_user",userName,pwd);
如果有多個數據庫驅動,DriverManager如何區分呢,需要在數據庫連接url中指定,比如mysql需要添加jdbc:mysql前綴:
String url= "jdbc:mysql://127.0.0.1:3306/mi_user";
Connection con=DriverManager.getConnection(url,userName,pwd);
數據源DataSource包含連接池和連接池管理2個部分,習慣上稱為連接池。在系統初始化的時候,將數據庫連接作為對象存儲在內存中,當需要訪問數據庫時,從連接池中取出一個已建立的空閑連接對象。
使用數據源,獲取其DataSource對象,通過該對象動態的獲取數據庫連接。另外,DataSource對象可以注冊到名字服務(JNDI)中,可以通過名字服務獲得DataSource對象,無需硬性編碼驅動。
DriverManager是JDBC1提供的,DataSource是JDBC2新增的功能,提供了更好的連接數據源的方法。
通過上面的介紹,傳統的JDBC編程給我們帶來了連接數據庫的功能,但其工作量相對較大,首先連接,然后處理JDBC底層事務,處理數據類型,還要對可能產生的異常進行捕捉處理并正確的關閉資源。
實際工作中,很少使用JDBC進行編程,提出了ORM模型,主要解決數據庫數據和POJO對象的相互映射。
Hibernate和Mybatis都是ORM模型,Hibernate提供的是一種全表映射的模型,對JDBC的封裝程度比較高。但Hibernate也有不少缺點,列舉如下:
大型互聯網環境中,靈活、SQL優化,減少數據的傳遞是最基本的優化方法,Hibernate無法滿足要求,而MyBatis提哦給你了靈活、方便的方式,是一個半自動映射的框架。
MyBatis需要手工匹配提供POJO、SQL和映射關系,而全表映射的Hibernate只需要提供POJO和映射關系。
MyBatis可以配置動態SQL,可以解決Hibernate的表名根據時間變化,不同的條件下列明不一樣的問題。可以優化SQL,通過配置決定SQL映射規則,也能支持存儲過程,對于一些復雜和需要優化性能的SQL的查詢它更加方便。
核心組件主要包括以下幾個:
每個MyBatis應用都是以SqlSessionFactory的實例為中心的,它的任務是創建SqlSession。SqlSesion類似于一個JDBC的Connection對象。
提供了2種方式創建SqlSessionFactory:一種是XML配置的方式,一種是代碼的方式,推薦使用XML配置的方式。
定義mybatis-config.xml文件如下:
<? xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="application.properties">
</properties>
<!-- 定義別名 -->
<typeAliases>
<typeAlias alias="role" type="com.learn.chapter2.po.Role"/>
</typeAliases>
<!-- 定義數據庫信息.默認使用development數據庫構建環境 -->
<environments default="development">
<environment id="development">
<!-- 采用jdbc事務管理 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 定義映射器 -->
<mappers>
<mapper resource="com\learn\chapter2\mapper\roleMapper.xml"/>
</mappers>
</configuration>
創建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession是一個接口類,扮演者門面的作用,真正干活的是Executor接口。需要保證每次用完正常關閉它。
SqlSession sqlSession=null;
try{
sqlSession=sqlSessionFactory.openSession();
//some code
sqlSession.commit();
} catch(Exception ex){
sqlSession.roolback();
} finally{
if(sqlSession!=null){
sqlSession.close();
}
}
映射器是由Java接口和XML文件(或注解)共同組成的,作用如下:
首先,定義Java接口:
public interface RoleMapper{
public Role getRole(Long id);
}
然后,定義映射XML文件,RoleMapper.xml
<? xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<mapper namespace ="com.learn.chapter2.mapper.RoleMapper">
<select id="getRole" paramterType="long" resultType="role" >
select id,role_name as roleName , note from t_role where id=#{id}
</select>
</mapper>
POJO對象Role的定義比較簡單,就不列出了。#{id}為這條SQL的參數,SQL列的別名和POJO的屬性名稱保持一致,會把這條語句的查詢結果自動映射到Role屬性上,這就是自動映射。
執行查詢
RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1L);
String roleName=role.getRoleName();
SqlSessionFactory在MyBatis應用的整個生命周期中,每個數據庫只對應一個SqlSessionFactory,可以實現一個工具類,以單例模式獲取該對象。
SqlSession的生命周期在請求數據庫處理事務的過程中,它是一個線程不安全的對象,在涉及多線程的時候要特別當心。它存活于一個應用的請求和操作,可以執行多條SQL,保證事務的一致性。
Mapper的作用是發送SQL,然后返回需要的結果,或者執行SQL修改數據庫的數據,所以它應該在一個SqlSession事務方法之內,如同JDBC中一條SQL語句的執行,它最大的范圍和SqlSession是相同的。
本書分為3個部分,依次介紹了MyBatis的基礎應用、原理及插件開發、實戰應用。
主要介紹如何高效地使用MyBatis:
深入源碼理解MyBatis的內部運行原理以及插件的開發方法和技巧:
主要講解MyBatis的一些實用的場景:
下篇會介紹MyBatis的相關配置,更好的配置MyBatis以適用于不同的業務場景,以及提供給我們的擴展。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。