ibatis學習(一)--ibatis介紹以及用例 [轉]

介紹java

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

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

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

簡單示例數據庫

基於ibatis-2.3.0.677版本。express

1 建立新的項目,並引入jarapache

a)         ibatis-2.3.0.677.jar安全

b)        mysql驅動session

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

<?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/

相關文章
相關標籤/搜索