1. 程式人生 > >Ibatis 框架的基本介紹及基礎操作

Ibatis 框架的基本介紹及基礎操作

《一》、iBatis框架的基本介紹:

Ibatis是開源軟體組織Apache推出的一種輕量級的物件關係對映(ORM)框架,和Hibernate、Toplink等在java程式設計的物件持久化方面深受開發人員歡迎。

物件關係對映(ORM):簡單原理是通過面向物件方式操作關係型資料庫,目前儲存資料最常用最流行的工具是關係型資料庫,其操作方式是通過 SQL語句操作資料庫的表,但是對於Java面向物件程式語言中,所有的操作物件都是物件,因此物件關係對映就是把資料庫表和java程式語言中的物件對 應起來,把表的列同java物件中的欄位對應起來,程式設計師在程式開發過程中不再是使用原始SQL語句去直接操作資料庫,而是通過ORM提供的查詢語句操作 普通的java物件,ORM將其提供的對普通java物件的查詢語句翻譯成SQL語句來操作資料庫,從而遮蔽了不同資料庫SQL語句的差別,簡化了程式開 發工作,提高了程式的可移植性。


一、為啥使用iBatis?
    在 Hibernate、JPA 這樣的一站式物件 / 關係對映(O/R Mapping)解決方案盛行之前,iBaits 基本是持久層框架的不二選擇。即使在持久層框架層出不窮的今天,iBatis 憑藉著易學易用、輕巧靈活等特點,也仍然擁有一席之地。尤其對於擅長 SQL 的開發人員來說,iBatis 對 SQL 和儲存過程的直接支援能夠讓他們在獲得 iBatis 封裝優勢的同時而不喪失 SQL 調優的手段,這是 Hibernate/JPA 所無法比擬的。具體而言,使用 iBatis 框架的主要優勢主要體現在如下幾個方面:
 首先,iBatis 封裝了絕大多數的 JDBC 樣板程式碼,使得開發者只需關注 SQL 本身,而不需要花費精力去處理例如註冊驅動,建立 Connection,以及確保關閉 Connection 這樣繁雜的程式碼。
 其次,iBatis 可以算是在所有主流的持久層框架中學習成本最低,最容易上手和掌握的框架。雖說其他持久層框架也號稱門檻低,容易上手,但是等到你真正使用時會發現,要想掌握並用好它是一件非常困難的事。在工作中我需要經常參與面試,我曾聽到過很多位應聘者描述,他們所在的專案在技術選型時選擇 Hibernate,後來發現難以駕馭,不得不將程式碼用 JDBC 或者 iBatis 改寫。

二、iBATIS 是什麼?

 iBatis是一個持久層框架,它能夠自動在java、.NET和Ruby on Rails中與SQL資料庫和物件之間的對映。對映是從應用程式邏輯封裝在XML配置檔案中的SQL語句脫鉤。

    iBatis是一個輕量級的框架和永續性API適合持久化的POJO(普通Java物件)。

    iBatis是被稱為一個數據對映和對映需要的類的屬性和資料庫中的表的列之間的引數和結果。

    iBatis和其他持久化框架,如Hibernate之間的顯著區別在於,iBATIS強調使用SQL,而其他的框架通常使用一個自定義的查詢語言,具有Hibernate查詢語言(HQL)或Enterprise JavaBeans的查詢語言(EJB QL)。

三.iBatis的設計理念:

        iBatis提供了以下的設計理念:
    1、簡單: iBATIS的被廣泛認為是可用的最簡單的持久化框架之一。
    2、快速開發:iBATIS的理念是盡一切可能,以方便超快速開發。
    3、可移植性: iBATIS可用於幾乎任何語言或平臺,如Java,Ruby和C#,微軟.NET實現。
    4、獨立的介面:iBATIS提供獨立於資料庫的介面和API,幫助應用程式的其餘部分保持獨立的任何永續性相關的資源。
    5、開源:iBATIS是自由和開放原始碼軟體。

四.iBatis的優點

         使用iBATIS的一些優勢:
     1、支援儲存過程:iBATIS的SQL封裝以儲存過程的形式,使業務邏輯保持在資料庫之外,應用程式更易於部署和測試,更便於移植。
     2、支援內嵌的SQL:預編譯器不是必需的,並有完全訪問所有的SQL語句的特性。
     3、支援動態SQL: iBATIS特性提供基於引數動態生成SQL查詢。
     4、支援O / RM:iBATIS支援許多相同的功能作為一個O / RM工具,如延遲載入,連線抓取,快取,執行時程式碼生成和繼承。

 Ibatis優缺點總結:

優勢:使用標準的Sql語句,與JDBC相比簡單方便,減少了程式碼量,架構和效能得到增強;與Hibernate等ORM工具相比因為更接近Sql語句,效能可控;sql語句與程式程式碼分隔,簡化了專案分工,大大提高並行開發的可能性。

缺點:還需要寫標準的sql語句,不像Hibernate完全遮蔽了底層資料庫的差異,程式的 可移植性比Hibernate和JPA要差 ; 輸入引數和輸出引數都只能有一個 ,程式編寫的靈活性不是太高。


    

五、iBatis到MyBatis

     iBatis 自從在 Apache 軟體基金會網站上釋出至今,和他的明星兄弟們(Http Server,Tomcat,Struts,Maven,Ant 等等)一起接受者萬千 Java 開發者的敬仰。在 Apache 寄居六年之後,iBatis 將程式碼託管到 Google Code。在宣告中給出的主要理由是,和 Apache 相比,Google Code 更有利於開發者的協同工作,也更能適應快速釋出。於此同時,iBatis 更名為 MyBatis。

    從 iBatis 到 MyBatis,不只是名稱上的變化,MyBatis 提供了更為強大的功能,同時並沒有損失其易用性,相反,在很多地方都藉助於 JDK 的泛型和註解特性進行了簡化。iBatis 確實該退休了,因為一個更為出色的繼任者經過 10 個 Beta 版本的蛻變已然出現在我們的面前。

《二》、 Ibatis的基本操作

1、Ibatis開發的準備工作:

(1).將Ibaits相關的jar包新增到工程的類路徑下。

(2).Ibatis工程的主要配置檔案為:

a.Ibatis的總配置檔案SqlMapConfig.xml。

b.Ibatis的實體對映檔案。

2、Ibatis總配置檔案sql-map-config.xml:

Ibatis的總配置檔案主要是配置資料庫連線相關資訊,和Ibatis實體對映檔案。其寫法示例如下:

<? xml version=”1.0” encoding=”UTF-8” ?>  
<! DOCTYPE sqlMapConfig public “-//ibatis.apache.org//DTD SQL Map Config 2.0//EN”  “http://ibatis.apache.org//dtd//sql-map-config-2.dtd”>  
<sqlMapConfig>  
  <transactionManager type=”JDBC” commitRequired=”false”>  
    <dataSource type=”SIMPLE”>  
      <property name= “JDBC.Driver” value=”資料庫的jdbc驅動”/>  
      <property name=”JDBC.ConnectionURL” value=”資料庫的url”/> 
      <property name=”JDBC.Username” value=”資料庫使用者名稱”/>  
      <property name=”JDBC.Password” value=”資料庫的密碼”/>  
      ……  
    </dataSource>  
  </transactionManager>  
  <sqlMap resource=”Ibatis的實體對映檔案”/>  
  ……  
</sqlMapConfig>

3、 Ibatis實體對映檔案user.xml的寫法示例:

Ibatis的實體對映檔案是Ibatis框架的核心,起作用是將Java的持久化實體物件和關係型資料庫對映起來,其內容主要是包括java實體各種增刪改查操作對應的資料庫語句。其寫法示例如下:

<? xml version=”1.0” encoding=”UTF-8” ?>  
<! DOCTYPE sqlMap public “-//ibatis.apache.org//DTD SQL Map 2.0//EN”  “http://ibatis.apache.org//dtd//sql-map-2.dtd”>  
<sqlMap namespace=”Ibatis名稱空間”>  
  <typeAlias alias=”實體類類別名” type=”實體類全路徑”/>  
  <!--restultMap主要是用於Ibatis對資料增刪改查操作的返回值結果對於java物件的對映,一般用於所返回的物件可能包含的是一個以上java物件的欄位,如果是一個java物件中的欄位一般使用resultClass-->  
  <resultMap id=”結果集id” class=”實體類別名”>  
    <result property=”java實體類中的屬性名” column=”資料庫表中的列名”/>  
    ……  
  </resultMap>  
  ……  
</sqlMap>

   4、   讀取Ibatis的總配置檔案得到SqlMapClient:

private static SqlMapClient sqlMapClient = null;  
static{  
  try{  
    Reader reader = com.ibatis.common.resource.Resources.getResourceAsReader(“Ibatis總配置檔案路徑”);  
    sqlMapClient = com.ibatis.sqlMap.client.SqlMapClientBuilder.builderSqlMapClient(reader);  
    reader.close();  
  }catch(IOException e){  
    異常處理…….  
  }  
}

  5、   Ibatis的SQL Map:

(1).Ibatis的SQL Map的核心概念是Mapped Statement。Mapped Statement可以使用任意的SQL語句,並擁有 parameterMap/parameterClass(輸入引數)和resultMap/resultClass(輸出結果)。

(2). <statement>元素是個通用的宣告,可以用於任何型別的SQL語句,但是通常使用具體的<statement>型別, 如:查詢使用<select>,新增使用<insert>,更新使用<update>,刪除使 用<delete>。

   6、  Ibatis的增刪改查操作簡單例子:

(1).實體類必須遵循JavaBean的規範,提供一個無引數的構造方法,欄位必須提供get和set方法。

(2).在Ibatis對應的實體對映檔案的<sqlMap>標籤元素新增如下:

7、Ibatis新增:

<insert id=”Ibatis新增實體操作Id” parameterClass=”引數型別”>  
     insert into 實體對應資料庫中的表名(實體欄位對應的表的列名1, 實體欄位對應的表的列名2,……) values(#實體類欄位1#,#實體類欄位2#......);  
</insert>

注意:Ibatis增刪改查語句的引數是通過 parameterClass或者parameterMap 傳遞的。 Ibatis只能傳遞 一個引數 ,如果又多個引數需要封裝在一個物件中。

 8、Ibatis刪除:

<delete id=”Ibatis刪除實體操作Id” parameterClass=”引數型別”>  
       delete from 實體對應資料庫中的表名 where 列名=#列名對應的實體欄位名#;  
</delete>

注意:刪除和查詢時,經常需要根據一定條件操作,有時可能需要模糊查詢,對於

c. Ibatis 模糊查詢

如name like‘%c%’。在Ibatis中有兩種寫法:

寫法1:在java方法中傳遞引數時寫成:”%欄位名%”。

寫法2:在Ibatis的sql語句中可以寫成如:where name=’%$欄位名$%’。

 9、 Ibatis更新:

<update id=”Ibatis更新實體操作Id” parameterClass=”引數型別”>  
       update 實體對應資料庫的表名 set 列名1=#欄位1#,列名2=#欄位2#,…….where ….;  
</update>   

 10、  Ibatis查詢

<select id=”Ibatis查詢實體操作Id” resultClass=”查詢結果型別” >  
       select * from 實體對應的表名;  
</select>

注意:這裡演示的是最簡單的查詢,其結果是一個實體的集合。

 11、  在java物件中使用Ibatis的statement操作:

(1).根據Ibatis總配置檔案得到SqlMapClient物件,具體方法參見“5. 讀取Ibatis的總配置檔案得到SqlMapClient”。

(2).使用SqlMapClient物件的 queryForObject(),queryForList(),insert(),delete(),update()方法 。這些方法都需要一個傳遞一個引數: 在實體對映檔案中定義的操作statementId ,如果這些定義的操作還需要輸入引數,則還需要傳遞輸入引數物件。簡單用法如下:

實體物件型別 物件= sqlMapClient.queryForObject(“實體對映檔案名稱空間.statementId”, “查詢條件引數”); 
例如:
user = (User) sqlMapClient.queryForObject("querybyid",id);
list = sqlMapClient.queryForList("queryAll",user);
sqlMapClient.update("update", user);
sqlMapClient.delete("delete",id);
sqlMapClient.insert("insert", user);
user = (User)sqlMapClient.queryForObject("login", u);

  12、  Ibatis主鍵自動生成:

通過使用 <select>的子元素<selectkey>來支援自動生成主鍵 。對於不同的資料庫主鍵自動生成機制是不同的,Oracle是通過自增序列欲生成的,MS-SQL Server是通過Identity後生成的。這裡以Oracle資料庫為例簡單講述一下主鍵自動生成的方法:

(1).首先在Oracle資料庫中建立一個自增的序列:

create Sequence 序列名
start with 1
increment 1;

(2).在insert標籤中插入selectkey子標籤:

<insert id=”新增實體操作Id” parameterClass=”輸入引數型別”>  
       <selectkey resultClass=”int” keyProperty=”自定義主鍵名稱”>  
              select 序列名.nextval from dual;  
       </selectkey>  
       insert into 表名(主鍵,列名1,列名2,……)  values(#自定義主鍵名稱#,#欄位1#,#欄位2#,…….);  
</insert>

注意:selectkey標籤中的keyProperty屬性是主鍵賦值的物件。

13、 Ibatis的內嵌引數:

所謂內嵌引數是指,使用Ibatis時,當沒有給定引數傳遞值時,Ibatis會使用預設的值代替。

語法為:#引數值:資料庫中資料型別:內嵌引數#

一個簡單的例子如下:

<statement id=”insertProduct” parameterClass=”Product”>  
      Insert into Product(PRD_ID,PRD_DESC)  values(#id:Number:-999999#,#desc:varchar:noEntry#);  
</statement>

當id沒有給定值是資料庫中預設為0,當desc沒有給定值是資料庫預設給定noEntry。

  14、 Ibatis物件之間的關係:

Ibatis的輸入引數和輸出引數只能是一個,因此,當輸入引數在一個實體物件時,使用 parameterClass ,當輸入物件也只在一個實體物件中時,使用 resultClass 。

但是有很多時候輸入引數和輸出引數可能包含在幾個實體物件中,我們不能為了只傳遞一個引數而專門為這些輸入和輸出引數組合專門建立類,因此就需要使用 parameterMap和resultMap 來組合多個實體物件中的欄位。

以resultMap為例,使用方法如下:

<resultMap id=”resultMapId”>  
       <result property=”……” column=”…….” select=”實體對映檔案中的StatementId”/>  
       ……  
</resultMap>   
<sqlMap>
  <typeAlias alias="User" type="com.pojo.User" />
     <resultMap id="UserResult" class="User">
       <result property="id" column="ID" />
     <result property="username" column="USERNAME" />
     <result property="password" column="PASSWORD" />
   </resultMap>
    
   <select id="login" resultMap="UserResult" parameterClass="User">
     select * from USER where USERNAME=#username# and PASSWORD=#password#
   </select>
  
   <insert id="insert" parameterClass="User">
    insert into USER(ID,USERNAME,PASSWORD)values(#id#,#username#,#password#)
   </insert>
  
  <delete id="delete" parameterClass="int">
        delete from USER where ID = #id#
    </delete>
  
  <update id="update" parameterClass="User">
        update USER set USERNAME=#username#,PASSWORD=#password# where ID = #id#
    </update>
  
  <select id="querybyid" parameterClass="int" resultClass="User">
        select * from USER where ID = #id#
    </select> 
    
     <select id="queryAll" parameterClass="User" resultClass="User">
        select * from USER
    </select>
</sqlMap>

15、  Ibatis的SQL Map通過<procedure>標籤元素呼叫儲存過程:

儲存過程是資料庫將一組完成特定功能的Sql語句進行編譯,每次呼叫時不必重新編譯,因此執行速度和效率都比直接使用Sql語句有很大優勢。在 Ibatis中通過<procedure>標籤元素 可以直接呼叫資料庫的儲存過程,其過程如下:

(1).定義儲存過程所需輸入/輸出引數,如:

<parameterMap id=”儲存過程引數” class=”map”>  
       <parameter property=”email1” jdbcType=”varchar” javaType=”java.lang.String” mode=”INOUT”/>  
       <parameter property=”email2” jdbcType=”varchar” javaType=”java.lang.String” mode=”INOUT”/>  
</parameterMap>   

(2).呼叫儲存過程,如:

<procedure id=”Ibatis呼叫儲存過程” parameterMap=” 儲存過程引數”>  
       {call 儲存過程名(?,?)}  
</procedure>   

注意:Ibatis呼叫儲存過程時,要確保始終只使用JDBC標準的儲存過程語法。

 16、  Ibatis與Spring整合:

現在Java Web開發中,SSH(Spring,Sturts,Hibernate)三個開源框架組合非常流行,對於一些對Hibernate不熟悉或者懷疑 Hibernate效能的人,也可以使用Ibatis代替Hibernate框架,即SSI(Spring,Struts,Ibatis)。Spring 和Struts的整合這裡不多說了,具體說一下Spring和Ibatis的整合。

(1).對Ibatis工程引入Spring支援,即將Spring相關的jar包加入到類路徑中,在/src目錄下建立spring配置檔案,在web.xml檔案中指定spring配置檔案並新增spring的WebContext啟動監聽器。

(2).將對資料庫的連線資訊放交由spring管理,在spring配置檔案中新增資料庫連線資訊:

<bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”>  
       <property name=”driverClassName” value=”資料庫驅動類”/>  
       <property name=”url” value=”資料庫連線URL”/>  
       <property name=”username” value=”資料庫連線使用者名稱”/> 
       <property name=”password” value=”資料庫連線密碼”/>  
</bean>   

(3).在spring配置檔案中新增對Ibatis的支援:

<bean id=”sqlMapClient” class=”org.springframework.orm.ibatis.SqlMapClientFactoryBean”>  
       <property name=”configLocation” value=”Ibatis總配置檔案路徑”/>  
       <!--為Spring建立的SqlMapClient物件指定資料來源-->  
       <property name=”dataSource” ref=”dataSource”/>  
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="configLocation">
            <value>/WEB-INF/sql-map-config.xml</value>
        </property>
    </bean>

(4).在Ibatis總配置檔案中移除關於資料庫連線的資訊,只需在Ibatis總配置檔案中配置實體對映檔案即可。

至此,Spring和Ibatis就無縫整合起來,在使用時Spring會讀取建立SqlMapClient物件,併為其注入資料來源,直接通過spring獲得SqlMapClient物件就可以直接使用。