一、概念
MyBatis的前身叫iBatis,本是apache的一個開源項目, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis。MyBatis是支援普通SQL查詢,預存程序和進階映射的優秀持久層架構。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設定以及結果集的檢索。MyBatis使用簡單的XML或註解用於配置和原始映射,將介面和Java的POJOs(Plan Old Java Objects,普通的Java對象)映射成資料庫中的記錄。
Mybatis的功能架構分為三層:
1) API介面層:提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫。介面層一接收到調用請求就會調用資料處理層來完成具體的資料處理。
2) 資料處理層:負責具體的SQL尋找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次資料庫操作。
3) 基礎支撐層:負責最基礎的功能支撐,包括串連管理、交易管理、配置載入和緩衝處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的資料處理層提供最基礎的支撐。
二、Mybatis執行流程圖
詳細說明
1、SessionFactory會話工廠建立
SqlSessionFactoryBuilder
每一個MyBatis的應用程式的入口是SqlSessionFactoryBuilder,它的作用是通過XML設定檔建立Configuration對象(當然也可以在程式中自行建立),然後通過build方法建立SqlSessionFactory對象。沒有必要每次訪問Mybatis就建立一次SqlSessionFactoryBuilder,通常的做法是建立一個全域的對象就可以了。樣本程式如下:
private static SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private static SqlSessionFactory sqlSessionFactory;
private static void init() throws IOException {
String resource = "mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(reader);
}
SqlSessionFactory
SqlSessionFactory對象由SqlSessionFactoryBuilder建立。它的主要功能是建立SqlSession對象,和SqlSessionFactoryBuilder對象一樣,沒有必要每次訪問Mybatis就建立一次SqlSessionFactory,通常的做法是建立一個全域的對象就可以了。SqlSessionFactory對象一個必要的屬性是Configuration對象,它是儲存Mybatis全域配置的一個設定物件,通常由SqlSessionFactoryBuilder從XML設定檔建立。這裡給出一個簡單的樣本:
<?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>
<!-- 配置別名 -->
<typeAliases>
<typeAlias type="org.iMybatis.abc.dao.UserDao" alias="UserDao" />
<typeAlias type="org.iMybatis.abc.dto.UserDto" alias="UserDto" />
</typeAliases>
<!-- 配置環境變數 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/iMybatis?characterEncoding=GBK" />
<property name="username" value="iMybatis" />
<property name="password" value="iMybatis" />
</dataSource>
</environment>
</environments>
<!-- 配置mappers -->
<mappers>
<mapper resource="org/iMybatis/abc/dao/UserDao.xml" />
</mappers>
</configuration>
要注意XML頭部的聲明,需要用來驗證XML文檔正確性。typeAliases 元素是包含所有typeAlias(別名)的列表,別名用來替換完整類名,這樣在需要完整類名的地方就可以用別名來代替。environment元素體中包含對交易管理和串連池的環境配置。mappers元素是包含所有mapper(映射器)的列表,這些mapper的XML檔案包含SQL代碼和映射定義資訊。當然,在XML設定檔中還有很多可以配置的,上面的樣本指出的則是最關鍵的部分,其他配置請參考Mybatis的官方文檔。
2、SqlSession
SqlSession對象的主要功能是完成一次資料庫的訪問和結果的映射,它類似於資料庫的session概念,由於不是安全執行緒的,所以SqlSession對象的範圍需限制方法內。SqlSession的預設實作類別是DefaultSqlSession,它有兩個必須配置的屬性:Configuration和Executor。Configuration前文已經描述這裡不再多說。SqlSession對資料庫的操作都是通過Executor來完成的,Executor的具體功能在下一小節在描述。
到目前為止,我們看到的都是mybatis的流程,我們的應用程式在什麼地方插入到這個流程中並獲得我們想要的結果呢。就是SqlSession這裡。SqlSession有一個重要的方法getMapper,顧名思義,這個方式是用來擷取Mapper對象的。什麼是Mapper對象。根據Mybatis的官方手冊,應用程式除了要初始並啟動Mybatis之外,還需要定義一些介面,介面裡定義訪問資料庫的方法,存放介面的包路徑下需要放置同名的XML設定檔。SqlSession的getMapper方法是聯絡應用程式和Mybatis紐帶,應用程式訪問getMapper時,Mybatis會根據傳入的介面類型和對應的XML設定檔產生一個代理對象,這個代理對象就叫Mapper對象。應用程式獲得Mapper對象後,就應該通過這個Mapper對象來訪問Mybatis的SqlSession對象,這樣就達到裡插入到Mybatis流程的目的。範例程式碼如下:
SqlSession session= sqlSessionFactory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
UserDto user = new UserDto();
user.setUsername("iMybatis");
List<UserDto> users = userDao.queryUsers(user);
對應的介面:
public interface UserDao {
public List<UserDto> queryUsers(UserDto user) throws Exception;
}
對應的設定檔:
<?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="org.iMybatis.abc.dao.UserDao">
<select id="queryUsers" parameterType="UserDto" resultType="UserDto"
useCache="false">
<![CDATA[
select * from t_user t where t.username = #{username}
]]>
</select>
</mapper>
3、Executor
Executor對象在建立Configuration對象的時候建立,並且緩衝在Configuration對象裡。Executor對象的主要功能是調用StatementHandler訪問資料庫,並將查詢結果存入緩衝中(如果配置了緩衝的話)。
4、StatementHandler
StatementHandler是真正訪問資料庫的地方,並調用ResultSetHandler處理查詢結果。
5、ResultSetHandler
處理查詢結果。
三、MyBatis官網
MyBatis官網:
http://www.mybatis.org/mybatis-3/
https://github.com/mybatis/mybatis-3/releases
所需jar包
mybatis-x.x.x.jar
mybatis的核心包只有一個mybatis-3.x.0.jar,另外還有一些【可選】的依賴包(日誌、代理等所需要的),在下載的壓縮包中可以找到。
http://www.mybatis.org/mybatis-3/zh/dependencies.html
四、MyBatis-config xml設定檔詳解
<?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></properties>
<!-- 設定:定義mybatis的一些全域性設定 -->
<settings>
<!-- 具體的參數名和參數值 -->
<setting name="" value=""/>
</settings>
<!-- 類型名稱:為一些類定義別名 -->
<typeAliases></typeAliases>
<!-- 類型處理器:定義Java類型與資料庫中的資料類型之間的轉換關係 -->
<typeHandlers></typeHandlers>
<!-- 對象工廠 -->
<objectFactory type=""></objectFactory>
<!-- 外掛程式:mybatis的外掛程式,外掛程式可以修改mybatis的內部運行規則 -->
<plugins>
<plugin interceptor=""></plugin>
</plugins>
<!-- 環境:配置mybatis的環境 -->
<environments default="">
<!-- 環境變數:可以配置多個環境變數,比如使用多資料來源時,就需要配置多個環境變數 -->
<environment id="">
<!-- 交易管理員 -->
<transactionManager type=""></transactionManager>
<!-- 資料來源 -->
<dataSource type=""></dataSource>
</environment>
</environments>
<!-- 資料庫廠商標識 -->
<databaseIdProvider type=""></databaseIdProvider>
<!-- 映射器:指定對應檔或者映射類 -->
<mappers></mappers>
</configuration>
五、Mapper.xml設定檔詳解
<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com...persistence.usermanager.UserMapper">
<!-- 要對應到所有屬性 才能使用-->
<!--<resultMap id="users" type="User">
<result property="userName"column="user_name"/>
</resultMap>-->
<!-- 這裡namespace必須是UserMapper介面的路徑,不然要啟動並執行時候要報錯 "is not knownto the MapperRegistry" -->
<insert id="createUser" parameterType="User">
<![CDATA[ insert into
user_info (user_id, user_name, user_password,
user_email,user_role) values (#{userId},#{userName}
,#{userPassword},#{userEmail},#{userRole})]]>
<!-- 這裡sql結尾不能加分號,否則報"ORA-00911"的錯誤 -->
</insert>
<!-- 這裡的id必須和UserMapper介面中的介面方法名相同,不然啟動並執行時候也要報錯 -->
<delete id="deleteUser" parameterType="Java.lang.String">
<![CDATA[ delete from user_info where id = #{id} ]]>
</delete>
<update id="updateUsers"parameterType="User">
<![CDATA[update user_info set
user_name = #{userName},
user_password = #{userPassword},
user_email = #{userEmail},
user_role = #{userRole}
where user_id = #{userId} ]]>
</update>
<selectid="selectAllUsers" resultType="User">
<![CDATA[select * from user_info ]]>
</select>
<selectid="selectUserById" resultType="User"parameterType="java.lang.String">
<![CDATA[select * from user_info where user_id = #{userId}]]>
</select>
<select id="selectUsers"resultType="User" parameterType="User">
<![CDATA[select * from user_info ]]>
<where>
<if test="userName!=null">
<![CDATA[And user_name like'%'||#{userName}||'%']]>
</if>
<if test="userRole!=null">
<![CDATA[And user_role like'%'||#{userRole}||'%']]>
</if>
</where>
</select>
<selectid="selectUsersCount" resultType="int">
<![CDATA[select count(*) from user_info ]]>
</select>
<selectid="selectUserByName" resultType="User"parameterType="java.lang.String">
<![CDATA[select * from user_info where user_name =#{userName}]]>
</select>
</mapper>
六、Hibernate與Mybatis的本質區別和應用情境
Hibernate:標準的ORM架構,不需要寫SQL語句,但是最佳化和修改SQL語句比較難。
應用於需求變化固定的中小型的項目,例如後台管理系統、ERP、ORM、OA。
Mybatis:專註SQL本身,SQL的最佳化比較方便,是不完全的ORM。
主要適用於需求變化較多的項目,例如互連網項目。
參考資料:
MyBatis-config xml配置:http://blog.csdn.net/summer_yuxia/article/details/53169227
Mapper.xml配置:http://www.cnblogs.com/lcngu/p/5470695.html