1. 程式人生 > 實用技巧 >Mybatis_整合筆記01

Mybatis_整合筆記01

MyBatis簡介

MyBatis 是支援定製化 SQL 、儲存過程以及高階對映的優秀的持久層框架。 • • MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。 • • MyBatis 可以使用簡單的 XML 或註解用於配置和原始對映,將介面和 Java POJO Plain Old Java Objects ,普通的 Java 物件)對映成資料庫中的記錄 .

MyBatis歷史

A pache 的一個開源專案 iBatis , 2010 6 月這個專案 A pache S oftware F
oundation 遷移到 Google C ode ,隨著開發團隊轉投 Google Code 旗下 iBatis3.x 正式更名為 MyBatis ,程式碼於 2013 11 月遷移到 Github (下載地址見後)。 • • iBatis 詞來源於“ internet ”和“ abatis ”的組合,是一個基於 Java 的持久層框架 iBatis 提供 的持久層框架包括 SQL Maps Data Access Objects DAO

為什麼要使用MyBatis

MyBatis 是一個半自動化的持久化層框架。JDBC
SQL 夾在 Java 程式碼塊裡,耦合度高導致硬編碼 內傷維護不易且實際開發需求中 sql 是有變化,頻繁修改的情況多 Hibernate JPA長難複雜 SQL ,對於 Hibernate 而言處理也不容易內部自動生產的 SQL ,不容易做特殊優化。基於全對映的全自動框架 ,大量欄位的 POJO 進行部分對映時比較困難。 導致資料庫效能下降 開發人員而言,核心 sql 還是需要自己 優化sql java 編碼分開,功能邊界清晰,一個專注業務、一個專注資料

去哪裡找MyBatis?https://github.com/mybatis/mybatis-3/

MyBatis操作資料庫

1 建立 MyBatis 全域性配置檔案MyBatis 的全域性配置檔案包含了影響 MyBatis 行為甚深的設定( settings )和屬性( properties )資訊、如資料庫連線池資訊等。指導著 MyBatis 進行工作。我們可以參照官方檔案的配置示例

2 建立 SQL 對映檔案對映檔案的作用就相當於是定義 Dao 介面的實現類如何工作。這也是我們使用 MyBatis 時編寫的最多的檔案。

測試

SqlSessionFactoryBuilder 建立 SqlSessionFactory

使用SqlSessionFactory獲取sqlSession物件。一SqlSession物件代表和資料庫的一次會話

使用SqlSession根據方法id進行操作

使用SqlSession獲取對映器進行操作

SqlSession

SqlSession 的例項 不是執行緒安全 的,因此是不能被共享的 • • SqlSession 每次 使用完成後需要正確關閉 ,這個關閉操作是必須的 • • SqlSession 可以直接呼叫方法的 id 進行資料庫操作,但是我們一般還是推薦使用 SqlSession 獲取到 Dao 介面的代理 類,執行代理物件的 方法,可以更安全的進行型別檢查操作

三、MyBatis-全域性配置檔案

MyBatis 的配置檔案包含了影響 MyBatis 行為甚深的設定( settings )和 屬性( properties )資訊。文件的頂層結構如下 • • configuration 配置 properties 屬性settings 設定typeAliases 型別命名typeHandlers 型別處理器objectFactory 物件工廠plugins 外掛environments 環境environment 環境變數 transactionManager 事務管理器dataSource 資料來源databaseIdProvider 資料庫廠商標識mappers 對映器

Eclipse中引入XMLdtd約束檔案,方便編寫XML的時候有提示

properties屬性

如果 屬性在不只一個地方進行了配置,那麼 MyBatis 將按照下面的順序來載入 properties 元素體內指定的屬性首先被讀取。 然後根據 properties 元素中的 resource 屬性讀取類路徑下屬性檔案或根據 url 屬性指定的路徑讀取屬性檔案,並覆蓋已讀取的同名屬性 最後讀取作為方法引數傳遞的屬性,並覆蓋已讀取的同名屬性。

settings設定

這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為

typeAliases別名處理器

類型別名是為 Java 型別設定一個短的名字,可以方便我們引用某個類。

  • 類很多的情況下,可以批量設定別名這個包下的每一個類建立一個預設的別名,就是簡單類名小寫

也可以使用@Alias註解為其指定一個別名

值得注意的是,MyBatis已經為許多常見的 Java 型別內建了相應的類型別名。它們都是大小寫不敏感,我們在起別名的時候千萬不要佔用已有的別名。

別名

對映的型別

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

別名

對映的型別

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

typeHandlers型別處理器

無論是 MyBatis 在預處理語句( PreparedStatement )中設定一個引數時,還是從結果集中取出一個值時, 都會 用型別處理器將獲取的值以合適的方式轉換成 Java 型別

型別處理器

Java 型別

JDBC 型別

BooleanTypeHandler

java.lang.Boolean, boolean

資料庫相容的 BOOLEAN

ByteTypeHandler

java.lang.Byte, byte

資料庫相容的 NUMERIC BYTE

ShortTypeHandler

java.lang.Short, short

資料庫相容的 NUMERIC SHORT INTEGER

IntegerTypeHandler

java.lang.Integer, int

資料庫相容的 NUMERIC INTEGER

LongTypeHandler

java.lang.Long, long

資料庫相容的 NUMERIC LONG INTEGER

FloatTypeHandler

java.lang.Float, float

資料庫相容的 NUMERIC FLOAT

DoubleTypeHandler

java.lang.Double, double

資料庫相容的 NUMERIC DOUBLE

BigDecimalTypeHandler

java.math.BigDecimal

資料庫相容的 NUMERIC DECIMAL

StringTypeHandler

java.lang.String

CHAR, VARCHAR

日期型別的處理

日期和時間的處理 JDK1.8 以前一直是個頭疼的問題。我們通常使用 JSR310 規範領導者 Stephen Colebourne 建立的 Joda -Time 來操作。 1.8 已經實現全部的 JSR310 規範了。日期時間處理上,我們可以使用 MyBatis 基於 JSR310 Date and Time API )編寫的各種日期 時間型別處理器 MyBatis3.4 以前的版本需要我們手動註冊這些處理器,以後的版本都是自動註冊的

自定義型別處理器

我們可以重寫型別處理器或建立自己的型別處理器來處理不支援的或非標準的型別 • • 步驟:1 )、實現 org.apache.ibatis.type.TypeHandler 介面 或者繼承 org.apache.ibatis.type.BaseTypeHandler2 )、指定其對映某個 JDBC 型別(可選操作)3 )、在 mybatis 全域性配置檔案中 註冊

plugins外掛

外掛是 MyBatis 提供的一個非常強大的機制,我們可以通過外掛來修改 MyBatis 的一些核心行為。 外掛通過動態代理機制 ,可以介入四大物件的任何一個方法的執行。後面會有專門的章節我們來介紹 mybatis 執行原理以及 外掛 • • Executor (update, query, flushStatements , commit, rollback, getTransaction , close, isClosed )

ParameterHandler ( getParameterObject , setParameters ) • • ResultSetHandler ( handleResultSets , handleOutputParameters ) • • StatementHandler (prepare, parameterize, batch, update, query)

environments環境

MyBatis 可以配置多種環境,比如開發、測試和生產環境需要有不同的配置 • • 每種環境使用一個 environment 標籤進行配置並指定唯一 識別符號 • • 可以通過 environments 標籤中的 default 屬性指定一個環境的識別符號來快速的切換 環境

environment-指定具體環境

id :指定當前環境的唯一標識transactionManager 、和 dataSource 都必須有

transactionManager

type JDBC | MANAGED | 自定義JDBC :使用了 JDBC 的提交和回滾設定,依賴於從資料來源得到的連線來管理事務 範圍。 JdbcTransactionFactoryMANAGED :不提交或回滾一個連線、讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 ManagedTransactionFactory自定義 :實現 TransactionFactory 介面, type= 全類名 / 別名

dataSource

type UNPOOLED | POOLED | JNDI | 自定義UNPOOLED :不使用連線 池, UnpooledDataSourceFactoryPOOLED :使用連線池, PooledDataSourceFactoryJNDI : 在 EJB 或應用伺服器這類容器中查詢指定的資料來源自定義 :實現 DataSourceFactory 介面,定義資料來源的獲取方式。 – • 實際開發中我們使用 Spring 管理資料來源 ,並進行事務控制的配置來 覆蓋上述配置

databaseIdProvider環境

MyBatis 可以根據不同的資料庫廠商執行不同的語句 Type DB_VENDOR使用 MyBatis 提供的 VendorDatabaseIdProvider 解析資料庫廠商標識。也可以實現 DatabaseIdProvider 介面來自定義 Property-name :資料庫廠商標識Property-value :為標識起一個別名,方便 SQL 語句使用 databaseId 屬性 引用 DB_VENDOR 通過 DatabaseMetaData#getDatabaseProductName () 返回的字串進行設定。由於通常情況下這個字串都非常長而且相同產品的不同版本會返回不同的值,所以最好通過設定屬性別名來使其變 • • MyBatis 匹配規則 如下:1 、如果沒有配置 databaseIdProvider 標籤,那麼 databaseId =null2 、如果配置了 databaseIdProvider 標籤,使用標籤配置的 name 去匹配資料庫資訊,匹配上設定 databaseId = 配置指定的值,否則依舊為 null3 、如果 databaseId 不為 null ,他只會找到配置 databaseId sql 語句4 MyBatis 會載入 不帶 databaseId 屬性和帶有 匹配當前資料庫databaseId 屬性 所有語句 。如果同時找到帶有 databaseId 和不帶databaseId 的相同語句 則後者會被捨棄

mapper對映

mapper逐個註冊SQL對映檔案

或者使用批量 註冊 這種方式要求 SQL 對映檔名必須和介面名相同並且在同一目錄下

MyBatis-對映檔案

對映檔案指導著 MyBatis 如何進行資料庫增刪改查,有著非常重要的 意義; • • c ache –名稱空間的 二級快取配置cache-ref – 其他名稱空間快取配置的引用。 resultMap 自定義結果集對映parameterMap – 已廢棄!老式風格的引數 對映sql 抽取 可重用語句塊。 insert – 對映插入語句 update – 對映更新語句 delete – 對映刪除語句 select – 對映查詢語句

insertupdatedelete元素

主鍵生成方式

若資料庫 支援自動生成主鍵 的欄位(比如 MySQL SQL Server ),則可以設定 useGeneratedKeys =”true” ,然後再把 keyProperty 設定到目標屬性上。

主鍵生成方式

而對於不支援自增型主鍵的資料庫(例如 Oracle ),則可以使用 selectKey 子元素: selectKey 元素將會首先執行 id 會被設定 然後插入語句會被呼叫

selectKey

引數(Parameters傳遞

單個 引數可以接受基本型別,物件型別,集合型別的值。這種情況 MyBatis 可直接使用這個引數,不需要經過任何處理 個引數任意多個引數,都會被 MyBatis 重新包裝成一個 Map 傳入。 Map key param1 param2 0 1… ,值就是引數的值 命名引數為引數使用 @Param 起一個名字, MyBatis 就會將這些引數封裝進 map 中, key 就是我們自己指定的 名字POJO當這些引數屬於我們業務 POJO 時,我們直接傳遞 POJOMap我們也可以封裝多個引數為 map ,直接傳遞

引數處理

引數也可以指定一個特殊的資料型別

javaType 通常可以從引數物件中來去確定

如果 null 被當作值來傳遞,對於所有可能為空的列,jdbcType 需要被設定

對於數值型別,還可以設定小數點後保留的位數:

mode 屬性允許指定 INOUT INOUT 引數。如果引數為 OUT INOUT,引數物件屬性的真實值將會被改變,就像在獲取輸出引數時所期望的那樣

引數位置支援的屬性javaType jdbcType mode numericScale

resultMaptypeHandlerjdbcTypeNameexpression

實際上 通常被設定的是

可能為空的列名指定 jdbcType

#{key} :獲取引數的值,預編譯到 SQL 中。安全。${key} :獲取引數的值,拼接到 SQL 中。有 SQL 注入問題。 ORDER BY ${name}

select元素

Select 元素來定義查詢操作。Id :唯一 識別符號。用來 引用這條語句,需要和介面的方法名一致parameterType :引數型別 可以 不傳, MyBatis 會根據 TypeHandler 自動 推斷resultType 返回值型別 別名或者全類名,如果返回的是 集合,定義 集合中元素的型別。不能和 resultMap 同時使用

自動對映

1 、全域性 setting 設定autoMappingBehavior 預設是 PARTIAL ,開啟自動對映的功能。唯一的要求是列名和 javaBean 屬性名 一致如果 autoMappingBehavior 設定為 null 則會取消自動 對映資料庫欄位命名規範, POJO 屬性符合駝峰命名法,如 A_COLUMN à aColumn ,我們可以 開啟自動駝峰命名規則對映功能 mapUnderscoreToCamelCase =true

2 自定義 resultMap 實現高階 結果集對映。

resultMap

constructor- 類在例項化時 , 用來注入結果到構造方法中idArg - ID 引數 ; 標記結果作為 ID 可以幫助提高整體效能arg - 注入到構造方法的一個普通結果id 一個 ID 結果 ; 標記結果作為 ID 可以幫助提高整體效能result 注入到欄位或 JavaBean 屬性的普通結果association 一個複雜的型別關聯 ; 許多結果將包成這種型別嵌入結果對映 結果對映自身的關聯 , 或者參考一個collection 複雜型別的 嵌入結果對映 結果對映自身的集 , 或者參考一個discriminator– 使用結果值來決定使用哪個結果對映case– 基於某些值的結果對映嵌入結果對映 這種情形結果也對映它本身 , 因此可以包含很多 相同 的元素 , 或者它可以參照一個外部的結果對映。

id & result

id result 對映一個單獨列的值到簡單資料型別(字串,整型,雙精度浮點數,日期等)的屬性或欄位。

association

複雜物件對映POJO 中的屬性可能會是一個物件我們可以使用聯合查詢,並以級聯屬性的方式封裝物件。 使用 association 標籤定義物件的封裝規則

association-巢狀結果集

association-分段查詢

select:呼叫目標的方法查詢當前屬性的值

column:將指定列的值傳入目標方法

association-分段查詢&延遲載入

開啟延遲載入和屬性按需載入

舊版本的 MyBatis 需要額外的支援包asm-3.3.1.jarcglib-2.2.2.jar

Collection-集合型別&巢狀結果集

Collection-分步查詢&延遲載入

擴充套件-多列值封裝map傳遞

分步查詢 的時候通過 column 指定,將對應的列的資料傳遞過去,我們有時需要傳遞多列資料 使用 {key1=column1,key2=column2…} 形式 association 或者 collection 標籤的 fetchType =eager/lazy 可以覆蓋全域性的延遲載入策略,指定 立即載入( eager 或者 延遲載入( lazy