一.MyBatis介紹
1.簡介
MyBatis 是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis 可以使用簡單的XML或注解用於配置和原始映射,將接口和Java的POJO(n Plain d Old a Java Objects ,普通的 a Java 對象)映射成數據庫中的記錄。
mybatis不是一個完全的orm框架,Mybatis需要程序員自己寫 sql,但是也存在映射(輸入參數映射,輸出結果映射), 學習門檻 s mybatis 比hibernate低;同時靈活性高,特別適用於業務模型易變的項目,使用范圍廣。
簡單概括:更加簡化jdbc代碼,簡化持久層,sql 語句從代碼中分離,利用反射,將表中數據與java bean屬性一一映射即ORM(Object Relational Mapping 對象關系映射).
二、MyBatis 功能架構圖
1.架構圖
2.架構圖解析
mybatis 的功能架構分為三層:
API 接口層:提供給外部使用的接口API,開發人員通過這些本地 API 來操縱數據庫。接口層接收到調用請求就會調用數據處理層來完成具體的數據處理。
數據處理層:負責具體的 SQL 查找、SQL 解析、SQL 執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操作。
基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的數據處理層提供最基礎的支撐。
三、MyBatis 框架體系結構
1、Configuration-mybatis 配置
1)、與 spring 一樣,可以通過配置文件或注解的形式進行配置;
2)、 SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis 的運行環境等信息;
3)、mapper 文件即sql映射文件,文件中配置了操作數據庫的sql 語句。 此文件需要在SqlMapConfig.xml 中加載。
4)、有了配置文件后,通過mybatis環境等配置信息構造 SqlSessionFactory即會話工廠
5)、由會話工廠創建sqlSession 即會話,操作數據庫需要通過 sqlSession 進行
6)、sqlSession 使用 Executor(數據庫操作執行器口)操作數據庫,同Executor 具體實現類實現指定 dao 層數據訪問操作
四、Mybatis 環境搭建
1.新建maven項目
與spring建立項目一致
2.配置依賴文件pom.xml
2.Resources資源包下的文件配置
(1)添加log4j日志文件.
在 src/main/resources 資源包下添加 log4j 日志輸出properties 文件,便於查看日志輸出信息
(2) 添加數據庫連接信息文件
(3) 添加mybatis.xml文件
(4) 映射文件添加
在main-àjavaà包下新建mapper映射文件UserMapper.xml
該文件主要用來寫SQL語句的,
注意:該文件必須有一個借口與之對應,並且必須和該文件寫在同一個包下
3.代碼編寫
(1) UserMapper.xml文件中書寫SQL語句.
(2)UserMapper接口寫方法
方法名與xml文件中的id屬性名保持一致
(4).Dao層實現接口重寫方法
(5).測試類
4. typeAliases別名
若有注解,則別名為其注解值。注解名 @Alias(value=“user”)
別名à映射的類型
_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;dateàDate;decimalàBigDecimal
5.配置環境
盡管可以配置多個環境,每個 SqlSessionFactory 實例只能選擇其一。
五. mappers 映射器
1. sqlmapper 配置文件路徑
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
2.絕對路徑形式
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
3.接口列表配置形式注解sql
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
4.映射包下所有接口
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
六、Mapper Xml映射文件
1. Select 元素標簽使用
輸入參數分類
基本類型,字符串,java bean,map,數組(刪除操作時體現),List(添加時體現)等每種情況定義如下
1), <!-- 輸入參數為基本數據類型 -->
<select id="queryUserById" parameterType="int" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
2) <!-- 每條結果類型為 實體 最終結果為多條記錄 list 結果 -->
<select id="queryUserByName" parameterType="string" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user
where user_name like concat("%",#{userName},"%")
</select>
3) <!-- 輸入參數為 map 類型 -->
<select id="queryUserByMap" parameterType="map" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
4) <!-- 輸入參數為 java bean 類型 -->
<select id="queryUserByUser" parameterType="user" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
2.Insert 元素標簽使用(四種添加配置篇幅限制)
1)添加記錄不返回主鍵配置
<insert id="addUserNoKey" parameterType="User">
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
2)添加記錄返回主鍵 1(屬性配置)
<insert id="addUserHasKey" parameterType="user">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID() as id
</selectKey>
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
Oracle 情況
<selectKey resultType="int" order="BEFORE" keyProperty="id">
SELECT LOGS_SEQ.nextval AS ID FROM DUAL
</selectKey>
3)加記錄返回主鍵 2(屬性配置)
<insert id="addUserHasKey2" parameterType="user" useGeneratedKeys="true"keyProperty="id">
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
4)批量添加記錄返回影響總記錄行數(屬性配置)
<insert id="addUserBatch" parameterType="list" >
insert into user(user_name,user_pwd) values
<foreach collection="list" item="item" separator=",">
(#{item.userName},#{item.userPwd})
</foreach>
</insert>
3.Update 元素標簽使用
1)更新單條記錄返回影響行數
<!-- 更新單條 -->
<update id="updateUser" parameterType="User">
update user set
userName=#{userName} ,userPwd=#{userPwd} where id=#{id}
</update>
2)批量更新多條記錄 屬性配置
<update id="updateUserBatch" parameterType="java.util.Map">
update user set userPwd=#{pwd}
where id in
<foreach collection="ids" item="item" open="(" separator=","
close=")">
#{item}
</foreach>
</update>
4.Delete 元素標簽使用
1)刪除單條記錄
<delete id="delUserById" parameterType="int">
delete from user where
id=#{id}
</delete>
2)批量刪除多條記錄(屬性配置)
<delete id="delUserBatch" parameterType="java.util.Map">
delete from user where
id in
<foreach collection="ids" item="item" open="(" separator=","
close=")" index="index">
#{item}
</foreach>
</delete>
或下列形式,入參為數組類型
<delete id="deleteUserBatch2" >
delete from user where id in
<foreach collection="array" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
九.動態sql語句
1.簡介
MyBatis的強大特性之一便是它的動態SQL。如果你有使用JDBC 或其他類似框架的經驗,你就能體會到根據不同條件拼接SQL語句有多么痛苦。拼接的時候要確保不能忘了必要的空格,還要注意省掉列名列表最后的逗號。利用動態SQL這一特性可以徹底擺脫這種痛苦。它借助ognl(類似於jsp 里面的el表達式)表達式來完成動
態 sql 的拼接使得非常簡便。
2.if條件判斷
<!-- 模糊匹配 -->
<select id="queryUserByUserName" parameterType="map"
resultType="user">
select id,userName,userPwd from user where 1=1
<if test="userName!=null and userName!=''">
and userName like '%${userName}%'
</if>
</select>
2.choose, when, otherwise 選擇器使用
我們不想用到所有的條件語句,而只想從中擇其一二。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句
< select id="queryUserByParams" parameterType="map" resultType="user">
select id,userPwd
<choose>
<when test="nation!=null and nation!=''">
,userName
</when>
<otherwise>
,realName
</otherwise>
</choose>
from user
where userName like '%${userName}%'
<if test="phone!=null and phone!=''">
and phone like '%${phone}%'
</if>
</select>
這條語句的意思就是說 如果我傳進 nation 不為空就查 userName 的值, 否則是realName 的值
3.trim, where, set
前面幾個例子已經合宜地解決了一個臭名昭著的動態 SQL 問題, 然后我們再來看第一條的配置
<select id="findUserByUserName" resultMap="RM_User" >
select
userId, userName, password from user where
userName like '%${userName}%'
<if test="phone != null and phone != ''" >
and phone like '%${phone}%'
</if>
</select>
如果我把 userName like '%${userName}%'這個語句也用if做個判斷
<select id="findUserByUserName" resultMap="RM_User" >
select
userId, userName, password from user where
<if test="userName != null and userName != ''" >
userName like '%${userName}%'
</if>
<if test="phone != null and phone != ''" >
and phone like '%${phone}%'
</if>
</select>
這樣的話我們預測一下 打印的sql應該是
select userId, userName, password from user where
很明顯這條sql會報錯
那為了解決這個問題呢, 我們使用<where></where>標簽
<select id="queryUserByParams" parameterType="map" resultType="user">
select id,userPwd,phone
<choose>
<when test="nation!=null and nation!=''">
,userName
</when>
<otherwise>
,realName
</otherwise>
</choose>
from user
<where>
<if test="userName !=null and userName !=''">
userName like '%${userName}%'
</if>
<if test="phone!=null and phone!=''">
and phone like '%${phone}%'
</if>
</where>
4.foreach
動態 SQL 的另外一個常用的必要操作是需要對一個集合進行遍歷,通常是在構建IN條件語句或者是批量插入 。