1. Ibatis是開源軟件組織Apache推出的一種輕量級的對象關系映射(ORM)框架,和Hibernate、Toplink等在java編程的對象持久化方面深受開發人員歡迎。
對象關系映射(ORM):簡單原理是通過面向對象方式操作關系型數據庫,目前存儲數據最常用最流行的工具是關系型數據庫,其操作方式是通過SQL語句操作數據庫的表,但是對於Java面向對象編程語言中,所有的操作對象都是對象,因此對象關系映射就是把數據庫表和java編程語言中的對象對應起來,把表的列同java對象中的字段對應起來,程序員在程序開發過程中不再是使用原始SQL語句去直接操作數據庫,而是通過ORM提供的查詢語句操作普通的java對象,ORM將其提供的對普通java對象的查詢語句翻譯成SQL語句來操作數據庫,從而屏蔽了不同數據庫SQL語句的差別,簡化了程序開發工作,提高了程序的可移植性。
2. Ibatis開發的准備工作:
(1).將Ibaits相關的jar包添加到工程的類路徑下。
(2).Ibatis工程的主要配置文件為:
a.Ibatis的總配置文件SqlMapConfig.xml。
b.Ibatis的實體映射文件。
3.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>
4. 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>
5. 讀取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){
異常處理…….
}
}
6. Ibatis的SQL Map:
(1).Ibatis的SQL Map的核心概念是Mapped Statement。Mapped Statement可以使用任意的SQL語句,並擁有parameterMap/parameterClass(輸入參數)和resultMap/resultClass(輸出結果)。
(2). <statement>元素是個通用的聲明,可以用於任何類型的SQL語句,但是通常使用具體的<statement>類型,如:查詢使用<select>,添加使用<insert>,更新使用<update>,刪除使用<delete>。
7. Ibatis的增刪改查操作簡單例子:
(1).實體類必須遵循JavaBean的規范,提供一個無參數的構造方法,字段必須提供get和set方法。
(2).在Ibatis對應的實體映射文件的<sqlMap>標簽元素添加如下:
a.Ibatis添加:
<insert id=”Ibatis添加實體操作Id” parameterClass=”參數類型”>
insert into 實體對應數據庫中的表名(實體字段對應的表的列名1, 實體字段對應的表的列名2,……) values(#實體類字段1#,#實體類字段2#......);
</insert>
注意:Ibatis增刪改查語句的參數是通過parameterClass或者parameterMap傳遞的。Ibatis只能傳遞一個參數,如果又多個參數需要封裝在一個對象中。
b. Ibatis刪除:
<delete id=”Ibatis刪除實體操作Id” parameterClass=”參數類型”>
delete from 實體對應數據庫中的表名 where 列名=#列名對應的實體字段名#;
</delete>
注意:刪除和查詢時,經常需要根據一定條件操作,有時可能需要模糊查詢,對於
c. Ibatis 模糊查詢
如name like‘%c%’。在Ibatis中有兩種寫法:
寫法1:在java方法中傳遞參數時寫成:”%字段名%”。
寫法2:在Ibatis的sql語句中可以寫成如:where name=’%$字段名$%’。
d. Ibatis更新:
<update id=”Ibatis更新實體操作Id” parameterClass=”參數類型”>
update 實體對應數據庫的表名 set 列名1=#字段1#,列名2=#字段2#,…….where ….;
</update>
e. Ibatis查詢
<select id=”Ibatis查詢實體操作Id” resultClass=”查詢結果類型” >
select * from 實體對應的表名;
</select>
注意:這里演示的是最簡單的查詢,其結果是一個實體的集合。
8. 在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);
9. 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屬性是主鍵賦值的對象。
10. 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。
11. 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>
12. 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標准的存儲過程語法。
13. 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對象就可以直接使用。
14. Ibatis優缺點總結:
優勢:使用標准的Sql語句,與JDBC相比簡單方便,減少了代碼量,架構和性能得到增強;與Hibernate等ORM工具相比因為更接近Sql語句,性能可控;sql語句與程序代碼分隔,簡化了項目分工,大大提高並行開發的可能性。
缺點:還需要寫標准的sql語句,不像Hibernate完全屏蔽了底層數據庫的差異,程序的可移植性比Hibernate和JPA要差;輸入參數和輸出參數都只能有一個,程序編寫的靈活性不是太高。
