在使用MyBatis框架時,設計兩個核心的d對象:SqlSessionFactory和SqlSession.java
SqlsessionFactorymysql
SqlSessionFactory是單個數據庫映射關係通過編譯後的內存鏡像,其主要做用用來建立SqlSession對象,SqlSessionFactory實例對象是能夠經過SqlSessionFactoryBulider對象來構建,而SqlSessionFactoryBulider對象能夠經過XML文件或者Configuration實例來建立SqlSessionFactory實例,其代碼以下:web
//1.讀取配置文件 String resource ="mybatis-config.xml";
InputStream inputStream=Resources.getResourceAsStream(resource); //2.獲取會話工廠對象 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
注意:SqlSessionFactory對象是線性安全的,它一旦被建立,在整個應用程序間都會存在,若是咱們屢次的建立同一個SqlSessionFactory對象,那麼數據庫的資源很快就會被應用完,爲了解決這個問題,一般,一個數據庫是建一個SqlSessionFactory對象的。
spring
SqlSessionsql
SqlSession對象是應用層和持久層之間進行數據庫操做的一個單線程對象,其中主要做用是執行持久化操做,SqlSession對象中包含了全部執行數據庫操做的方法,因爲底層封裝了JDBC的鏈接,因此能夠直接使用SqlSession對象來執行已經映射的SQL語句。數據庫
注意:每個線程都應該有本身的SqlSession實例,而且該SqlSession實例是不可共享的,同時,SqlSession是線程不安全的,所以,其使用範圍最好是在一個請求中,或者一個方法中,絕對不能將其放入一個類的靜態字段中,實例字段或者任何類型的管理範圍中,使用完SqlSession後,要及時的關閉它,一般能夠將其放入finally塊中關閉。apache
Sqlsession sqlSession=sqlSessionFactory.openSession(); try{ //執行操做 }finally{ //關閉sqlSession sqlSession.close(); }
使用工具類來建立SqlSession對象緩存
因爲每一個方法執行都須要獲取配置文件,並根據配置文件的信息來構建SqlSessionFactory對象,而後建立SqlSession對象,這致使了大量重複的代碼,爲了簡化開發,能夠將重複的代碼封裝到一個工具類中,而後經過這個工具類來建立SqlSession安全
package com.itheima.util; /** * 工具類 * @author 12428 * */ import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.jdbc.Null; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtils { private static SqlSessionFactory sqlSessionFactory=null; //獲取sqlSessionFactory對象 static { try { //使用MyBatis提供的Resource類加載配置文件 Reader reader =Resources.getResourceAsReader("mybatis-config.xml"); //構建SqlSessionFactory對象 sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader); }catch(Exception e) { e.printStackTrace(); } } //獲取SqlSession對象的靜態方法 public static SqlSession getSession() { return sqlSessionFactory.openSession(); } }
二.配置文件服務器
主要元素
在MyBatis核心配置文件中,<configuration>元素是配置文件的根元素,其餘的元素都要在其中配置,MyBatis的配置文件mybatis-config.xml中的主要元素以下:
注意:<configuration>的子元素中必須按照由上到下的順序進行配置,不然MyBatis在解析XML配置文件的時候會出錯。
<properties>元素
該元素是一個配置屬性的元素,該元素一般是用於將內部的配置外在化,既經過外部的配置來動態的替換內部定義的屬性。例如,數據庫的來鏈接屬性,就能夠經過Java文件中配置文件來替換,具體以下:
1.在src下建立一個db.properties屬性文件,內容以下:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring jdbc.username=root jdbc.password=abc
2.在MyBatis配置文件mybatis-config.xml中的configuration元素中配置子元素<properties>
<properties resource="db.properties"/> //映入外部配置文件
3.修改<dataSource>配置文件中數據庫鏈接的信息,具體以下。
<!-- 數據庫鏈接池 --> <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>
完成了上面的配置後,dataSource中鏈接數據庫的4個屬性,就能夠由db.properties文件中的對應的值來動態的替換。
因爲使用properties配置文件來配置屬性值能夠方便的在多個配置文件中使用這些屬性,而且方便往後的維護和修改,因此在實際開發中,使用properties配置文件來配置屬性值是最經常使用的方法。
MyBatis在預處理語句(PrparedStatement)中設置了一個參數或者從結果集中取出一個值時,都會使用其框架內部的註冊了的typeHandler(類型處理器)進行相關的處理,typeHandler是將預處理語句中傳入的參數從javaType(java類型)裝換爲jdbcType(JDBC)類型,或者從數據庫中取出結果時將jdbcType轉換爲javaType類型。MyBatis框架提供了一些默認的類型轉換器,若是提供的類型轉換器不能知足需求時,能夠自定義類型轉換器,自定義類型轉換器能夠經過實現TypeHandler接口或者繼承BaseTypeHandle類來定義。
1.註冊一個類的類型處理器:
<typeHandlers> <!--以單個類的形式來配置:handler屬性是用指定在程序中自定義的類型處理器類--> <typeHandler handler="com.itheima.type.CustomtypeHandler"/> </typeHandlers>
2.註冊一個包中的全部類型處理器:
<typeHandlers> <!--註冊一個包中全部的typeHandler,系統會在啓動時會自動掃描包下的全部文件--> <package name="com.itheima.type"/> </typeHandlers>
在配置文件中,<environments>元素用於對環境進行配置。MyBatis的環境配置其實是數據源的配置,咱們能夠經過<environments>元素來配置多種數據源。既配置多種數據庫。
使用該元素進行環境配置時的實例以下:
<!--由於一個environments元素中能夠配置多個數據-庫環境<environment>,default屬性是指定使用哪一個數據庫環境,該屬性值是<environment>元素的id值->
<environments default="mysql">
<!-- 配置id爲mysql的數據庫環境 --> <environment id="mysql">
<!-- 使用JDBC的事務管理 --> <transactionManager type="JDBC"/> <!-- 數據庫鏈接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/spring"/> <property name="username" value="root"/> <property name="password" value="abc"/> </dataSource> </environment> </environments>
<environment>元素是<environments>的子元素,該元素能夠有多個。在<environment>中包含了事務管理和數據源的配置信息,其中<teansactionManager>是用於配置事務管理,其中它的type屬性是用於指定使用哪一種事務管理器;<dataSource>是用於配置數據源,其中的type屬性是用於指定使用哪一種數據源。
對於數據源的配置,MyBatis框架提供了UNPOOLED,POOLED,JNDI這三種類型的數據源。
(1)UNPOOLED:配置此數據源後,在每次被請求時會打開和關閉鏈接,此配置適用於對性能沒有要求的簡單應用程序是一個很好的選擇。
(2)POOLED:此數據源是利用」池「的概念將JDBC鏈接對象組織起來,避免了在建立新的實例時所須要初始化和認證的時間,這種方法使得併發web應用能夠快速的響應,是當前流行的處理方法。
(3)JNDI:此數據源是能夠在EJB或者應用服務器上使用,(是從TOMCAT內部來獲取一個內置的數據庫鏈接池)
在配置文件中,<mappers>元素是用來指定Mapper配置文件的位置,通常是使用以下四種方法引入:
1.使用類路勁引入
<mappers> <mapper resource="com/itheima/mapper/UserMapper.xml"/> </mappers>
2.使用本地文件路勁引入
<mappers> <mapper url="file:///D:/com/itheima/mapper/UserMapper.xml"/> </mappers>
3.使用接口類來引入
<mappers> <mapper class="com.itheima.mapper.UserMapper"/> </mappers>
4.使用包名來引入文件
<mappers> <package name="com.itheima.mapper"/> </mappers>
映射文件是框架中的重要文件,能夠說,此框架的強大之處就在於映射文件的編寫上,
1.主要元素
在映射文件中,<mapper>元素是映射文件的根元素,其餘元素都是它的子元素,
2.<select>元素
該元素是用於映射查詢語句,它能夠幫助咱們從數據庫中讀取出數據,並組裝數據庫給業務開發人員
使用select元素執行查詢操做很是簡單,其示例以下
<select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer"> select * from t_customer where id=#{id} </select>
select元素的經常使用屬性以下:
屬性 | 說明 |
id | 表示命名空間中的惟一標識符,常常和命名空間namespace一塊兒使用,組合namespace一塊兒使用後若是不惟一,就會拋出錯誤。 |
parameterType | 該屬性是表示傳入sql參數類的全限定名或者別名,它是一個可選屬性。 |
resultType | 該屬性是表示從sql語句中返回結果的類型的全限定名或者別名,若是是集合類型,那麼返回的應該是集合裏能夠包含的類型,而不是集合自己。 |
resultMap | 該屬性是表示外部resultMap的命名引用,返回時可使用resultMap或者resultType |
flushCache | 表示在調用SQL語句後,是否清除緩以前查詢的本地緩存和二級緩存,默認時false |
useCache | 用於控制二級緩存的開啓和關閉,其值爲布爾型,默認爲true,表示將查詢結果放在二級緩存裏 |
timeout | 用於設置超時參數,單位爲秒,超時時將拋出異常 |
fetchSize | 獲取記錄的總條數設置,其默認值是unset(依賴於驅動) |
statementType | 用於設置MyBatis使用哪一個JDBC的Statement工做。 |
resultSetType | 表示結果集的類型 |
3<insert>元素
insert元素是用於映射插入語句,在執行完元素中定義的SQL語句後,就會返回一個表示插入記錄數的整數,insert元素的配置實例以下
<insert id="addCustomer" parameterType="com.itheima.po.Customer" flushCache="true" statmentType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20"> </insert>
insert元素的屬性大部分和select相同,可是它由三個特定是屬性,這三個屬性以下:
屬性 | 說明 |
keyProperty | (僅對insert和update有用)此屬性的做用是將插入或者更新操做時的返回值賦給PO類的某個屬性,一般會設置爲主鍵對應的屬性,若是須要設置聯合主鍵,能夠在多個值之間用逗號分開 |
keyColumn | (僅對insert和update有用)此屬性的做用是用於設置第幾行是主鍵,當主鍵列不是表中的第一列是,是須要設置這個屬性,在須要使用主鍵聯合時,值可使用逗號分開 |
useGeneratedKeys | (僅對insert和update有用)此屬性會使MyBatis使用JDBC的getGeneratedKeys()方法來獲取由數據庫內部產生的主鍵,如MYSql和sql Server等自動生成的主鍵 |
執行查詢操做後,不少時候咱們須要返回插入成功的數據生成的主鍵,此時就能夠經過上面所講解的3個屬性來實現。
當使用的數據庫支持自動增加時,咱們能夠經過keyproperty屬性來指定PO類的某個屬性接受主鍵的返回值,同時設置useGeneratedKeys的屬性值爲true,其使用以下:
<insert id="addCustomer" parameterType="com.itheima.po.Customer" keyProperty="id" useGeneratedKeys="true"> insert into t_customer(username,jobs,phone) values(#{username},#{jobs},#{phone}) </insert>
使用以上的配置後執行插入操做後,就會返回插入成功的行數,以及插入行的主鍵值,爲了驗證配置,可使用以下代碼測試:
@Test public void addCustomer(){ //獲取SqlSession對象 SqlSession sqlSession=MyBatisUtis.getSession(); Customer customer=new Customer(); customer.setUsername("rose"); customer.setJobs("student"); customer.setPhone("11111111"); int rows=sqlSession.insert("som.itheima.mapper.CustomerMapper.addCustomer",customer); //輸出插入數據的主鍵 System.out.println(customer.getId()); if(rows>0){ system.out.println("您成功插入了"+rows+"行數據!"); }else{ system.out.println("插入失敗!"); } //執行提價事務 sqlSession.commit(); //關閉資源 sqlSession.close(); }
當數據庫不能夠支持自動增加時,如Oracle,或者自動增加的數據庫取消了自動增加的規則時,可使用MyBatis提供的另外一種方法來自定義生成主鍵,具體配置以下:
<insert id="addCustomer" parameterType="com.itheima.po.Customer" > <selectKey keyProperty="id" resultType="Integer" order="BEFORE"> select if(max(id) is null,1, max(id)+1) as newId from t_customer </selectKey> insert into t_customer(id,username,jobs,phone) values(#{id},#{username},#{jobs},#{phone}) </insert>
在執行上面代碼時,會先執行<selectKey>中的語句,他會經過自定義的語句來設置主鍵的值,若是t_customer表中的沒有記錄,就將id的值設置爲1,若是有id值,就將id值加上1,做爲新的主鍵,而後在調用插入語句。
selectKey能夠設置的屬性以下:
<selectKey keyProperty="id" resultType="Integer" order="BEFORE" statmentType="PREPARED">
</selectKey>
order屬性能夠被設置爲BEFORE或者AFTER,若是設置爲BREFORE,那麼它會先執行<selectKey>中的配置來設置主鍵,而後執行插入語句,若是設置爲AFTER,那麼它會先執行插入語句,而後再執行<selectKey>中的配置內容。
4.<update>和<delete>元素
這兩個元素的執行很是簡單,它們的配置也基本相同,與<insert>元素同樣,這裏兩個元素在執行後,也會返回一個表示影響記錄條數的整數。
5.<sql>元素
<sql>元素是用於定義可重用的SQL片斷,而後在其餘的語句中引用這一片代碼,例如定義一個包含了id,username,jobs,phone字段的代碼片斷以下:
<sql id="customerColumns">id,username,jobs,phone</sql>
引用此代碼以下:
<select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer"> select <include refid="customerColumns"/> from t_customer where id=#{id} </select>
使用<include>元素的refid屬性能夠引用自定義的代碼片斷,refid屬性值自定義代碼段的id值。
6.<resultMap>元素
該元素是用於配置查詢返回的結果與JavaBean類之間的映射關係,是MyBatis中最強大的元素。它的主要做用是定義映射規則,級聯的更新,以及定義類型轉換器。
<resultMap>元素包含了一些子元素,他的結構以下:
<!--resultMap元素的結構 --> <resultMap type="" id=""> <!--類在實例化時,用來注入結果到構造方法中--> <constructor> <idArg/> <!--ID參數:標記結果做爲Id--> <arg/> <!--注入到構造方法中的一個普通結果--> </constructor> <id/> <!--用來表示哪一個列示主鍵--> <result> <!--注入到字段或者JavaBean屬性的普通結果--> <association property=""/> <!--用於一對一關聯--> <collection property=""/> <!--用於一對多關聯--> <discriminator javaType=""> <case value=""/> <!--基於某些值的結果映射--> </discriminator> </resultMap>
該元素的type屬性是表示須要映射的POJO,id屬性是這個resultMap的惟一標識,它的子元素<constructor>用於配置構造方法,當一個POJO中未定義無參數的構造方法時,就可使用<constructor>配置。子元素<id>是用於表示哪一個鍵是主鍵,而<result>是用於表示普通POJO和數據表中普通列的映射關係,<association>和<collection>用於配置處理多表時的關聯關係。而<discriminator>是用於處理一個單獨的數據庫查詢返回不少不一樣數據類型結果集的狀況。
在默認的狀況下,MyBatis程序在運行時會自動的將查詢到 的結果和須要返回的對象的屬性進行匹配複製(須要表中的列和對象的屬性名徹底一致。然而,在現實中,數據表中的列和須要返回的對象屬性可能並非徹底同樣,這時,就可使用該元素進行處理。