作者:夏昕 xiaxin(at)gmail.com
ibatis基礎(chǔ)代碼包括:?
1.??ibatis實例配置?
一個典型的配置文件如下(具體配置項目的含義見后):?
<?
xml?version="1.0"?encoding="UTF-8"?
?>
?
<!
DOCTYPE?sqlMapConfig?
????PUBLIC?"-//iBATIS.com//DTD?SQL?Map?Config?2.0/
????"http://www.ibatis.com/dtd/sql-map-config-2.dt
?
<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
>
?
??
</
transactionManager
>
?
?
??
<
sqlMap?
resource
="com/ibatis/sample/User.xml"
/>
?
?
</
sqlMapConfig
>
?
?
⑴ Settings 節(jié)點?
cacheModelsEnabled?
是否啟用SqlMapClient上的緩存機制。 建議設(shè)為"true"
enhancementEnabled?
是否針對POJO啟用字節(jié)碼增強機getter/setter的調(diào)用效能,避免Reflect所帶來的性能開銷。同時,這也為Lazy Loading帶來提升。 建議設(shè)為"true"
errorTracingEnabled?
是否啟用錯誤日志,在開發(fā)期間建議設(shè)為"true" 以方便調(diào)試
lazyLoadingEnabled?
是否啟用延遲加載機制,建議設(shè)為"true"
maxRequests?
最大并發(fā)請求數(shù)(Statement并發(fā)數(shù))
maxTransactions?
最大并發(fā)事務(wù)數(shù)
maxSessions? 最大Session數(shù)。即當前最大允許的并發(fā)SqlMapClient數(shù)。?
?
useStatementNamespaces?
是否使用Statement命名空間。
這里的命名空間指的是映射文件中,sqlMap節(jié)的namespace屬性,如在上例中針對t_use
表的映射文件sqlMap節(jié)點: <sqlMap namespace="User"> 這里,指定了此sqlMap節(jié)點下定義的操作均屬于"User"命名空間。 在useStatementNamespaces="true"的情況下,Statement調(diào)用需追加命名空間,如:sqlMap.update("User.updateUser",user);
否則直接通過Statement名稱調(diào)用即可,如: sqlMap.update("updateUser",user); 但請注意此時需要保證所有映射文件中,Statement定義無重名。
transactionManager節(jié)點
transactionManager節(jié)點定義了ibatis的事務(wù)管理器,目前提供了以下幾
種選擇:
? JDBC
通過傳統(tǒng)JDBC Connection.commit/rollback實現(xiàn)事務(wù)支持。??
JTA
使用容器提供的JTA服務(wù)實現(xiàn)全局事務(wù)管理。
?? EXTERNAL
外部事務(wù)管理,如在EJB中使用ibatis,通過EJB的部署配置即可實現(xiàn)自
動的事務(wù)管理機制。此時ibatis將把所有事務(wù)委托給外部容器進行管理。
dataSource節(jié)點?
? dataSource從屬于transactionManager節(jié)點,用于設(shè)定ibatis運行期使用的DataSource屬性。
?type屬性:
?dataSource節(jié)點的type屬性指定了dataSource的實現(xiàn)類型。 可選項目:
?SIMPLE:
? SIMPLE是ibatis內(nèi)置的dataSource實現(xiàn),其中實現(xiàn)了一個簡單的
數(shù)據(jù)庫連接池機制,對應(yīng) ibatis 實現(xiàn)類為
com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
?
DBCP:
? 基于Apache DBCP連接池組件實現(xiàn)的DataSource封裝,當無容器提
供DataSource服務(wù)時,建議使用該選項,對應(yīng)ibatis實現(xiàn)類為
com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
?
JNDI:
使用J2EE容器提供的DataSource實現(xiàn),DataSource將通過指定
的JNDI Name從容器中獲取。對應(yīng) ibatis實現(xiàn)類為
com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
?
?dataSource的子節(jié)點說明(SIMPLE&DBCP):
JDBC.Driver? JDBC 驅(qū)動。
如:org.gjt.mm.mysql.Driver
JDBC.ConnectionURL?
數(shù)據(jù)庫URL。
如:jdbc:mysql://localhost/sample
如果用的是SQLServer JDBC Driver,需要
在url后追加SelectMethod=Cursor以獲得
JDBC事務(wù)的多Statement支持。
?JDBC.Username
? 數(shù)據(jù)庫用戶名
JDBC.Password?
數(shù)據(jù)庫用戶密碼
Pool.MaximumActiveConnections?
數(shù)據(jù)庫連接池可維持的最大容量。
Pool.MaximumIdleConnections?
數(shù)據(jù)庫連接池中允許的掛起(idle)連接數(shù)。
JNDI由于大部分配置是在應(yīng)用服務(wù)器中進行,因此ibatis中的配置相對簡
分別使用JDBC和JTA事務(wù)管理的JDNI配置:
使用JDBC事務(wù)管理的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
>
?
?sqlMap節(jié)點
sqlMap節(jié)點指定了映射文件的位置,配置中可出現(xiàn)多個sqlMap節(jié)點,以指定
項目內(nèi)所包含的所有映射文件。
ibatis基礎(chǔ)語義
XmlSqlMapClientBuilder
XmlSqlMapClientBuilder是ibatis 2.0之后版本新引入的組件,用以替代1.x
版本中的XmlSqlMapBuilder。其作用是根據(jù)配置文件創(chuàng)建SqlMapClient實例。
?
SqlMapClient
SqlMapClient是ibatis的核心組件,提供數(shù)據(jù)操作的基礎(chǔ)平臺。SqlMapClient
可通過XmlSqlMapClientBuilder創(chuàng)建:?
?
String?resource?
=
"
com/ibatis/sample/SqlMapConfig.xml
"
;?
Reader?reader;?
?
reader?
=
?Resources.getResourceAsReader(resource);?
?
XmlSqlMapClientBuilder?xmlBuilder?
=
??
new
?XmlSqlMapClientBuilder();?
?
SqlMapClient?sqlMap?
=
?xmlBuilder.buildSqlMap(reader);?
"com/ibatis/sample/SqlMapConfig.xml"指明了配置文件在CLASSPATH
中的相對路徑。XmlSqlMapClientBuilder通過接受一個Reader類型的配置文
件句柄,根據(jù)配置參數(shù),創(chuàng)建SqlMapClient實例。
?
SqlMapClient提供了眾多數(shù)據(jù)操作方法,下面是一些常用方法的示例,具體說明
文檔請參見ibatis java doc,或者ibatis官方開發(fā)手冊。
SqlMapClient基本操作示例
以下示例摘自ibatis官方開發(fā)手冊,筆者對其進行了重新排版以獲得更好的閱讀效果。
例1: 數(shù)據(jù)寫入操作(insert, update, delete):
sqlMap.startTransaction();?
Product?product?
=
?
new
?Product();?
product.setId?(
1
);?
product.setDescription?(“Shih?Tzu”);?
int
?rows?
=
?sqlMap.insert?(“insertProduct”,?product);?
sqlMap.commitTransaction();?
例2: 數(shù)據(jù)查詢 (select)
sqlMap.startTransaction();?
Integer?key?
=
?
new
?Integer?(
1
);?
Product?product?
=
?(Product)sqlMap.queryForObject?
(“getProduct”,?key);?
sqlMap.commitTransaction();?
例3: 在指定對象中存放查詢結(jié)果(select)?
sqlMap.startTransaction();?
Customer?customer?
=
?
new
?Customer();?
sqlMap.queryForObject(“getCust”,?parameterObject,?customer);?
sqlMap.queryForObject(“getAddr”,?parameterObject,?customer);?
sqlMap.commitTransaction();?
例4: 執(zhí)行批量查詢 (select)
sqlMap.startTransaction();?
List?list?
=
?sqlMap.queryForList?(“getProductList”,?
null
)
sqlMap.commitTransaction();?
例5: 關(guān)于AutoCommit
//
沒有預(yù)先執(zhí)行startTransaction時,默認為auto_commit模式?
int
?rows?
=
?sqlMap.insert?(“insertProduct”,?product);?
例6:查詢指定范圍內(nèi)的數(shù)據(jù)
sqlMap.startTransaction();?
List?list?
=
?sqlMap.queryForList?(“getProductList”,?
null
,?
0
,?
40
);?
sqlMap.commitTransaction();?
例7: 結(jié)合RowHandler進行查詢(select)
public
?
class
?MyRowHandler?
implements
?RowHandler?
{?
???
public
?
void
?handleRow?(Object?object,?List?list)?
throws
?

????SQLException?
{?
??????Product?product?
=
?(Product)?object;?
??????product.setQuantity?(
10000
);?
??????sqlMap.update?(“updateProduct”,?product);?
????}
?
}
?
sqlMap.startTransaction();?
RowHandler?rowHandler?
=
?
new
?MyRowHandler();?
List?list?
=
?sqlMap.queryForList?(“getProductList”,?
null
,?
rowHandler);?
sqlMap.commitTransaction();?
?
//
例8:?分頁查詢?(select)?
PaginatedList?list?
=
?
sqlMap.queryForPaginatedList?(“getProductList”,?
null
,?
10
);?
list.nextPage();?
list.previousPage();?
?
?
//
例9:?基于Map的批量查詢?(select)?
sqlMap.startTransaction();?
Map?map?
=
?sqlMap.queryForMap?(“getProductList”,?
null
,?
“productCode”);?
sqlMap.commitTransaction();?
Product?p?
=
?(Product)?map.get(“EST
-
93
”);?
?