1、前言
努力學習完ssm框架之后,終於也成功的把三大框架的使用以及配置文件細節忘得一干二凈。為了努力撿起來以及方便今后的復習,決定寫一篇博客記錄一下。
- 本博客的所有分析都是在持久層接口以及接口中的方法已經創建的基礎上進行的。
- 本博客對於Mybatis中標簽的細節屬性不做過多探討,主要着重於Mybatis框架的底層原理和大體使用步驟。
- 本博客着重於以Mybatis的xml配置方式為主,作源碼分析。
- 本博客中的所有圖片均為原創,如需原圖,請聯系作者。
2、 mybatis簡介
持久層框架Mybatis,該框架涉及Java與數據庫的交互,有一下幾個特點:
(1)采用了高大上的ORM(Object-Relation Mapper) 思想,其作用也就是將關系型數據庫(mysql,oracle等)中的表與Java中的類作一個映射,從而使得在需要操作數據庫時,可以直接操作java中的對象完成操作。
- 實際使用時的體現:將Java中的類名與數據庫表中的列名保持一致
- 優點:解耦,操作簡便
- 缺點:影響性能(使用緩存技術解決),復雜查詢困難。
(2)使用了構建者模式以及工廠模式。構建者模式了解不多,而工廠模式則在創建對象和設置緩存時起到了極為重要的作用。
(3)使用動態代理創建持久層對象,得利於該方法,在使用mybatis框架進行持久層操作時,不需要實現定義好的java接口,只需在配置文件中使用合適標簽完成需要的sql語句操作即可。
(4)與原始的JDBC相比,使用Mybatis能讓我們的注意力放在SQL語句的編寫上,而屏蔽了注冊驅動,建立連接和獲取執行SQL語句的statement對象等一系列操作。(雖然這些操作都反映在了配置文件中,但是我們還是假裝看不到吧…)
3、 Mybatis配置文件
Mybatis通常都是有一個主配置文件和多個映射配置文件。主配置文件定義在項目中的resources包下,主配置文件中有各個映射配置文件的路徑,而每個映射配置文件就對應Dao層中定義好的接口,映射配置文件的位置也要和dao的文件位置保持一致,具體見下圖:
3.1、主配置文件
首先,我們需要知道主配置文件的主要功能是什么,從我的現階段的學習來說,主配置文件的功能主要有以下四個方面:
- 配置數據庫連接
- 映射其他配置文件位置
- 起別名簡化操作
- 設置緩存
那么,如何實現這些功能,此處先將主配置文件的內容展示如下:
<configuration>
<!--引入外部數據庫連接池的配置文件jdbcConfig.properties-->
<properties resource="jdbcConfig.properties"/>
<!--開始配置環境-->
<environments default="mysql">
<!--配置mysql的環境-->
<environment id="mysql">
<!--配置事務-->
<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>
<!--配置映射文件的位置-->
<mappers>
<package name="com.zjl.dao"></package>
<mapper resource="com/zjl/dao/UserDao.xml"/>
<mapper class="com.zjl.dao.UserDao"/>
</mappers>
</configuration>
第一步,從數據庫的連接開始,對代碼中的數據庫配置的圖解分析如下:
第二步,確定映射配置文件的位置,這一階段的開啟標簽是mapper,對於代碼的圖解分析如下:
在映射文件路徑的配置中,我們可以直接通過package標簽進行別名的配置,故而就不再論述。
對於提及的緩存配置,因為所牽涉的細節過多,且在不進行配置的情況下,其默認設置可以符合我們大多數場景的需求,在此處就不再過多論述,之后可能會另寫一篇博客記錄一下標簽的詳細使用細節。
3.2、映射配置文件
在主配置文件創建完成的情況下,我們應該依照主配置文件中指定的映射配置文件路徑創建映射配置文件,並根據對應的dao層中接口的方法編寫好映射配置文件,而映射配置文件的功能即:
- 使用標簽編寫sql語句,從而對dao層中接口的方法進行實現
要實現該功能,我們需要知道想要通過一個映射文件實現一個接口中定義好的方法,所必備的因素有哪些?列舉如下:
- 接口及方法名
- 方法輸出參數類型
- 方法返回參數類型
- 方法實現的功能
有了以上的大致分析,再列舉出一個映射文件書寫的例子進行分析:
首先,我們dao接口UserDao中定義的方法如下:
<mapper namespace="com.zjl.dao.UserDao">
<!--添加用戶-->
<insert id="saveUser" parameterType="com.zjl.domain.User">
<!--配置插入操作后,獲取插入用戶的id-->
<!--keyProperty對應與實體類中屬性的名稱-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
<!--更新用戶-->
<update id="updateUser" parameterType="com.zjl.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id};
</update>
<!--刪除用戶-->
<delete id="deleteUser" parameterType="Integer">
delete from user where id=#{uid};
</delete>
<!--查詢一個用戶-->
<select id="findById" parameterType="INT" resultType="com.zjl.domain.User">
select * from user where id=#{uid};
</select>
<!--根據姓名查詢(模糊查詢)用戶-->
<select id="findByName" resultType="com.zjl.domain.User" parameterType="String">
select * from user where username like #{name};
</select>
</mapper>
對於配置文件對應以上接口的聯合圖解分析如下:
在完成了主配置文件和映射配置文件的編寫之后,實際上我們已經能夠根據這兩種配置文件的內容去連接數據庫,並且對接口中的方法進行實現從而完成dao層的操作了,而mybatis框架正是封裝了從配置文件實現dao層操作,所需要的各種方法和對象。
4、 Mybatis實現原理
從我們之前的經驗可以知道,實現dao層的操作,獲取可以對數據庫進行操作Connection連接對象以及PrepareStatement執行sql語句的對象是最重要的,在主配置文件中,我們已經配置了數據庫連接的信息,那么Mybatis是如何通過xml文件中的信息完成數據庫連接呢?我們先對數據庫連接做分析,首先mybatis使用時的代碼如下:
public class mybatisTest {
private UserDao userDao;
private InputStream in;
private SqlSessionFactoryBuilder builder;
private SqlSessionFactory factory;
private SqlSession sqlSession;
public void init() throws IOException {
//讀取配置文件,生成字節碼文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//使用構建者模式,創建SqlSessionfactory工廠
builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
//使用工廠模式,創建sqlSession
sqlSession = factory.openSession();
//使用sqlsession中的方法獲取UserDao的代理對象,相當於對UserDao接口進行實現
userDao = sqlSession.getMapper(UserDao.class);
}
對於以上的代碼,分步做以下圖解:
在通過SqlSession.getMapper()方法獲得接口的實現類之后,即可使用接口實現類直接調用方法即可。
5、 Mybatis小結
想要深入Mybatis的原理細節,有幾個重要的對象需要去熟悉:
- Configuration:雖然並未直接在代碼中出現,但其卻貫穿Mybatis框架始終;
- SqlSession:Mybatis的核心對象;
- Executor:執行sql語句的執行器;
- MapperRegister:動態代理的開端,SqlSession.getMapper()方法的后端實現。
框架的學習往往繁雜易忘,希望自己有足夠的耐心去閱讀源碼,深入分析。