ibatis介紹以及用例

ptjs 12年前發布 | 1K 次閱讀 5.2.1版本發布

介紹

iBATIS是以SQL為中心的持久化層框架。能支持懶加載、關聯查詢、繼承等特性。

iBATIS不同于一般的OR映射框架(eg:hibernate)OR映射框架,將數據庫表、字段等映射到類、屬性,那是一種元數據(meta-data)映射。iBATIS則是將SQL查詢的參數和結果集映射到類。因此可以說,iBATIS做的是SQL Mapping的工作。它把SQL語句看成輸入以及輸出,結果集就是輸出,而where后面的條件參數則是輸入。iBATIS能將輸入的普通POJO對象、MapXML等映射到SQL的條件參數上,同時也可以將查詢結果映射到普通POJO對象(集合)、MapXML等上面。

iBATIS使用xml文件來映射這些輸入以及輸出。能大大減少數據庫存儲部分的代碼量,而且可以非常方便的利用SQL中的一些小技巧。

簡單示例

基于ibatis-2.3.0.677版本。

1 創建新的項目,并引入jar

a)         ibatis-2.3.0.677.jar

b)        mysql驅動

2 在類路徑中(classes下)提供ibatis的配置文件:sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     

    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     

    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

 <transactionManager type="JDBC" commitRequired="false">

    <dataSource type="SIMPLE">

      <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>

      <property name="JDBC.ConnectionURL"value="jdbc:mysql://127.0.0.1/ibatis"/>

      <property name="JDBC.Username" value="root"/>

      <property name="JDBC.Password" value="mysql"/>

    </dataSource>

 </transactionManager>

 <sqlMap resource="com/ibatis/model/User.xml"/>

</sqlMapConfig>

3、創建實體類:User.java

package com.ibatis.model;

publicclass User {

    privateintid;

    private String username;

    private String password;

   

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getPassword() {

       returnpassword;

    }

    publicvoid setPassword(String password) {

       this.password = password;

    }

    public String getUsername() {

       returnusername;

    }

    publicvoid setUsername(String username) {

       this.username = username;

    }

}

4、創建針對User對象的CRUDxml映射配置:User.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     

    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     

    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="User">

 <!-- Use type aliases to avoid typing the full classname every time. -->

 <typeAlias alias="User" type="com.ibatis.model.User"/>

 <!-- Select with no parameters using the result map for Account class. -->

 <select id="selectAllUsers" resultClass="User">

    select * from t_user

 </select>

 

 <select id="selectUser" resultClass="User" parameterClass="int">

  select * from t_user where id=#id#

 </select>

 

 <insert id="insertUser" parameterClass="User">

  insert into t_user values (

       null,#username#,#password#

  )

 </insert>

 

 <update id="updateUser" parameterClass="User">

  update t_user set username = #username#,password=#password#

  where id=#id#

 </update>

 

 <delete id="deleteUser" parameterClass="int">

  delete from t_user where id=#id#

 </delete>

</sqlMap>

5、創建測試程序測試:

package com.crm.model;

import java.io.Reader;

import java.util.Iterator;

import java.util.List;

import com.ibatis.common.resources.Resources;

import com.ibatis.sqlmap.client.SqlMapClient;

import com.ibatis.sqlmap.client.SqlMapClientBuilder;

/**

 *最簡單的形式!

 *@authorq

 *

 */

publicclass UserTest {

    /**

     *@paramargs

     */

    publicstaticvoid main(String[] args) throws Exception{

       //從配置文件中得到SqlMapClient對象

       Reader reader = Resources.getResourceAsReader("sqlMapConfig.xml");

       SqlMapClient sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

       reader.close();

      

       //創建用戶數據

       for(int i=0; i<10; i++){

           User user = new User();

           user.setUsername("用戶"+i);

           user.setPassword("密碼"+i);

           sqlMapper.insert("insertUser", user);

       }

      

       //查詢用戶數據

       List users = sqlMapper.queryForList("selectAllUsers");

       for (Iterator iter = users.iterator(); iter.hasNext();) {

           User user = (User) iter.next();

           System.out.println(user.getUsername());

       }

      

       //查詢特定用戶的數據

       User user = (User)sqlMapper.queryForObject("selectUser", 1);

       System.out.println("用戶【id="+1+"】的名稱是:"+user.getUsername());

      

       //更新用戶的信息

       user = new User();

       user.setId(3);

       user.setUsername("更改之后的用戶名稱");

       user.setPassword("密碼被更改");

       sqlMapper.update("updateUser", user);

      

       //刪除用戶的信息

       sqlMapper.delete("deleteUser", 6);

    }

}

 

SqlMapClient對象

這個對象是iBatis操作數據庫的接口(執行CRUD等操作),它也可以執行事務管理等操作。這個類是我們使用iBATIS的最主要的類。它是線程安全的。通常,將它定義為單例。(與hibernatesessionFactory的定義類似)。如:

import java.io.Reader;

import com.ibatis.common.resources.Resources;

import com.ibatis.sqlmap.client.SqlMapClient;

import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class IbatisSQLMapConfig {

    private static final SqlMapClient sqlMap;

    //在靜態區塊中初試化返回

    static {

        try {

            //聲明配置文件的名稱(映射文件被定義在其中)

            String resource = "sql_map_config.xml";

            //利用工具類Resources來讀取到配置文件

            Reader reader = Resources.getResourceAsReader(resource);

            //創建SqlMapClient接口的變量實例

            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

        } catch (Exception e) {

            e.printStackTrace();

            throw new RuntimeException(

                    "Error initializing MyAppSqlConfig class. Cause: " + e);

        }

    }

    public static SqlMapClient getSqlMapInstance() {

        //提供靜態方法返回靜態區塊中得到的SqlMapClient

        return sqlMap;

    }

}

主要用法:

如何獲得剛插入記錄的自增長ID值?

以下所有虛線上面代表User.xml中的內容,虛線下方是測試類中的內容:User類沿用上一篇中的User

 <insert id="insertUser" parameterClass="User">

  insert into t_user values (

       null,#username#,#password#

  )

  <selectKey resultClass="int" keyProperty="id">

       SELECT @@IDENTITY AS ID

  </selectKey> 

 </insert>

       User user = new User();

       user.setUsername("張三");

       user.setPassword("張三密碼");

      

       //如果主鍵是自動生成的,則其返回值可以通過<selectKey>標簽來設置

       //如果不通過<selectKey>標簽來設置,則返回值為空!

       //<selectKey >中的keyProperty,是指定User中的id屬性,當調用結束之后,

       //user對象的id值和insert方法的返回值都是這條記錄的ID值!

       Object obj = sqlMapper.insert("insertUser", user);

parameterClass的使用

 <insert id="insertUser" parameterClass="User">

  insert into t_user values (

       null,#username#,#password#

  )

  <selectKey resultClass="int" keyProperty="id">

       SELECT @@IDENTITY AS ID

  </selectKey> 

 </insert>

 

 <insert id="insertUser2">

  insert into t_user values (

       null,#username#,#password#

  )

  <selectKey resultClass="int" keyProperty="id">

       SELECT @@IDENTITY AS ID

  </selectKey> 

 </insert>

insertUser使用了parameterClass,所以必需傳入User類型的對象

       User user = new User();

       user.setUsername("張三");

       user.setPassword("張三密碼");

      

       //傳遞進去的對象,必須是User類型

       Object obj = sqlMapper.insert("insertUser", user);

insertUser2沒有使用parameterClass,所以可以傳入任意具有相應屬性值的對象

       JustAnObject anobj = new JustAnObject();

       anobj.setUsername("用戶名");

       anobj.setPassword("用戶密碼");

      

       //如果沒有指定parameterClass屬性,則任何一個具有相應屬性值

       //的對象都可以被傳遞進去

       Object obj = sqlMapper.insert("insertUser2", anobj);

parameterMap的使用

 <parameterMap class="User" id="insertUser-param">

  <parameter property="username"/>

  <parameter property="password"/>

 </parameterMap>

 <insert id="insertUser" parameterMap="insertUser-param">

  insert into t_user values (

       null,?,?

  )

  <selectKey resultClass="int" keyProperty="id">

       SELECT @@IDENTITY AS ID

  </selectKey> 

 </insert>

parameterMap用于傳入參數,以便匹配SQL語句中的?

       User user = new User();

       user.setUsername("張三dd");

       user.setPassword("張三密碼dd");

      

       Object obj = sqlMapper.insert("insertUser", user);

利用parameterMap,可以定義參數對象的屬性如何映射到SQL查詢語句的動態參數上,注意parameterMap<parameter/>標簽的先后順序不能顛倒!

如何將查詢結果映射到不同的對象?(resultClass的使用)

package com.ibatis.model;

publicclassOtherObject {

    privateintid;

    private String prop1;

    private String prop2;

   

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getProp1() {

       return Prop1;

    }

    publicvoid set Prop1 (String Prop1) {

       this. Prop1 = Prop1;

    }

    public String getProp2() {

       returnusername;

    }

    publicvoid setProp2 (String Prop2) {

       this.Prop2 = Prop2;

    }

}

 <select id="selectUserForOtherObject" resultClass="com. ibatis.OtherObject" parameterClass="int">

  select

  username as prop1,

  password as prop2

  from t_user where id=#value#

 </select>

       //查找t_user表,將其結果映射到一個屬性名不同的對象中!

       OtherObject obj = (OtherObject)sqlMapper.queryForObject("selectUserForOtherObject", 1);

       System.out.println(obj.getProp1()+","+obj.getProp2());

如何將查詢結果集映射到不同的對象?(resultMap的基本使用)

 <resultMap class="com.ibatis.model.OtherObject" id="ooResult">

  <result property="prop1" column="username"/>

  <result property="prop2" column="password"/>

 </resultMap>

 <!--

 如果使用resultMap來定義如何映射,則如下語句不可寫成:

 select username as prop1,password as prop2 ....

 -->

 <select id="selectUserForOtherObject2" parameterClass="int"resultMap="ooResult">

      select

      username,

      password

      from t_user where id=#value#

 </select>

       //查找t_user表,將其結果映射到一個屬性名不同的對象中!

       OtherObject obj = (OtherObject)sqlMapper.queryForObject("selectUserForOtherObject2", 17);

       System.out.println(obj.getProp1()+","+obj.getProp2());

如何將查詢結果集映射為xml格式的數據?

 <select id="selectXmlData" resultClass="xml" xmlResultName="User"parameterClass="int">

  select * from t_user where id=#value#

 </select>

 <select id="selectXmlDatas" resultClass="xml" xmlResultName="User">

  select * from t_user

 </select>

       //查找t_user表,將其結果映射到xml

       //返回值是xml形式的字符串

       Object obj = (Object)sqlMapper.queryForObject("selectXmlData", 1);

       System.out.println(obj);

       //查找t_user表,將其結果映射到xml

       List list  = (List)sqlMapper.queryForList("selectXmlDatas");

       System.out.println(list);

如何用Map類型的對象作為傳入參數

 <!--

 這里,可以使用全路徑類名,如:

 java.util.Map

 java.util.HashMap

 java.util.TreeMap

 

 map

 -->

 <insert id="insertUser" parameterClass="map">

  insert into t_user values (

       null,#username#,#password#

  )

 </insert>

       Map user = new TreeMap();

       user.put("username""Map用戶");

       user.put("password""Map用戶密碼");

       sqlMapper.insert("insertUser",user);

如何將查詢結果集的元素轉換為Map類型的對象?

 <!--

 resultClass可以定義為java.util.HashMap類型,

 將能自動轉換

 -->

 <select id="selectMapUsers" resultClass="java.util.HashMap">

  select * from t_user

 </select>

       List list = (List)sqlMapper.queryForList("selectMapUsers");

       System.out.println(list);

       for (Iterator iter = list.iterator(); iter.hasNext();) {

           Map map = (Map) iter.next();

           //可在此輸出map的數據

       }

事務處理

可以使用sqlMapClientstartTransaction/commitTransaction/endTransaction等方法來控制事務的邊界。

如果與spring整合(這是iBatis推薦的方式),則我們需要在spring配置文件中指定其事務特性。

Spring通過DAO模式,提供了對iBATIS的良好支持。SqlMapClient對象是iBATIS中的主要對象,我們可以通過配置讓spring來管理SqlMapClient對象的創建。

hibernate類似,Spring 提供了SqlMapClientDaoSupport對象,我們的DAO可以繼承這個類,通過它所提供的SqlMapClientTemplate對象來操縱數據庫。看起來這些概念都與hibernate類似。

通過SqlMapClientTemplate來操縱數據庫的CRUD是沒有問題的,這里面關鍵的問題是事務處理。Spring提供了強大的聲明式事務處理的功能,我們已經清楚hibernate中如何配置聲明式的事務,那么在iBATIS中如何獲得聲明式事務的能力呢?

第一,我們需要了解的是spring通過AOP來攔截方法的調用,從而在這些方法上面添加聲明式事務處理的能力。典型配置如下:applicationContext-common.xml

    <!-- 配置事務特性 -->

    <tx:advice id="txAdvice" transaction-manager="事務管理器名稱">

        <tx:attributes>

           <tx:method name="add*" propagation="REQUIRED"/>

           <tx:method name="del*" propagation="REQUIRED"/>

           <tx:method name="update*" propagation="REQUIRED"/>

           <tx:method name="*" read-only="true"/>

       </tx:attributes>

    </tx:advice>

   

    <!-- 配置哪些類的方法需要進行事務管理 -->

    <aop:config>

       <aop:pointcut id="allManagerMethod" expression="execution(* com.ibatis.manager.*.*(..))"/>

       <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>

    </aop:config>

這些事務都是聲明在業務邏輯層的對象上的。

第二,我們需要一個事務管理器,對事務進行管理。

    <bean id="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="dataSource"/>

    </bean>

    <bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

        <property name="url" value="jdbc:mysql://127.0.0.1/ibatis"/>

        <property name="username" value="root"/>

        <property name="password" value="mysql"/>

    </bean>

此后,我們需要讓spring來管理SqlMapClient對象:

    <bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

       <property name="configLocation"><value>classpath:sqlMapConfig.xml</value></property>

    </bean>

我們的sqlMapConfig.xml就可以簡寫為:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     

    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     

    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

    <settings

       lazyLoadingEnabled="true"

        useStatementNamespaces="true" />

    <!-- 使用spring之后,數據源的配置移植到了spring上,所以iBATIS本身的配置可以取消 -->

  <sqlMap resource="com/ibatis/dao/impl/ibatis/User.xml"/>

</sqlMapConfig>

User.xml:如下

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     

    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     

    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="User">

 <!-- Use type aliases to avoid typing the full classname every time. -->

 <typeAlias alias="User" type="com.ibatis.User"/>

 <!-- Select with no parameters using the result map for Account class. -->

 <select id="selectAllUsers" resultClass="User">

    select * from t_user

 </select>

 

 <select id="selectUser" resultClass="User" parameterClass="int">

  select * from t_user where id=#id#

 </select>

 

 <insert id="insertUser" parameterClass="User">

  insert into t_user values (

       null,#username#,#password#

  )

 </insert>

 

 <update id="updateUser" parameterClass="User">

  update t_user set username = #username#,password=#password#

  where id=#id#

  </update>

 

 <delete id="deleteUser" parameterClass="int">

  delete from t_user where id=#id#

 </delete>

</sqlMap>

我們的DAO的編寫:

package com.iabtis.dao.impl.ibatis;

import java.util.List;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.dao.UserDAO;

import com.ibatis.crm.model.User;

public class UserDAOImpl extends SqlMapClientDaoSupport implements UserDAO {

    public User select(User user) {

            return  getSqlMapClientTemplate().querForObject("selectUser ",user.getId());

       }

   public List findAll() {

              return getSqlMapClientTemplate().queryForList("selectAllUsers ");

       }

       public void delete(User user) {

              getSqlMapClientTemplate().delete("deleteUser ",user.getId());

       }

       public void save(User user) {

              getSqlMapClientTemplate().insert("insertUser ",user);

       }

       public void update(User user) {

              getSqlMapClientTemplate().update("updateUser ",user);

       }

}

繼承SqlMapClientDaoSupport,要求我們注入SqlMapClient對象,因此,需要有如下的DAO配置:

<bean id="userDAO" class="com.ibatils.dao.impl.ibatis.UserDAOImpl">

     <property name=”sqlMapClient” ref=”sqlMapClient”/>

</bean>

這就是所有需要注意的問題了,此后就可以在業務邏輯層調用DAO對象了!

 原文連接http://www.blogjava.net/freeman1984/

 本文由用戶 ptjs 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!