j2ee的O/R方案真是多,和Hibernate相比,iBatis最大的特點就是小巧,上手很快??磇Batis的文檔2小時就會用了,這個O/R Mapping特點就是簡單易用。只要有SQL基礎,相信你不用教程也能看明白。最新版本2.0(下載)。
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;
reader = Resources.getResourceAsReader(resource);
XmlSqlMapClientBuilder xmlBuilder =
new XmlSqlMapClientBuilder();
SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader);
Reader reader = Resources.getResourceAsReader( resource );
??SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(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 節點,以指定
項目內所包含的所有映射文件。