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為什麼要使用MyBatis?
• MyBatis 是一個半自動化的持久化層框架。 • JDBC去哪裡找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中引入XML的dtd約束檔案,方便編寫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.BaseTypeHandler • 2 )、指定其對映某個 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 的提交和回滾設定,依賴於從資料來源得到的連線來管理事務 範圍。 JdbcTransactionFactory – MANAGED :不提交或回滾一個連線、讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 ManagedTransactionFactory – 自定義 :實現 TransactionFactory 介面, type= 全類名 / 別名dataSource
• type : UNPOOLED | POOLED | JNDI | 自定義 – UNPOOLED :不使用連線 池, UnpooledDataSourceFactory – POOLED :使用連線池, PooledDataSourceFactory – JNDI : 在 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 =null – 2 、如果配置了 databaseIdProvider 標籤,使用標籤配置的 name 去匹配資料庫資訊,匹配上設定 databaseId = 配置指定的值,否則依舊為 null – 3 、如果 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 – 對映查詢語句insert、update、delete元素
主鍵生成方式
• 若資料庫 支援自動生成主鍵 的欄位(比如 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 時,我們直接傳遞 POJO • Map – 我們也可以封裝多個引數為 map ,直接傳遞引數處理
引數也可以指定一個特殊的資料型別:
javaType 通常可以從引數物件中來去確定
如果 null 被當作值來傳遞,對於所有可能為空的列,jdbcType 需要被設定
對於數值型別,還可以設定小數點後保留的位數:
mode 屬性允許指定 IN,OUT 或 INOUT 引數。如果引數為 OUT 或 INOUT,引數物件屬性的真實值將會被改變,就像在獲取輸出引數時所期望的那樣。
• 引數位置支援的屬性 – javaType 、 jdbcType 、 mode 、 numericScale 、 resultMap、typeHandler、jdbcTypeName、expression
可能為空的列名指定 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.jar – cglib-2.2.2.jar