j2ee的O/R方案真是多,和Hibernate相比,iBatis最大的特點就是小巧,上手很快。看iBatis的文檔2小時就會用了,這個O/R Mapping特點就是簡單易用。隻要有SQL基礎,相信你不用教程也能看明白。最新版本2.0(下載下傳)。
建構ibatis基礎代碼
ibatis 基礎代碼包括:
1. ibatis 執行個體配置
一個典型的配置檔案如下(具體配置項目的含義見後):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
errorTracingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<transactionManager type="JDBC">
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
<dataSource type="SIMPLE">
<property name="JDBC.Driver"
value="com.p6spy.engine.spy.P6SpyDriver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:mysql://localhost/sample"/>
<property name="JDBC.Username" value="user"/>
<property name="JDBC.Password" value="mypass"/>
<property name="Pool.MaximumActiveConnections"
value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime"
value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from
ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan"
value="1"/>
<property name="Pool.PingConnectionsNotUsedFor"
value="1"/>
</dataSource>
</transactionManager>
<sqlMap resource="com/ibatis/sample/User.xml"/>
</sqlMapConfig>
2. POJO(Plain Ordinary Java Object)
下面是我們用作示例的一個POJO:
public class User implements Serializable {
private Integer id;
private String name;
private Integer sex;
private Set addresses = new HashSet();
public User() {
}
public Integer getId() {
return this.id;
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return this.sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
}
3. 映射檔案
與Hibernate 不同。因為需要人工編寫SQL 代碼,ibatis 的映射檔案一般采
用手動編寫(通過Copy/Paste,手工編寫映射檔案也并沒想象中的麻煩)。
針對上面POJO 的映射代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
" http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
<typeAlias alias="user" type="com.ibatis.sample.User"/>
<select id="getUser"
parameterClass="java.lang.String"
resultClass="user">
<![CDATA[
select
name,
sex
from t_user
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
where name = #name#
]]>
</select>
<update id="updateUser"
parameterClass="user">
<![CDATA[
UPDATE t_user
SET
name=#name#,
sex=#sex#
WHERE id = #id#
]]>
</update>
<insert id="insertUser"
parameterClass="user"
>
INSERT INTO t_user (
name,
sex)
VALUES (
#name#,
#sex#
)
</insert>
<delete id="deleteUser"
parameterClass="java.lang.String">
delete from t_user
where id = #value#
</delete>
</sqlMap>
從上面的映射檔案可以看出,通過<insert>、<delete>、<update>、
<select>四個節點,我們分别定義了針對TUser 對象的增删改查操作。在這
四個節點中,我們指定了對應的SQL 語句,以update節點為例:
……
<update id="updateUser" ⑴
parameterClass="user"> ⑵
<![CDATA[ ⑶
UPDATE t_user ⑷
SET (
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
name=#name#, ⑸
sex=#sex# ⑹
)
WHERE id = #id# ⑺
]]>
</update>
……
⑴ ID
指定了操作ID,之後我們可以在代碼中通過指定操作id 來執行此節點所定
義的操作,如:
sqlMap.update("updateUser",user);
ID設定使得在一個配置檔案中定義兩個同名節點成為可能(兩個update節
點,以不同id區分)
⑵ parameterClass
指定了操作所需的參數類型, 此例中update 操作以
com.ibatis.sample.User 類型的對象作為參數,目标是将提供的User
執行個體更新到資料庫。
parameterClass="user"中,user為“com.ibatis.sample.User”
類的别名,别名可通過typeAlias節點指定,如示例配置檔案中的:
<typeAlias alias="user" type="com.ibatis.sample.User"/>
⑶ <![CDATA[……]]>
通過<![CDATA[……]]>節點,可以避免SQL 中與XML 規範相沖突的字元對
XML映射檔案的合法性造成影響。
⑷ 執行更新操作的SQL,這裡的SQL 即實際資料庫支援的SQL 語句,将由
ibatis填入參數後交給資料庫執行。
⑸ SQL中所需的使用者名參數,“#name#”在運作期會由傳入的user對象的name
屬性填充。
⑹ SQL 中所需的使用者性别參數“#sex#”,将在運作期由傳入的user 對象的
sex屬性填充。
⑺ SQL中所需的條件參數“#id#”,将在運作期由傳入的user對象的id屬性
填充。
對于這個示例,ibatis在運作期會讀取id 為“updateUser”的update節點
的SQL定義,并調用指定的user對象的對應getter方法擷取屬性值,并用此
屬性值,對SQL中的參數進行填充後送出資料庫執行。
此例對應的應用級代碼如下,其中示範了ibatis SQLMap的基本使用方法:
String resource ="com/ibatis/sample/SqlMapConfig.xml";
Reader reader;
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
reader = Resources.getResourceAsReader(resource);
XmlSqlMapClientBuilder xmlBuilder =
new XmlSqlMapClientBuilder();
SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader);
//sqlMap系統初始化完畢,開始執行update操作
try{
sqlMap.startTransaction();
User user = new User();
user.setId(new Integer(1));
user.setName("Erica");
user.setSex(new Integer(1));
sqlMap.update("updateUser",user);
sqlMap.commitTransaction();
finally{
sqlMap.endTransaction();
}
其中,SqlMapClient是ibatis運作的核心,所有操作均通過SqlMapClient
執行個體完成。
可以看出,對于應用層而言,程式員面對的是傳統意義上的資料對象,而非JDBC
中煩雜的ResultSet,這使得上層邏輯開發人員的工作量大大減輕,同時代碼更
加清晰簡潔。
資料庫操作在映射檔案中加以定義,進而将資料存儲邏輯從上層邏輯代碼中獨立
出來。
而底層資料操作的SQL可配置化,使得我們可以控制最終的資料操作方式,通過
SQL的優化獲得最佳的資料庫執行效能,這在依賴SQL自動生成的“全自動”ORM
機制中是所難以實作的。
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
ibatis配置
結合上面示例中的ibatis配置檔案。下面是對配置檔案中各節點的說明:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
" http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings ⑴
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
errorTracingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<transactionManager type="JDBC"> ⑵
<dataSource type="SIMPLE"> ⑶
<property name="JDBC.Driver"
value="com.p6spy.engine.spy.P6SpyDriver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:mysql://localhost/sample"/>
<property name="JDBC.Username" value="user"/>
<property name="JDBC.Password" value="mypass"/>
<property name="Pool.MaximumActiveConnections"
value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime"
value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from
ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan"
value="1"/>
<property name="Pool.PingConnectionsNotUsedFor"
value="1"/>
</dataSource>
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
</transactionManager>
<sqlMap resource="com/ibatis/sample/User.xml"/> ⑷
<sqlMap resource="com/ibatis/sample/Address.xml"/>
</sqlMapConfig>
⑴ Settings 節點
參數 描述
cacheModelsEnabled 是否啟用SqlMapClient上的緩存機制。
建議設為"true"
enhancementEnabled 是否針對POJO啟用位元組碼增強機制以提升
getter/setter的調用效能,避免使用Java
Reflect所帶來的性能開銷。
同時,這也為Lazy Loading帶來了極大的性能
提升。
建議設為"true"
errorTracingEnabled 是否啟用錯誤日志,在開發期間建議設為"true"
以友善調試
lazyLoadingEnabled 是否啟用延遲加載機制,建議設為"true"
maxRequests 最大并發請求數(Statement并發數)
maxTransactions 最大并發事務數
maxSessions 最大Session 數。即目前最大允許的并發
SqlMapClient數。
maxSessions設定必須介于
maxTransactions和maxRequests之間,即
maxTransactions<maxSessions=<
maxRequests
useStatementNamespaces 是否使用Statement命名空間。
這裡的命名空間指的是映射檔案中,sqlMap節點
的namespace屬性,如在上例中針對t_user
表的映射檔案sqlMap節點:
<sqlMap namespace="User">
這裡,指定了此sqlMap節點下定義的操作均從
屬于"User"命名空間。
在useStatementNamespaces="true"的情
況下,Statement調用需追加命名空間,如:
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
sqlMap.update("User.updateUser",use
r);
否則直接通過Statement名稱調用即可,如:
sqlMap.update("updateUser",user);
但請注意此時需要保證所有映射檔案中,
Statement定義無重名。
⑵ transactionManager節點
transactionManager 節點定義了ibatis 的事務管理器,目前提供了以下幾
種選擇:
Ø JDBC
通過傳統JDBC Connection.commit/rollback實作事務支援。
Ø JTA
使用容器提供的JTA服務實作全局事務管理。
Ø EXTERNAL
外部事務管理,如在EJB中使用ibatis,通過EJB的部署配置即可實作自
動的事務管理機制。此時ibatis 将把所有事務委托給外部容器進行管理。
此外,通過Spring 等輕量級容器實作事務的配置化管理也是一個不錯的選
擇。關于結合容器實作事務管理,參見“進階特性”中的描述。
⑶ dataSource節點
dataSource從屬于transactionManager節點,用于設定ibatis運作期使
用的DataSource屬性。
type屬性: dataSource節點的type屬性指定了dataSource的實作類型。
可選項目:
Ø SIMPLE:
SIMPLE是ibatis内置的dataSource實作,其中實作了一個簡單的
資料庫連接配接池機制, 對應ibatis 實作類為
com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
Ø DBCP:
基于Apache DBCP 連接配接池元件實作的DataSource 封裝,當無容器提
供DataSource 服務時,建議使用該選項,對應ibatis 實作類為
com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
Ø JNDI:
使用J2EE 容器提供的DataSource 實作,DataSource 将通過指定
的JNDI Name 從容器中擷取。對應ibatis 實作類為
com.ibatis.sqlmap.engine.datasource.JndiDataSourceFacto
ry。
dataSource的子節點說明(SIMPLE&DBCP):
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
參數 描述
JDBC.Driver JDBC 驅動。
如:org.gjt.mm.mysql.Driver
JDBC.ConnectionURL 資料庫URL。
如:jdbc:mysql://localhost/sample
如果用的是SQLServer JDBC Driver,需要
在url後追加SelectMethod=Cursor以獲得
JDBC事務的多Statement支援。
JDBC.Username 資料庫使用者名
JDBC.Password 資料庫使用者密碼
Pool.MaximumActiveConn
ections
資料庫連接配接池可維持的最大容量。
Pool.MaximumIdleConnec
tions
資料庫連接配接池中允許的挂起(idle)連接配接數。
以上子節點适用于SIMPLE 和DBCP 模式,分别針對SIMPLE 和DBCP 模式的
DataSource私有配置節點如下:
SIMPLE:
參數 描述
Pool.MaximumCheckoutTi
me
資料庫聯接池中,連接配接被某個任務所允許占用的
最大時間,如果超過這個時間限定,連接配接将被強
制收回。(毫秒)
Pool.TimeToWait 當線程試圖從連接配接池中擷取連接配接時,連接配接池中無
可用連接配接可供使用,此時線程将進入等待狀态,
直到池中出現空閑連接配接。此參數設定了線程所允
許等待的最長時間。(毫秒)
Pool.PingQuery 資料庫連接配接狀态檢測語句。
某些資料庫在連接配接在某段時間持續處于空閑狀态
時會将其斷開。而連接配接池管理器将通過此語句檢
測池中連接配接是否可用。
檢測語句應該是一個最簡化的無邏輯SQL。
如“select 1 from t_user”,如果執行此語句
成功,連接配接池管理器将認為此連接配接處于可用狀态。
Pool.PingEnabled 是否允許檢測連接配接狀态。
Pool.PingConnectionsOl
derThan
對持續連接配接時間超過設定值(毫秒)的連接配接進行
檢測。
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
Pool.PingConnectionsNo
tUsedFor
對空閑超過設定值(毫秒)的連接配接進行檢測。
DBCP:
參數 描述
Pool.MaximumWait 當線程試圖從連接配接池中擷取連接配接時,連接配接池中無
可用連接配接可供使用,此時線程将進入等待狀态,
直到池中出現空閑連接配接。此參數設定了線程所允
許等待的最長時間。(毫秒)
Pool.ValidationQuery 資料庫連接配接狀态檢測語句。
某些資料庫在連接配接在某段時間持續處于空閑狀态
時會将其斷開。而連接配接池管理器将通過此語句檢
測池中連接配接是否可用。
檢測語句應該是一個最簡化的無邏輯SQL。
如“select 1 from t_user”,如果執行此語句
成功,連接配接池管理器将認為此連接配接處于可用狀态。
Pool.LogAbandoned 當資料庫連接配接被廢棄時,是否列印日志。
Pool.RemoveAbandonedTi
meout
資料庫連接配接被廢棄的最大逾時時間
Pool.RemoveAbandoned 當連接配接空閑時間超過
RemoveAbandonedTimeout時,是否将其廢
棄。
JNDI由于大部配置設定置是在應用伺服器中進行,是以ibatis中的配置相對簡單,下面
是分别使用JDBC和JTA事務管理的JDNI配置:
使用JDBC事務管理的JNDI DataSource配置
<transactionManager type="JDBC" >
<dataSource type="JNDI">
<property name="DataSource"
value="java:comp/env/jdbc/myDataSource"/>
</dataSource>
</transactionManager>
<transactionManager type="JTA" >
<property name="UserTransaction"
value="java:/ctx/con/UserTransaction"/>
<dataSource type="JNDI">
<property name="DataSource"
value="java:comp/env/jdbc/myDataSource"/>
</dataSource>
IBATIS Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
</transactionManager>
⑷ sqlMap節點
sqlMap 節點指定了映射檔案的位置,配置中可出現多個sqlMap 節點,以指定
項目内所包含的所有映射檔案。