MyBatis--把SQL帶進Java


    簡單來看軟件服務的工作流程:用戶端界面操作請求<---->本地處理|遠程服務程序攔截轉發請求<---->服務端邏輯功能實現<--MyBatis用在這里-->數據庫。

    很容易產生兩個問題:為什么在服務程序與數據庫之間需要使用持久層框架?為什么要使用MyBatis?

    直接使用Java操作數據庫會非常繁瑣,具有以下問題:

a. 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。

b. Sql語句在代碼中硬編碼,造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。

c. 使用preparedStatement向占有位符號傳參數存在硬編碼,因為sql語句的where條件不一定,可能多也可能少,修改sql還要修改代碼,系統不易維護。

d. 對結果集解析存在硬編碼(查詢列名),sql變化導致解析代碼變化,系統不易維護,如果能將數據庫記錄封裝成pojo對象解析比較方便。

    MyBatis解決上述問題:

a. 在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。

b. 將Sql語句配置在mapper.xml文件中與java代碼分離。

c. Mybatis自動將java對象映射至sql語句,通過statement中的parameterType定義輸入參數的類型。

d. Mybatis自動將sql執行結果映射至java對象,通過statement中的resultType定義輸出結果的類型。

    

    當前Java工程中常用的持久層框架有MyBatis和Hiberate,兩者的異同點如下:

    相同點:

    a. Hibernate與MyBatis都可以是通過SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session來開啟執行事務和SQL語句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

    b. Hibernate和MyBatis都支持JDBC和JTA事務處理。

    區別:

  • MyBatis可以進行更為細致的SQL優化,可以減少查詢字段。

  • MyBatis容易掌握,而Hibernate門檻較高

  • Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。

  • Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。

  • Hibernate數據庫移植性很好,MyBatis的數據庫移植性不好,不同的數據庫需要寫不同SQL。

  • Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。

    由於MyBatis支持手寫SQL,在開發時進行SQL調優及業務邏輯處理更靈活,現在中小公司大多數采用MyBatis進行持久層開發。

    

    進入正題,什么是MyBatis?

    MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。 MyBatis是一個優秀的持久層框架,它對jdbc的操作數據庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如注冊驅動、創建connection、創建statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。

  Mybatis通過xml或注解的方式將要執行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,並通過java對象和statement中的sql進行映射生成最終執行的sql語句,最后由mybatis框架執行sql並將結果映射成java對象並返回。

    MyBatis(3.2.7版本)架構圖如下:

 

1、 mybatis配置

    SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運行環境等信息。

    mapper.xml文件即sql映射文件,文件中配置了操作數據庫的sql語句。此文件需要在SqlMapConfig.xml中加載。

2、 通過mybatis環境等配置信息構造SqlSessionFactory即會話工廠。

3、 由會話工廠創建sqlSession即會話,操作數據庫需要通過sqlSession進行。

4、 mybatis底層自定義了Executor執行器接口操作數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。

5、 Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id即是Mapped statement的id。

6、 Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。

7、 Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql后將輸出結果映射至java對象中,輸出結果映射過程相當於jdbc編程中對結果的解析處理過程。

 

Mapper.xml中配置的注意點:

<!-- 自定義條件查詢用戶列表 -->

<select id="findUserByUsername" parameterType="java.lang.String" resultType="com.beichen.mybatis.po.User">
select * from user where username like '%${value}%'
</select>

<insert id="insertUser" parameterType="com.beichen.mybatis.po.User">
<selectKey resultType="java.lang.String" order="BEFORE"
keyProperty="id">
  select uuid()

</selectKey>
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

<select id="findUserList" parameterType="com.beichen.mybatis.po.User" resultType="com.beichen.mybatis.po.User">
select * from user

<where>

<if test="id!=null and id!=''">

and id=#{id}
</if>
  <if test="username!=null and username!=''">

and username like '%${username}%'

</if>

</where>

</select>


<sql id="foreach_and_sql_example">  
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
#{id}
</foreach>
</if>
</sql>

<select id="findUserList" parameterType="user" resultType="user">
select * from user

<where>

   id in <include refid="foreach_and_sql_example"/>

</where>
 
</select>   

1. #{}與 ${}

#{}表示一個占位符號,通過#{}可以實現preparedStatement向占位符中設置值,自動進行java類型和jdbc類型轉換,#{}可以有效防止sql注入。 #{}可以接收簡單類型值或pojo屬性值。 如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。

 ${}表示拼接sql串,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,${}括號中只能是value。

2. selectKey可以查詢自增主鍵的值,並自動將其設置到POJO中,其中order="BEFORE"表示當前記錄的主鍵,"AFTER"表示下一條記錄的主鍵。

3. 動態sql

a. if、where、foreach標簽分別實現條件查詢與遍歷,其中<where>標簽會自動處理sql中多出來的第一個and;

b. <sql>標簽用於編寫通用的sql片段,使用<include>標簽加載。

 

Spring與MyBatis整合可以使用掃描包的形式創建Mapper代理對象,簡化了配置過程,具體配置方法略過。

 

最后說明下MyBatis的逆向工程,MyBatis的逆向工程基於數據庫中的表格生成Dao及Mapper文件,提供增刪改查等基本功能,是極好的偷懶神器。逆向工程下載鏈接:

https://github.com/mybatis/generator/releases


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM