教你學會SSM框架第七步,詳解MyBatis核心配置

7.1 MyBatis的核心對象

MyBatis框架主要涉及兩個核心對象

  • SqlSessionFactory
  • SqlSession

7.1.1 SqlSessionFactory

SqlSessionFactory是單個數據庫映射關係經過編譯後的內存鏡像,用於創建SqlSession。SqlSessionFactory對象的實例通過SqlSessionFactoryBuilder對象來構建,通過XML配置文件或一個預先定義好的Configuration實例構建出SqlSessionFactory的實例。通過XML配置文件構建出SqlSessionFactory實例的實現代碼如下:

//讀取配置文件
InputStream inputStream=Resource.getResourceAsStream(配置文件位置);
//構建SqlSessionFactory
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);

SqlSessionFactory對象是線程安全的,一旦被創建,在整個應用執行期間都會存在。如果多次創建同一個數據庫的SqlSessionFactory,那麼此數據庫的資源將很容易被耗盡。所以在構建SqlSessionFactory實例時,建議使用單列模式。

7.1.2 SqlSession

SqlSession是應用程序與持久層之間執行交互操作的一個單線程對象,其主要作用是執行持久化操作。SqlSession對象包含數據庫中所有執行SQL操作的方法,底層封裝了JDBC連接,所以可以直接使用其實例來執行已映射的SQL語句。SqlSession實例是不能被共享的,也是線程不安全的,因此其使用範圍最好限定在一次請求或一個方法中,絕不能將其放在一個類的靜態字段、實例字段或任何類型的管理範圍中使用。使用完SqlSession對象之後,要及時將它關閉,通常可以將其放在finally塊中關閉。
SqlSession對象常用方法

  • < T> T selectOne(String statement);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id。該方法返回執行SQL語句查詢結果的一個泛型對象
  • < T>I selectOne(String statement, Object parameter);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id,parameter是查詢所需的參數。該方法返回執行SQL語句查詢結果的一個泛型對象
  • < E> List< E> selectList( String statement);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id。該方法返回執行SQL語句查詢結果的泛型對象的集合
  • < E> List< E> selectList( String statement, Object parameter);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id,parameter是查詢所需的參數。該方法返回執行SQL語句查詢結果的泛型對象的集合
  • e < E> List< E> selectList(String statement, Object parameter, RowBounds rowBounds);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id,parameter是查詢所需的參數,rowBounds是用於分頁的參數對象。該方法返回執行SQL語句查詢結果的泛型對象的集合
  • void select(String statement, Object parameter, ResultHandler handler);
    查詢方法。參數statement是在配置文件中定義的< select>元素的id,parameter是查詢所需的參數,ResultHandler對象用於處理查詢返回的複雜結果集,通常用於多表查詢
  • int insert( String statement);
    插入方法。參數statement是在配置文件中定義的< insert>元素的id。該方法返回執行SQL語句所影響的行數。
  • int insert(String statement, Object parameter);
    插入方法。參數statement是在配置文件中定義的< insert>元素的id,parameter是插入所需的參數。該方法返回執行SQL語句所影響的行數
  • int update(String statement);
    更新方法。參數statement是在配置文件中定義的< update>元素的id。該方法返回執行SQL語句所影響的行數
  • int update(String statement, Object parameter);
    更新方法。參數statement是在配置文件中定義的< update>元素的id,parameter是更新所需的參數。該方法返回執行SQL語句所影響的行數
  • int delete(String statement);
    刪除方法。參數statement是在配置文件中定義的< delete>元素的id。該方法返回執行SQL語句所影響的行數
  • int delete(String statement, Object parameter );
    刪除方法。參數statement是在配置文件中定義的< delete>元素的id,parameter是刪除所需的參數。該方法返回執行SQL語句所影響的行數
  • void commit();
    提交事務的方法。
  • void rollback();
    回滾事務的方法。
  • void close();
    關閉SqlSession對象。
  • < T>T getMapper(Class type)
    返回 Mapper接口的代理對象,該對象關聯了Sqlsession對象,開發人員可以使用該對象直接調用方法操作數據庫。參數type是Mapper的接口類型。
  • Connection getConnection();
    獲取JDBC數據庫連接對象的方法。

爲了簡化開發,可以將構建SqlSessionFactory對象、創建SqlSession對象等重複性代碼封裝到一個工具類中,然後通過工具類來創建SqlSession。

7.2 MyBatis配置文件元素

使用MyBatis框架進行開發,需要創建MyBatis的核心配置文件,該配置文件包含重要的元素,熟悉配置文件中各個元素的功能十分重要。

在MyBatis框架的核心配置文件中,< configuration>元素是配置文件的根元素,其他元素都要在< contiguration>元素內配置。
MyBatis配置文件中的主要元素如圖

在這裏插入圖片描述

< contiguration>元素的子元素必須按照由上到下的順序配置。

7.2.1 < properties>元素

< properties>是一個配置屬性的元素,通過外部配置來動態替換內部定義的屬性。

示例1

配置數據庫的連接屬性
步驟01

在項目的src目錄下創建一個名稱爲db.properties的配置文件,代碼

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql: //localhost: 3306/db_mybatis
jdbc.username=root
jdbc.password=root
步驟02

在MyBatis配置文件mybatis-config.xml中配置屬性,具體如下。
< properties resource=“db.properties”/>

步驟03

修改配置文件中數據庫連接的信息,具體如下。
在這裏插入圖片描述
完成上述配置,dataSource中連接數據庫的4個屬性(driver、url、username和password)值將會由db.properties文件中對應的值來動態替換。另外,還可以通過配置< properties>元素的子元素< property>以及通過方法參數傳遞的方式來獲取屬性值。
由於使用properties配置文件來配置屬性值可以方便地在多個配置文件中使用這些屬性值,並且方便維護和修改,因此在實際開發中常用。

7.2.2 < settings>元素

< settings>元素主要用於改變MyBatis運行時的行爲,例如開啓二級緩存、開啓延遲加載等。元素中的常見配置及其描述如圖
在這裏插入圖片描述
圖中介紹了< settings>元素中的常見配置,這些配置在配置文件中的使用方式
在這裏插入圖片描述
上面所介紹的配置內容通常在需要時只配置少數幾項。

7.2.3 < typeAliases>元素

< typeAliases>元素用於爲配置文件中的Java類型設置一個簡短的名字,即設置別名別名的設置與XML配置相關,其使用的意義在於減少全限定類名的冗餘
使用< typeAliases>元素配置別名的方法如下:
在這裏插入圖片描述
在上述示例中,< typeAliases>元素的子元素< typeAlias>中的type屬性用於指定需要被定義別名的類的全限定名;alias屬性的屬性值“user”就是自定義的別名,可以代替“com.ssm.po.User”使用在MyBatis文件的任何位置。如果省略alias屬性,MyBatis會默認將類名首字母小寫後的名稱作爲別名。
當POJO類過多時,還可以通過自動掃描包的形式自定義別名,具體示例如下。
在這裏插入圖片描述
在上述示例中,< typeAliases>元素的子元素< package>中的name屬性用於指定要被定義別名的包,MyBatis會將所有com.ssm.po包中的POJO類以首字母小寫的非限定類名作爲它的別名。

需要注意的是上述方式的別名只適用於沒有使用註解的情況,如果使用了註解,那麼別名就是其註解的名字
在這裏插入圖片描述
除了可以使用元素自定義別名外,MyBatis框架還默認爲許多常見的Java類型(如數值、字符串、日期和集合等)提供相應的類型別名,如圖
 MyBatis默認別名
在這裏插入圖片描述
所列舉的別名可以在MyBatis中直接使用,但由於別名不區分大小寫因此在使用時要注意重複定義的覆蓋問題。

7.2.4 < typeHandle>元素

MyBatis在預處理語句(Prepared Statement)中設置一個參數或者從結果集(Resultset)中取出一個值時,都會用其框架內部註冊了的typeHandler(類型處理器)進行相關處理。typeHandler的作用就是將預處理語句中傳入的參數從javaType(Java類型)轉換爲jdbcType(JDBC類型),或者從數據庫取出結果時將jdbcType轉換爲javaType。
爲了方便轉換,MyBatis框架提供了一些默認的類型處理器
常用的類型處理器
 在這裏插入圖片描述
當MyBatis框架所提供的這些類型處理器不能夠滿足需求時,還可以通過自定義的方式對類型處理器進行擴展。自定義類型處理器可以通過實現TypeHandler接口或者繼承BaseTypeHandle類來定義。元素就是用於在配置文件中註冊自定義的類型處理器的。它的使用方式有兩種,具體如下。

  • 註冊一個類的類型處理器
    上述代碼中,子元素< typeHandler>的handler屬性用於指定在程序中自定義的類型處理器類。
    在這裏插入圖片描述
  • 註冊一個包中所有的類型處理器
    在上述代碼中,子元素< package>的name屬性用於指定類型處理器所在的包名,使用這種方式後,系統會在啓動時自動掃描com.ssm.type包下所有的文件,並把它們作爲類型處理器。
    在這裏插入圖片描述
    typeHandler的作用就是將預處理語句中傳入的參數從javaType(Java類型)轉換爲jdbcType(JDBC類型),或者從數據庫取出結果時將jdbcType轉換爲javaType

7.2.5 < objectFactory>元素

MyBatis框架每次創建結果對象的新實例時,都會使用一個對象工廠(ObjectFactory)的實例來完成。MyBatis中默認的ObjectFactory的作用就是實例化目標類,既可以通過默認構造方法實例化,也可以在參數映射存在的時候通過參數構造方法來實例化。
在通常情況下,我們使用默認的ObjectFactory即可。MyBatis中默認的ObjectFactory是由org.apache.ibatis.reflection.factory.DefaultObjectFactory來提供服務的,大部分場景下都不用配置和修改。如果想覆蓋ObjectFactory的默認行爲,那麼可以通過自定義ObjectFactory實現。

7.2.6 < plugins>元素

該元素的作用就是配置用戶開發所需的插件

7.2.7 < environments>元素

< environments>元素用於在配置文件中對環境進行配置。MyBatis的環境配置實際上就是數據源的配置,可以通過< environments>元素配置多種數據源,即配置多種數據庫。
示例1
使用< environments>元素進行環境配置的示例如下。
在這裏插入圖片描述

在上述示例代碼中,< environments>元素是環境配置的根元素,它包含一個default屬性,該屬性用於指定默認的環境ID。< environment>是< environments>元素的子元素,它可以被定義多個,其id屬性用於表示所定義環境的ID值。在< environment>元素內,包含事務管理和數據源的配置信息其中< transactionManager>元素用於配置事務管理,它的type屬性用於指定事務管理的方式,即使用哪種事務管理器;< dataSource>元素用於配置數據源,它的type屬性用於指定使用哪種數據源。
在MyBatis中,可以配置兩種類型的事務管理器

  1. JDBC:此配置直接使用JDBC的提交和回滾設置,依賴從數據源得到的連接來管理事務的作用域。
  2. MANAGED:此配置從來不提交或回滾一個連接,而是讓容器來管理事務的整個生命週期。在默認情況下,它會關閉連接,但一些容器並不希望這樣,爲此可以將closeConnection屬性設置爲false來阻止它默認的關閉行爲。

注意
如果項目中使用Spring+MyBatis,就沒有必要在MyBatis中配置事務管理器,因爲實際開發中會使用Spring自帶的管理器來實現事務管理。
對於數據源的配置,MyBatis框架提供了三種數據源類型。

  • UNPOOLED:配置此數據源類型後,在每次被請求時會打開和關閉連接。它對沒有性能要求的簡單應用程序是一個很好的選擇。
  • POOLED:此數據源利用“池”的概念將JDBC連接對象組織起來,避免在創建新的連接實例時需要初始化和認證的時間。這種方式使得併發Web應用可以快速地響應請求,是當前流行的處理方式。
  • JNDI:此數據源可以在EJB或應用服務器等容器中使用。容器可以集中或在外部配置數據源,然後放置一個JNDI上下文的引用。

7.2.8 < mappers>元素

在配置文件中,< mappers>元素用於指定MyBatis映射文件的位置,一般可以使用以下4種方法引入映射器文件

  • 使用類路徑引入
    < mappers>
    < mapper resource=“com/ssm/mapper/UserMapper.xmI”/>
    </ mappers>
  • 使用本地文件路徑引入
    < mappers>
    <mapper url=file: ///D:/com/ssm/mapper/UserMapper.xml"/>
    </ mappers>
  • 使用接口類引入
    < mappers>
    < mapper class=“com.ssm.mapper.UserMapper”/>
    </ mappers>
  • 使用包名引入
    < mappers>
    < package name="“com.ssm.mapper”/>
    </ mappers>

7.3 映射文件

映射文件是MyBatis框架中十分重要的文件。在映射文件中,< mapper>元素是映射文件的根元素,其他元素都是它的子元素。映射文件中的主要元素如下所示。
在這裏插入圖片描述

7.3.1 < select>元素

< select>元素用於映射查詢語句,從數據庫中讀取數據,並組裝數據給業務開發人員。示例如下:

< select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
select * from t_user where id=#{id}
</ select>

上述語句中的唯一標識爲findUserById,它接收一個Integer類型的參數,並返回一個User類型的對象。
在< select>元素中,除了上述示例代碼中的幾個屬性外,還有其他可以配置的屬性,如圖
在這裏插入圖片描述

7.3.2 < insert>元素

< insert>元素用於映射插入語句,在執行完元素中定義的SQL語句後,會返回一個表示插入記錄數的整數。< insert>元素的配置示例如下:

< insert id="addUser" parameterType="com.ssm.po.User" flushCache="true"
    statementType="PREPARED"  keyProperty="id" keyColumn=""
    useGeneratedKeys="" timeout="20">
       insert into    t_user(username,jobs,phone)values(#{username},#{jobs},#{phone})
</ insert>

從上述示例代碼中可以看出,< insert>元素的屬性與< select>元素的屬性大部分相同,但還包含3個特有屬性(僅對insert和update有用),如圖< insert>元素的常用屬性
在這裏插入圖片描述
執行插入操作後,很多時候我們會需要返回插入成功的數據生成的主鍵值,此時就可以通過上面所講解的3個屬性來實現。

示例1

如果使用的數據庫支持主鍵自動增長(如MySQL)那麼可以通過keyProperty屬性指定PO類的某個屬性(新增id屬性變量)接收主鍵返回值(通常會設置到id屬性上),然後將==useGeneratedKeys的屬性值設置爲true。==使用上述配置執行插入後,會返回插入成功的行數以及插入行的主鍵值。可以通過如下代碼測試。

在這裏插入圖片描述
如果使用的數據庫不支持主鍵自動增長(如Oracle),或者支持增長的數據庫取消了主鍵自增的規則,就可以使用MyBatis提供的另一種方式來自定義生成主鍵,具體配置示例如下。
在這裏插入圖片描述
在執行上述示例代碼時,< selectKey>元素會首先運行,它會通過自定義的語句來設置數據表中的主鍵(如果t_user表中沒有記錄,就將id設置爲1,否則將id的最大值加1作爲新的主鍵),然後調用插入語句。
< selectKey>元素在使用時可以設置以下幾種屬性。

< selectKey
   keyProperty="id"
   resultType="Integer"
   order="BEFORE"
   statement="PREPARED">

在上述< selectKey>元素的幾個屬性中,keyProperty、resultType和statement的作用與前面講解的相同。order屬性可以被設置爲BEFORE或AFTER。如果設置爲BEFORE,那麼它會先執行< selectKey>元素中的配置來設置主鍵,再執行插入語句如果設置爲AFTER,那麼它會先執行插入語句,再執行< selectKey>元素中的配置內容。

7.3.3 < update>元素和< delete>元素

< update>元素和< delete>元素的使用比較簡單,它們的屬性配置也基本相同,其常用屬性如下

< update
    id="updateUser"
    parameterType="com.ssm.po.User"
    flushCache="true"
    statementType="PREPARED"
    timeout="20">
< delete
    id="deleteUser"
    parameterType="com.ssm.po.User"
    flushCache="true"
    statementType="PREPARED"
    timeout="20">

從上述配置代碼中可以看出,< update>元素和< delete>元素的屬性基本與< select>元素中的屬性一致。與< insert>元素一樣,< update>元素和< delete>元素在執行完之後,也會返回一個表示影響記錄條數的整數,其使用示例如下。
在這裏插入圖片描述

7.3.4 < sql>元素

在一個映射文件中,通常需要定義多條SQL語句,這些SQL語句的組成可能有一部分是相同的(如多條select語句中都查詢相同的id、username、jobs字段),如果每一個SQL語句都重寫一遍相同的部分,勢必會增加代碼量,導致映射文件過於臃腫。那麼有沒有什麼辦法將這些SQL語句中相同的組成部分抽取出來,然後在需要的地方引用呢?答案是肯定的,我們可以在映射文件中使用MyBatis提供的< sql>元素來解決上述問題
< sql>元素的作用是定義可重用的SQL代碼片段然後在其他語句中引用這一代碼片段。
例如,定義一個包含id、username、jobs和phone字段的代碼片段:

< sql id="user Columns">id,username,jobs, phone</ sql>
這一代碼片段可以包含在其他語句中使用,具體如下:
< select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
    select < include refid="user Columns">
    from t_user
    where id=#{id}
</ select>

在上述代碼中,使用< include>元素的refid屬性引用了自定義的代碼片段,refid屬性值爲自定義代碼片段的id。

在實際開發中,可以更加靈活地定義SQL片段。

7.3.5 < resultMap>元素

< resultMap>元素表示結果映射集,主要作用是定義映射規則、級聯更新以及定義類型轉化器等。
< resultMap>元素中包含一些子元素,元素結構如下所圖
在這裏插入圖片描述
< resultMap>元素的type屬性表示需要映射的POJOid屬性是這個resultMap的唯一標識它的子元素< constructor>用於配置構造方法(當一個POJO中未定義無參的構造方法時,就可以使用< constructor>元素進行配置)。子元素< id>用於表示哪個列是主鍵而< result>用於表示POJO和數據表中普通列的映射關係。< association>和< collection>用於處理多表時的關聯關係而< discriminator>元素主要用於處理一個單獨的數據庫查詢返回很多不同數據類型結果集的情況。
在默認情況下,MyBatis程序在運行時會自動地將查詢到的數據與需要返回的對象的屬性進行匹配賦值(需要表中的列名與對象的屬性名稱完全一致)。然而實際開發時,數據表中的列和需要返回的對象的屬性可能不會完全一致,這種情況下MyBatis是不會自動賦值的。此時,就可以使用< resultMap>元素進行處理,示例代碼UserMapper.xml如圖
在這裏插入圖片描述
在上述代碼中,< resultMap>的子元素< id>和< result>的property屬性表示User類的屬性名,column屬性表示數據表t_user的列名。< select>元素的resultMap屬性表示引用上面定義的resultMap。接下來可以在配置文件mybatis-config.xml中引入UserMapper.xml。
除此之外,還可以通過< resultMap>元素中的< association>和< collection>處理多表時的關聯關係。

多表時的關聯關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章