關於ibatis的介紹、優缺點,以及ibatis和hibernate的比較再此不在贅述,可參閱其他資料。
一、準備工作
1、下載ibatis軟件包http://download.csdn.net/detail/itmyhome/7473661
所需jar包爲:ibatis-xxx.jar,mysql-connector-java-xxx-bin.jar
2、創建測試數據庫,並新建user表,其中包含三個字段:
id(int)
name(varchar)
age(int)
ps:以mysql數據庫爲例
- create table user(
- id int,
- name varchar(50),
- age int
- );
二、構建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">
- <dataSource type="SIMPLE">
- <property name="JDBC.Driver" value="com.mysql.jdbc.Driver" />
- <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost:3306/ibatis" />
- <property name="JDBC.Username" value="root" />
- <property name="JDBC.Password" value="root" />
- <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/itmyhome/User.xml" />
- </sqlMapConfig>
ibatis配置文件各節點簡單說明:
(1)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屬性,如在上例中針對user 表的映射文件sqlMap節點: <sqlMap namespace="User"> 這裏,指定了此sqlMap節點下定義的操作均從 屬於"User"命名空間。 在useStatementNamespaces="true"的情況下, Statement調用需追加命名空間,如: sqlMap.update("User.updateUser",user); 否則直接通過Statement名稱調用即可,如: sqlMap.update("updateUser",user); 但請注意此時需要保證所有映射文件中, Statement定義無重名 |
(2)transactionManager節點
transactionManager節點定義了ibatis的事務管理器,目前提供了以下幾種選擇:
1) JDBC
通過傳統 JDBC Connection.commit/rollback實現事務支持。
2) JTA
使用容器提供的JTA服務實現全局事務管理。
3) EXTERNAL
外部事務管理,如在EJB中使用ibatis,通過EJB的部署配置即可實現自動的事務管理機制。
此時ibatis將把所有事務委託給外部容器進行管理。此外,通過Spring等輕量級容器實現事務的配置化管理也是一個不錯的選
擇。關於結合容器實現事務管理,參見“高級特性”中的描述。
(3)dataSource節點
dataSource從屬於transactionManager節點,用於設定ibatis運行期使用的DataSource屬性。
type屬性:dataSource節點的type屬性指定了dataSource的實現類型。
可選項目:
1) SIMPLE:
SIMPLE是ibatis內置的dataSource實現,其中實現了一個簡單的數據庫連接池機制,對應ibatis實現類爲
com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
3) DBCP:
基於Apache DBCP連接池組件實現的DataSource封裝,當無容器提
供DataSource服務時,建議使用該選項,對應ibatis實現類爲com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
3) JNDI:
使用J2EE容器提供的DataSource實現,DataSource將通過指定
的JNDI Name從容器中獲取.對應ibatis實現類爲com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
dataSource的子節點說明(SIMPLE&DBCP):
JDBC.Driver | JDBC驅動.如:com.mysql.jdbc.Driver |
JDBC.ConnectionURL | 數據庫URL。如:jdbc:mysql://localhost:3306/ibatis 如果用的是SQLServer JDBC Driver,需要 在url後追加SelectMethod=Cursor以獲得 JDBC事務的多Statement支持。 |
JDBC.Username | 數據庫用戶名 |
JDBC.Password | 數據庫用戶密碼 |
Pool.MaximumActiveConnections | 數據庫連接池可維持的最大容量。 |
Pool.MaximumIdleConnections | 數據庫連接池中允許的掛起(idle)連接數。 |
(4)sqlMap節點
sqlMap節點指定了映射文件的位置,配置中可出現多個sqlMap節點,以指定
項目內所包含的所有映射文件。
2、POJO
下面是我們用作示例的一個POJO
- public class User implements Serializable {
- private static final long serialVersionUID = 1L;
- private int id;
- private String name;
- private int age;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
3、映射文件
與Hibernate不同,因爲需要人工編寫sql代碼 ibatis的映射文件一般採用手動編寫
- <?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.itmyhome.User" />
- <!-- 查詢 -->
- <select id="getUser" parameterClass="java.lang.Integer" resultClass="user">
- <![CDATA[
- select name,age from user where id = #id#
- ]]>
- </select>
- <!-- 插入 -->
- <insert id="insertUser" parameterClass="user">
- insert into user values(#id#,#name#,#age#)
- </insert>
- <!-- 更新 -->
- <update id="updateUser"
- parameterClass="user">
- <![CDATA[
- update user
- SET name=#name#, age=#age#
- WHERE id = #id#
- ]]>
- </update>
- <!-- 刪除 -->
- <delete id="deleteUser" parameterClass="java.lang.Integer">
- delete from user where id = #id#
- </delete>
- </sqlMap>
<select>四個節點,我們分別定義了針對User對象的增刪改查操作。在這
四個節點中,我們指定了對應的SQL語句,以update節點爲例:
- <update id="updateUser" (1
- parameterClass="user"> (2
- <![CDATA[ (3
- update user (4
- SET name=#name#, age=#age# (5
- WHERE id = #id#
- ]]>
- </update>
指定了操作ID,之後我們可以在代碼中通過指定操作id來執行此節點所定義的操作,如:
sqlMap.update("updateUser",user);
ID設定使得在一個配置文件中定義兩個同名節點成爲可能(兩個update節點,以不同id區分)
⑵ parameterClass
指定了操作所需的參數類型,此例中update操作以
com.itmyhome.User 類型的對象作爲參數,目標是將提供的User實例更新到數據庫。
parameterClass="user"中,user爲"com.itmyhome.User"類的別名,別名可通過typeAlias節點指定,
如示例配置文件中的:<typeAlias alias="user" type="com.itmyhome.User"/>
⑶ <![CDATA[… ]]>
通過<![CDATA[… ]]>節點,可以避免SQL中與XML規範相沖突的字符對XML映射文件的合法性造成影響。
⑷執行更新操的SQL,這裏的SQL即實際數據庫支持的SQL語句,將由ibatis填入參數後交給數據庫執行。
⑸ SQL中所需的用戶名參數,"#name#"在運行期會由傳入的user對象的name屬性填充。(其他參數同)
對於這個示例,ibatis在運行期會讀取id爲"updateUser"的update節點
的SQL定義,並調用指定的user對象的對應getter方法獲取屬性值,並用此
屬性值,對SQL中的參數進行填充後提交數據庫執行。
好了,我們完成了所有的配置文件和映射文件,就剩下應用的編碼工作了。
首先要設置SQL Map,讀入剛創建好的SQL Map XML配置文件。爲簡化這個工作,可以使用
SQL Map架構中提供的Resources類。
- Stringresource ="SqlMapConfig.xml";
- Readerreader=Resources.getResourceAsReader(resource);
- SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
以上的SqlMapClient對象是線程安全,並且應持久生存。對於一個特定的應用,只需
進行一次SqlMap配置。因此,它可以作爲基類的一個靜態對象(即DAO對象的基類),或
者,如果您想讓它有更大的作用範圍,可以把它封裝在方便使用的類中。例如:
- public class MyAppSqlConfig {
- private static final SqlMapClient sqlMap;
- static {
- try {
- String resource = "SqlMapConfig.xml";
- Reader reader = Resources.getResourceAsReader(resource);
- sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException("Error initializing MyAppSqlConfig class. Cause: " + e);
- }
- }
- public static SqlMapClient getSqlMapInstance() {
- return sqlMap;
- }
- }
從數據庫讀取對象
既然SqlMap對象已完成初始化,那麼就可以方便地使用它了。首先我們用它
從數據庫中讀取一個User對象(本例中 先假設User表中一村莊N條記錄,id從i到N)
要從數據庫中得到一個User對象,只需要SqlMap實例,讓我們讀入id爲1的User對象
- SqlMapClient sqlMap = MyAppSqlConfig.getSqlMapInstance();
- User user = (User)sqlMap.queryForObject ("getUser", 1);
把對象寫入數據庫
- User u = new User();
- u.setId(2);
- u.setName("wangwu");
- u.setAge(23);
- sqlMap.insert("insertUser",u);
更新對象
- User u = new User();
- u.setId(3);
- u.setName("itmyhome");
- u.setAge(25);
- sqlMap.update("updateUser",u)
刪除對象
- sqlMap.delete("deleteUser", 1)
項目工程圖如下: