作者:夏昕 xiaxin(at)gmail.com
ibatis基礎代碼包括:?
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 節點?
cacheModelsEnabled?
是否啟用SqlMapClient上的緩存機制。 建議設為"true"
enhancementEnabled?
是否針對POJO啟用字節碼增強機getter/setter的調用效能,避免Reflect所帶來的性能開銷。同時,這也為Lazy Loading帶來提升。 建議設為"true"
errorTracingEnabled?
是否啟用錯誤日志,在開發期間建議設為"true" 以方便調試
lazyLoadingEnabled?
是否啟用延遲加載機制,建議設為"true"
maxRequests?
最大并發請求數(Statement并發數)
maxTransactions?
最大并發事務數
maxSessions? 最大Session數。即當前最大允許的并發SqlMapClient數。?
?
useStatementNamespaces?
是否使用Statement命名空間。
這里的命名空間指的是映射文件中,sqlMap節的namespace屬性,如在上例中針對t_use
表的映射文件sqlMap節點: <sqlMap namespace="User"> 這里,指定了此sqlMap節點下定義的操作均屬于"User"命名空間。 在useStatementNamespaces="true"的情況下,Statement調用需追加命名空間,如:sqlMap.update("User.updateUser",user);
否則直接通過Statement名稱調用即可,如: sqlMap.update("updateUser",user); 但請注意此時需要保證所有映射文件中,Statement定義無重名。
transactionManager節點
transactionManager節點定義了ibatis的事務管理器,目前提供了以下幾
種選擇:
? JDBC
通過傳統JDBC Connection.commit/rollback實現事務支持。??
JTA
使用容器提供的JTA服務實現全局事務管理。
?? EXTERNAL
外部事務管理,如在EJB中使用ibatis,通過EJB的部署配置即可實現自
動的事務管理機制。此時ibatis將把所有事務委托給外部容器進行管理。
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.JndiDataSourceFactory。
?
?dataSource的子節點說明(SIMPLE&DBCP):
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.MaximumActiveConnections?
數據庫連接池可維持的最大容量。
Pool.MaximumIdleConnections?
數據庫連接池中允許的掛起(idle)連接數。
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
>
?
?sqlMap節點
sqlMap節點指定了映射文件的位置,配置中可出現多個sqlMap節點,以指定
項目內所包含的所有映射文件。
ibatis基礎語義
XmlSqlMapClientBuilder
XmlSqlMapClientBuilder是ibatis 2.0之后版本新引入的組件,用以替代1.x
版本中的XmlSqlMapBuilder。其作用是根據配置文件創建SqlMapClient實例。
?
SqlMapClient
SqlMapClient是ibatis的核心組件,提供數據操作的基礎平臺。SqlMapClient
可通過XmlSqlMapClientBuilder創建:?
?
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類型的配置文
件句柄,根據配置參數,創建SqlMapClient實例。
?
SqlMapClient提供了眾多數據操作方法,下面是一些常用方法的示例,具體說明
文檔請參見ibatis java doc,或者ibatis官方開發手冊。
SqlMapClient基本操作示例
以下示例摘自ibatis官方開發手冊,筆者對其進行了重新排版以獲得更好的閱讀效果。
例1: 數據寫入操作(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: 數據查詢 (select)
sqlMap.startTransaction();?
Integer?key?
=
?
new
?Integer?(
1
);?
Product?product?
=
?(Product)sqlMap.queryForObject?
(“getProduct”,?key);?
sqlMap.commitTransaction();?
例3: 在指定對象中存放查詢結果(select)?
sqlMap.startTransaction();?
Customer?customer?
=
?
new
?Customer();?
sqlMap.queryForObject(“getCust”,?parameterObject,?customer);?
sqlMap.queryForObject(“getAddr”,?parameterObject,?customer);?
sqlMap.commitTransaction();?
例4: 執行批量查詢 (select)
sqlMap.startTransaction();?
List?list?
=
?sqlMap.queryForList?(“getProductList”,?
null
)
sqlMap.commitTransaction();?
例5: 關于AutoCommit
//
沒有預先執行startTransaction時,默認為auto_commit模式?
int
?rows?
=
?sqlMap.insert?(“insertProduct”,?product);?
例6:查詢指定范圍內的數據
sqlMap.startTransaction();?
List?list?
=
?sqlMap.queryForList?(“getProductList”,?
null
,?
0
,?
40
);?
sqlMap.commitTransaction();?
例7: 結合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
”);?
?