Ibatis使用实践 - 2

  Ibatis中可以将pojo中的实体的属性对应于数据库里面的字段, 可以通过显示或隐式的方式进行指定。
 
1、pojo类: Account.java

public class Account {
   private int userid;
   private String username;
   private String password;
   private String groupname;
  
   public int getUserid() {
     return userid;
  }
   public void setUserid( int userid) {
     this.userid = userid;
  }
   public String getUsername() {
     return username;
  }
   public void setUsername(String username) {
     this.username = username;
  }
   public String getPassword() {
     return password;
  }
   public void setPassword(String password) {
     this.password = password;
  }
   public String getGroupname() {
     return groupname;
  }
   public void setGroupname(String groupname) {
     this.groupname = groupname;
  }
  
}
2、userAccount.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 >

   < select id ="getAllUsers" resultClass ="com.air.Account" >
    SELECT * FROM USER_ACCOUNT order by USERID
   </ select >


  <!--   无映射    -->
   < select id ="getAllUsers1" resultClass ="com.air.Account"
     parameterClass ="string" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

  <!--   内联映射->实体类  -->
   < select id ="getAllUsers2" resultClass ="com.air.Account"
     parameterClass ="string" >
    SELECT USERID as userid, USERNAME as username, PASSWORD as
    password, GROUPNAME as groupname FROM USER_ACCOUNT WHERE
    GROUPNAME=#groupName#
   </ select >

  <!--   内联映射->MAP类  -->
   < select id ="getAllUsers3" resultClass ="hashmap"
     parameterClass ="string" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

  <!--   显示映射->实体类  -->
   < resultMap id ="accoutResult" class ="com.air.Account" >
     < result property ="userid" column ="USERID" />
     < result property ="username" column ="USERNAME" />
     < result property ="password" column ="PASSWORD" />
     < result property ="groupname" column ="GROUPNAME" />
   </ resultMap >
   < select id ="getAllUsers4" resultMap ="accoutResult"
     parameterClass ="string" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

  <!--   显示映射->MAP类  -->
   < resultMap id ="mapResult" class ="hashmap" >
     < result property ="userid" column ="USERID" />
     < result property ="username" column ="USERNAME" />
     < result property ="password" column ="PASSWORD" />
     < result property ="groupname" column ="GROUPNAME" />
   </ resultMap >
   < select id ="getAllUsers5" resultMap ="mapResult"
     parameterClass ="string" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

  <!--   XML  -->
   < select id ="selectXML" parameterClass ="string" resultClass ="xml"
     xmlResultName ="log" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

   < select id ="getOneUser" resultClass ="com.air.Account"
     parameterClass ="string" >
    SELECT * FROM USER_ACCOUNT WHERE GROUPNAME=#groupName#
   </ select >

  <!--   自动参数映射  -->  
   < insert id ="insertOneUser1" parameterClass ="com.air.Account" >
    INSERT INTO USER_ACCOUNT
    (
      USERNAME, PASSWORD, GROUPNAME
    )VALUES(
      #username#,#password#,#groupname#
    )
   </ insert >

  <!--   内联参数映射  -->  
   < insert id ="insertOneUser2" parameterClass ="com.air.Account" >
    INSERT INTO USER_ACCOUNT
    (
      USERNAME, PASSWORD, GROUPNAME
    )VALUES(
      #username:VARCHAR#,
      #password:VARCHAR#,
      #groupname:VARCHAR#
    )
   </ insert >

  <!--   外联参数映射  -->  
   < parameterMap     id ="parameterMapEx" class ="com.air.Account" >
     < parameter property ="username" jdbcType ="VARCHAR" />
     < parameter property ="password" jdbcType ="VARCHAR" />
     < parameter property ="groupname" jdbcType ="VARCHAR" />
   </ parameterMap >
   < insert id ="insertOneUser3" parameterMap ="parameterMapEx" >
    INSERT INTO USER_ACCOUNT
    (
      USERNAME, PASSWORD, GROUPNAME
    )VALUES(
      ?,?,?
    )
   </ insert >
  
  <!--   自动生成的键  -->  
   < insert id ="insertOneUser4" parameterClass ="com.air.Account" >
    INSERT INTO USER_ACCOUNT
    (
      USERID,USERNAME, PASSWORD, GROUPNAME
    )VALUES(
      #userid#,
      #username#,
      #password#,
      #groupname#    
    )
     < selectKey  
       keyProperty ="userid"
       resultClass ="int" >
      SELECT LAST_INSERT_ID()      
     </ selectKey >
   </ insert >  

  <!--   存储过程  -->    
   < parameterMap id ="pro" class ="java.util.Map" >
     < parameter property ="name" jdbcType ="VARCHAR"
             javaType ="string" mode ="IN" />
   </ parameterMap >
   < procedure id ="pro_insert" parameterMap ="pro" >
    {call new_proc(?)}
   </ procedure >
  
</ sqlMap >
全局文件: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 >
  
   < properties resource ="sqlmap.properties" />
  
     < transactionManager type ="JDBC" >
         < dataSource type ="SIMPLE" >
             < property value ="${driver}" name ="JDBC.Driver" />
             < property value ="${url}" name ="JDBC.ConnectionURL" />
             < property value ="${username}" name ="JDBC.Username" />
             < property value ="${password}" name ="JDBC.Password" />
         </ dataSource >
     </ transactionManager >

     < sqlMap resource ="userAccount.xml" />
     < sqlMap resource ="Dynamic.xml" />

</ sqlMapConfig >
。。。。待续

3、cacheModel

cacheModel的属性值等于指定的cacheModel元素的name属性值。属性cacheModel定义查询mapped statement的缓存。每一个查询mapped statement可以使用不同或相同的cacheModel。
 
   
  1. <cacheModel id="product-cache" imlementation="LRU"> 
  2. <flushInterval hours="24"/> 
  3. <flushOnExecute statement="insertProduct"/> 
  4. <flushOnExecute statement="updateProduct"/> 
  5. <flushOnExecute statement="deleteProduct"/> 
  6. <property name=”size” value=”1000” /> 
  7. </cacheModel> 
  8.  
  9. <statement id=”getProductList” parameterClass=”int” cacheModel=”product-cache> 
  10. select * from PRODUCT where PRD_CAT_ID = #value# 
  11. </statement> 

4、事务处理

    缺省情况下,调用SqlMapClient对象的任意executeXxxx()方法将缺省地自动COMMIT/ROLLBACK。这意味着每次调用executeXxxx()方法都是一个独立的事务。这确实很简单,但对于需要在同一个事务中执行多个语句的情况(即只能同时成功或失败),并不适用。这正是事务处理要关心的事情。
    如果您在使用Global Transaction(在SQL Map配置文件中设置),您可以使用自动提交并且可以得到在同一事务中执行的效果。但为了提高性能,最好是明确地划分事务的范围,因为这样做可以减少连接池的通讯流量和数据库连接的初始化。
   SqlMapClient对象拥有让您定义事务范围的方法。使用下面SqlMapClient类的方法,可以开始、提交和/或回退事务:
public void startTransaction () throws SQLException
public void commitTransaction () throws SQLException
public void endTransaction () throws SQLException
开始一个事务,意味着您从连接池中得到一个连接,打开它并执行查询和更新SQL操作。
 
 
  
  1. public updateItemDescription (String itemId, String newDescription) throws SQLException { 
  2. try { 
  3. sqlMap.startTransaction (); 
  4. Item item = (Item) sqlMap.queryForObject ("getItem", itemId); 
  5. item.setDescription (newDescription); 
  6. sqlMap.update ("updateItem", item); 
  7. sqlMap.commitTransaction (); 
  8. finally { 
  9. sqlMap.endTransaction (); 
注意!事务不能嵌套。在调用commit()或rollback()之前,从同一线程多次调用.startTransaction,将引起抛出例外。换句话说,对于每个SqlMap实例,每个线程最多只能打开一个事务。
注意!SqlMapClient事务处理使用Java的 ThreadLocal保存事务对象。这意味着在处理事务时,每个调用startTransaction()的线程,将得到一个唯一的Connection对象。 将一个Connection对象返回数据源(或关闭连接)唯一的方法是调用commitTransaction()或rollbackTransaction()方法。否则,会用光连接池中的连接并导致死锁。