框架學習--mybatis--01
阿新 • • 發佈:2018-11-28
一、簡介
1、概念
- mybatis 是一個半自動輕量級的一個 orm 框架
2、作用
- 將 java 與 sql 分離,解決了 jdbc 的硬編碼問題,方便 sql 的修改;
- sql 由開發人員控制,更加方便 sql 的調優;
3、快速開始
(1)原始方法
- 建一個全域性配置檔案,裡面是資料來源等執行環境的資訊;
- 建立一個sql 的對映檔案,並將這個檔案註冊到全域性的配置中;
- 根據全域性的配置檔案獲得一個 sqlsessionfactory;
- 通過 factory 獲得 sqlsession(非執行緒安全),一個sqlsession 就是和資料庫的一次會話,用完需要關閉;
- sqlsession通過 sql 的唯一識別符號呼叫方法執行;
- 注意資料庫的欄位名和bean的欄位名要相同才能順利對映;
(2)介面式程式設計
- 定義一個介面,介面中定義操作資料庫的方法;
- 將介面和sql的對映檔案繫結:xml的namespace是介面全限定名,sql的id是介面中的方法名;
- 在 java 程式中通過session獲得藉口的實現類(代理物件)物件;
- 通過物件呼叫方法執行相應的sql;
二、配置檔案
1、全域性配置檔案
(1)xml 中引入 dtd 約束
(2)properties標籤:url引入網路或者磁碟的資源;resource引入 classpath 下的資源;
(3)settings標籤:設定一些mybatis執行時的重要引數
(4)typeAliases標籤:就是給 java 類起別名用的
- 別名不分大小寫;
- 可以單獨起也可以批量起;
- 預設別名就是類名;
- 也可以使用註解來起別名(@alias);
- java 中的基本資料型別和一些常用的類已經取好了別名(基本型別就是前面加 _ ;引用型別就是原類名)
(5)typeHandlers標籤:
- 就是處理 java 型別和資料庫型別的轉換的;
- 常用的型別 mybatis 都給預設處理了,不用我們自己去做;
- 當然是支援自定義的了;
(6)plugins標籤:
(7)environments標籤:
- 用來配置環境的,可以配置多個環境,在default屬性裡可以指定預設的環境;
- 每個環境都應包含:transactionManager 和 dataSource
(8)databaseIdProvider標籤:
- 為mybatis提供多資料庫廠商的支援;
- 廠商標識在資料庫的驅動裡;
- 標籤內通過property標籤指定資料庫的別名;
- 在相應的sql語句的標籤上用databaseId引入資料庫的別名;
- 注意:主配置檔案裡的標籤的書寫的順序是有要求的,databaseIdProvider應該寫在envir 和 mapper 之間;
(9)mappers標籤:
- 作用就是註冊 sql 對映;
- 裡面具體的 mapper 的屬性有三種寫法:
- resource:classpath 路徑下;
- url:網路資源或者磁碟資源;
- class:指定對應的對映的介面(條件是必須同包同名);
- 批量的註冊直接用package 標籤(條件是必須同包同名);
<?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="conf/dbconfig.properties"></properties>
<!-- <settings>
<setting name="" value="" />
</settings>
<typeAliases>
單獨起別名
<typeAlias type="" alias="" />
批量起別名
<package name="" />
</typeAliases>
<typeHandlers>
<typeHandler handler="" />
</typeHandlers>
<plugins>
<plugin interceptor=""></plugin>
</plugins> -->
<environments default="development">
<!-- <environment id="test">
<transactionManager type=""></transactionManager>
<dataSource type=""></dataSource>
</environment> -->
<environment id="development">
<transactionManager type="JDBC" />
<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>
</environment>
</environments>
<databaseIdProvider type="DB_VENDOR">
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql" />
</databaseIdProvider>
<mappers>
<mapper resource="conf/TuserMapper.xml" />
</mappers>
</configuration>
2、sql對映檔案概述
(1)增刪改測試
- int、long 和 boolean 型別的返回值我們可以直接用;
- 增刪改後一定要 commit;
(2)資料插入獲得自增主鍵
- mysql:支援自增主鍵
- useGeneratedKeys 和 keyProperty 屬性配合使用即可獲取到自增主鍵的值
- oracle:不支援自增主鍵,靠序列來完成
- 在要執行的sql前用 selectKey 標籤來實現
- 相關的三個屬性分別是 keyProperty、resultType 和 order;
- 有兩種寫法分別是 order 的屬性值為 before 和 after;通常使用 before
3、對映檔案的引數處理
(1)單個引數
- 單個引數可以在 #{}中隨意寫;
(2)多個引數
- 多個引數預設在其中寫 param1 和 param2 等;也可以用註解@param 指定名稱;多個引數本質是封裝在一個map中;
- 業務相關的資料直接封裝在 pojo 中;
- 關聯性不高且使用的頻率不高的話的可以放在一個map裡;在map 裡可以隨意指定鍵名;
- 同時多個引數如果使用的頻率很高的話還可以封裝為一個 TO 物件;
- 集合和陣列的特殊處理:引數可以寫 collection、list 和 array;
(3)引數處理原始碼分析
- 引數封裝成map 的過程:總結起來就是引數多的時候就封裝成 map 集合,有@param註解的引數的鍵值就是指定的值,否則就是預設的;
(4)關於 #{} 和 ${}兩種取值的方法:
- #{}是以預編譯的形式來取引數的值的,可以防注入;而${}是直接拼接的;
- 大多數的情況採用 #{},但在原生的 jdbc 不支援佔位符的地方可以使用 ${},比如order by ${age};
- #{}進行引數設定的時候可以指定一些規則,比如:#{email,jdbcType.null},mybatis自動將 null值對映為jdbc的other型別,這個型別oracle不支援會報錯;
4、對映檔案的select 元素
(1)resultType
- resultType的作用就是指定結果集的封裝的規則;
- 結果集封裝為 list型別直接寫 list裡資料型別即可;
- 封裝為 map 單條記錄直接寫 map 的別名;多條記錄寫pojo 的型別(map的值是pojo),map的鍵值在相應的方法上面用註解@mapKey來指定pojo中的屬性;
(2)resultMap(關聯查詢 | 分步查詢 | 延遲載入 | 集合屬性封裝)
- 配置列名屬性名對映
- resultMap也是用來定義結果集的封裝規則的(表的列名和pojo 的屬性名的對應關係);
- resultMap標籤兩個屬性 type是pojo型別,id是唯一標識;表中的主鍵列用id 封裝,普通列用 result 封裝;
- 用resultMap實現關聯查詢(前提pojo包裝pojo):
- 第一種方法是直接寫 property 的時候用屬性點屬性的方式就可以了;
- 第二種方法是在 resultMap 裡用 association 標籤實現關聯查詢,兩個屬性 property 和 javatype;
- association 標籤用法
- 可以用來實現關聯查詢;
- 用 association 實現分步查詢:select屬性指定 mapper方法,column 屬性指定傳入方法的引數;
- 關聯查詢時,如果想按需載入,就可以在全域性 settings 裡設定lazyloading 為true,實現get相應的pojo 的時候再發出sql向資料庫查詢;
- collection 標籤用法
- 用 collection 標籤實現集合型別屬性的封裝,屬性 property為相應的集合型別的屬性名,而ofType 是集合的泛型的型別;
- collection 實現分步查詢和延遲載入:
- 實際上還是 select 將兩個介面方法、兩個sql關聯,再用 column 屬性傳入引數;
- 多個引數的傳遞可以用map,就是這樣的形式:{key1=col1,key2=col2};
- fetchType屬性可以設定延遲載入;
- discriminator鑑別器根據列的值做出不同的處理:還是寫在 resultMap裡,內含case標籤指定各種值的處理方法(封裝方法),其中指定封裝資料的型別時,type 和 map 必須二選一;這個東西用的少;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wc.mapper.TuserMapper">
<!-- <resultMap type="tuser" id="map1">
<id property="uid" column="tid"/>
<result property="uname" column="uname"/>
<result property="age" column="age"/>
關聯查詢
<association property="dept" javaType="department">
<id property="did" column="did"/>
<result property="dname" column="dname"/>
</association>
</resultMap> -->
<resultMap type="tuser" id="map2">
<id property="uid" column="tid"/>
<result property="uname" column="uname"/>
<result property="age" column="age"/>
<result property="did" column="did"/>
<!-- select step by step -->
<association property="dept"
select="com.wc.mapper.DepartmentMapper.getDeptById" column="did">
<id property="did" column="did"/>
<result property="dname" column="dname"/>
</association>
</resultMap>
<select id="getById" resultMap="map2">
select * from tuser where tid = #{id}
</select>
</mapper>
三、動態sql
1、if 判斷
(1)OGNL(物件圖導航語言)
- 有點類似於 jsp 中的 el 表示式,可以用來取引數的值並作一些基本的運算;
(2)if 判斷
- if 判斷拼接 where 條件存在的問題:就是可能會出現where後面直接是一個 and的情況
- 第一種方法:就是where 後面緊跟一個 1=1;
- 第二種方法:使用where 標籤,使用時注意條件的後就不要寫 and 了;
- 第三種方法:使用trim 標籤,可以通過屬性設定字首字尾和前後綴的覆蓋問題,where 前後多出的 and(or)都能解決;
- set 標籤用來封裝修改條件,作用就是去除 set 的時候多餘的逗號,當然用 trim 標籤也可以實現,與if結合使用可以實現動態更新;
2、choose 分支選擇
(1)語法:choose----when----when----otherwise-----choose
(2)理解:類似於 java 中帶break 的 switch語句,只匹配一個條件;
3、foreach 遍歷
(1)遍歷集合拼接 where 條件(如:in 集合)
- 幾個常用的屬性 collection、item、separator、open、close、index(map的時候就是map的key);
(2)實現資料的批量插入
- mysql 第一種:在 values 後面用 foreach 遍歷拼接 sql;
- mysql 第二種:直接整個插入語句來迴圈,需要在資料庫的 url 後面傳參開啟多條語句執行的支援;
- oracle 第一種:用 plsql ,在begin 和 end 中來遍歷;
- oracle 第二種:迴圈用 select 語句將集合中的值從偽表中查出,再用查出的結果進行插入;
4、其他
(1)內建引數:
- 除了我們傳入的引數,還有內建的引數,這裡的內建引數可以取到也可以判斷
- _parameter:封裝所有的引數,傳入的引數一個就是這個引數本身,傳入多個引數就是一個 map;
- databaseId:全域性配置檔案裡面配置了 databaseproviderid這裡可以取到;
- _parameter 和 if結合可以用來進行 where條件的拼接;
- databaseId 和 if 結合使用可以用來在一個 select 元素裡寫兩個資料庫的 sql;
(2)bind 標籤:作用就是將傳入的引數賦值給一個變數方便以後的呼叫,連個屬性name 和 value;
(3)sql 片段:
- 用 sql 標籤抽取可以重用的sql 片段方便以後在其他的sql 裡用include標籤用id引用,如查詢欄位的重用;
- include 支援自定義 property ,在sql標籤的內部就能用${}取來使用;