l 编程式的事务管理

    编程式的事务管理可以清楚地控制事务的边界,也就是让您自行实现事务开始时间、撤消操作的时机、结束时间等,可以实现细粒度的事务控制。

    l 声明式的事务管理

    然而多数的情况下,事务并不需要细粒度的控制,而是采用声明式的事务管理,好处是Spring事务管理的相关API可以不用介入程序之中,从对象的角度来看,它并不知道自己正被纳入事务管理之中,在不需要事务管理的时候,只要在设置文件上修改一下设置,即可移去事务管理服务。

    5.3.2 JDBC编程事务管理Spring提供两种方式实现编程式的事务管理,一是直接使用PlatformTransaction- Manager实现,二是使用org.springframework.transaction.support.Transaction- Template.

    先来看看如何使用PlatformTransactionManager,在这里使用它的实现类 DataSourceTransactionManager,可以改写一下之前5.2.1节中的JdbcTemplateDemo项目,让它具有事务管理功能,修改一下UserDAO类的insert() 方法来作示范:ProgrammaticTransactionDemo UserDAO.java

 

package onlyfun.caterpillar; 
  
import java.util.Iterator; 
  
import java.util.List; 
  
import java.util.Map; 
  
import javax.sql.DataSource; 
  
import org.springframework.dao.DataAccessException; 
  
import org.springframework.jdbc.core.JdbcTemplate; 
  
import org.springframework.jdbc. 
  
            datasource.DataSourceTransactionManager; 
  
import org.springframework.transaction.TransactionDefinition; 
  
import org.springframework.transaction.TransactionStatus; 
  
import org.springframework.transaction. 
  
            support.DefaultTransactionDefinition; 
  
public class UserDAO implements IUserDAO { 
  
    private DataSourceTransactionManager transactionManager; 
  
    private DefaultTransactionDefinition def; 
  
    private JdbcTemplate jdbcTemplate; 
  
       
  
    public void setDataSource(DataSource dataSource) { 
  
        jdbcTemplate = new JdbcTemplate(dataSource); 
  
        transactionManager = 
  
            new DataSourceTransactionManager(dataSource); 
  
        // 建立事务的定义 

  
        def = new DefaultTransactionDefinition(); 
  
        def.setPropagationBehavior( 
  
                TransactionDefinition.PROPAGATION_REQUIRED); 
  
    } 
  
       
  
    public void insert(User user) { 
  
       String name = user.getName(); 
  
       int age = user.getAge().intValue(); 
  
          
  
       TransactionStatus status = 
  
           transactionManager.getTransaction(def); 
  
       try { 
  
           jdbcTemplate.update("INSERT INTO user (name,age) " 
  
                   + "VALUES('" + name + "'," + age + ")"); 
  
           // 下面的SQL有错误,用以测试事务 

  
           jdbcTemplate.update("INSER INTO user (name,age) " 
  
                   + "VALUES('" + name + "'," + age + ")"); 
  
       } 
  
       catch(DataAccessException e) { 
  
           transactionManager.rollback(status); 
  
           throw e; 
  
       } 
  
       transactionManager.commit(status); 
  
    } 
  
    public User find(Integer id) { 
  
        List rows = jdbcTemplate.queryForList( 
  
          "SELECT * FROM user WHERE id=" + id.intValue()); 
  
           
  
        Iterator it = rows.iterator(); 
  
        if(it.hasNext()) { 
  
            Map userMap = (Map) it.next(); 
  
            Integer i = new Integer( 
  
                    userMap.get("id").toString()); 
  
            String name = userMap.get("name").toString(); 
  
            Integer age = new Integer( 
  
                    userMap.get("age").toString()); 
  
            User user = new User(); 
  
               
  
            user.setId(i); 
  
            user.setName(name); 
  
            user.setAge(age); 
  
               
  
            return user; 
  
        } 
  
        return null; 
  
    } 
  
}

 

 

 

 

在 insert()方法中使用了DataSourceTransactionManager来进行事务管理,如果发生了异常,则catch区块中会进行事务的Rollback,在insert() 方法中故意写入错误的SQL(注意INSERT方法少写了一个T),因此实际上数据并不会被储存至数据库中。

    要使用MySQL数据库进行事务处理,必须建立支持事务的表格类型,例如InnoDB的表格类型,这里用来建立表格的SQL如下所示:

 

CREATE TABLE user ( 
  
    id INT(11) NOT NULL auto_increment PRIMARY KEY, 
  
    name VARCHAR(100) NOT NULL default '', 
  
    age INT 
  
) TYPE = InnoDB;

 

    另一个实现编程式事务管理的方法是使用TransactionTemplate,它需要一个TransactionManager实例,如下所示:

 

TransactionTemplate transactionTemplate = 
  
        new TransactionTemplate(transactionManager); 
  
... 
  
transactionTemplate.execute(new TransactionCallback() { 
  
    public Object doInTransaction(TransactionStatus status) { 
  
         return jdbcTemplate.update("INSERT INTO user (name,age) " 
  
               + "VALUES('" + name + "'," + age + ")"); 
  
    } 
  
});

 

    如果发生了异常,则会进行Rollback,否则提交事务,如果没有回传值,则也可以使用TransactionCallbackWithoutResult:

 

transactionTemplate.execute( 
  
        new TransactionCallbackWithoutResult() { 
  
                public void doInTransactionWithoutResult( 
  
                                TransactionStatus status) { 
  
            . ... 
  
                } 
  
            });

 

    5.3.3 JDBC声明事务管理

    Spring声明式的事务管理依赖它的AOP框架来完成。使用声明事务管理的好处是,事务管理不能侵入您所开发的组件,具体来说,DAO对象不会意识到正在事务管理之中,事实上也应当如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策略的话,也只需要在定义文件中重新配置。

    举个例子来说,可以将5.2.1节中的JdbcTemplateDemo 项目修改一下,在不修改UserDAO类的情况下,可以为它加入事务管理的服务,一个简单的方法是使用 TransactionProxyFactoryBean,指定要介入的事务管理对象及其方法,这需要在定义文件中修改,如下所示:

    DeclarativeTransactionDemo beans-config.xml

 

<?xml version="1.0" encoding="UTF-8"?> 
  
<beans xmlns="http://www.springframework.org/schema/beans" 
  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">   
     
  
    <bean id="dataSource" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DriverManagerDataSource" 
  
          destroy-method="close"> 
  
        <property name="driverClassName" 
  
                  value="com.mysql.jdbc.Driver"/> 
  
        <property name="url" 
  
                  value="jdbc:mysql://localhost:3306/demo"/> 
  
        <property name="username" value="caterpillar"/> 
  
        <property name="password" value="123456"/> 
  
    </bean> 
  
       
  
    <bean id="transactionManager" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DataSourceTransactionManager"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAO" 
  
          class="onlyfun.caterpillar.UserDAO"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAOProxy" 
  
          class="org.springframework.transaction. 
  
                   → interceptor.TransactionProxyFactoryBean"> 
  
        <property name="proxyInterfaces"> 
  
            <list> 
  
                <value>onlyfun.caterpillar.IUserDAO</value> 
  
            </list> 
  
        </property> 
  
        <property name="target" ref="userDAO"/> 
  
        <property name="transactionManager" 
  
                  ref="transactionManager"/> 
  
        <property name="transactionAttributes"> 
  
            <props> 
  
                <prop key="insert*">PROPAGATION_REQUIRED</prop> 
  
            </props> 
  
        </property> 
  
    </bean> 
  
</beans>

 

     在 insert()方法中使用了DataSourceTransactionManager来进行事务管理,如果发生了异常,则catch区块中会进行事务的Rollback,在insert() 方法中故意写入错误的SQL(注意INSERT方法少写了一个T),因此实际上数据并不会被储存至数据库中。

    要使用MySQL数据库进行事务处理,必须建立支持事务的表格类型,例如InnoDB的表格类型,这里用来建立表格的SQL如下所示:

 

CREATE TABLE user ( 
  
    id INT(11) NOT NULL auto_increment PRIMARY KEY, 
  
    name VARCHAR(100) NOT NULL default '', 
  
    age INT 
  
) TYPE = InnoDB;

 

    另一个实现编程式事务管理的方法是使用TransactionTemplate,它需要一个TransactionManager实例,如下所示:

 

TransactionTemplate transactionTemplate = 
  
        new TransactionTemplate(transactionManager); 
  
... 
  
transactionTemplate.execute(new TransactionCallback() { 
  
    public Object doInTransaction(TransactionStatus status) { 
  
         return jdbcTemplate.update("INSERT INTO user (name,age) " 
  
               + "VALUES('" + name + "'," + age + ")"); 
  
    } 
  
});

 

    如果发生了异常,则会进行Rollback,否则提交事务,如果没有回传值,则也可以使用TransactionCallbackWithoutResult:

 

transactionTemplate.execute( 
  
        new TransactionCallbackWithoutResult() { 
  
                public void doInTransactionWithoutResult( 
  
                                TransactionStatus status) { 
  
            . ... 
  
                } 
  
            });

 

    5.3.3 JDBC声明事务管理

    Spring声明式的事务管理依赖它的AOP框架来完成。使用声明事务管理的好处是,事务管理不能侵入您所开发的组件,具体来说,DAO对象不会意识到正在事务管理之中,事实上也应当如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策略的话,也只需要在定义文件中重新配置。

    举个例子来说,可以将5.2.1节中的JdbcTemplateDemo 项目修改一下,在不修改UserDAO类的情况下,可以为它加入事务管理的服务,一个简单的方法是使用 TransactionProxyFactoryBean,指定要介入的事务管理对象及其方法,这需要在定义文件中修改,如下所示:

    DeclarativeTransactionDemo beans-config.xml

 

<?xml version="1.0" encoding="UTF-8"?> 
  
<beans xmlns="http://www.springframework.org/schema/beans" 
  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">   
     
  
    <bean id="dataSource" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DriverManagerDataSource" 
  
          destroy-method="close"> 
  
        <property name="driverClassName" 
  
                  value="com.mysql.jdbc.Driver"/> 
  
        <property name="url" 
  
                  value="jdbc:mysql://localhost:3306/demo"/> 
  
        <property name="username" value="caterpillar"/> 
  
        <property name="password" value="123456"/> 
  
    </bean> 
  
       
  
    <bean id="transactionManager" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DataSourceTransactionManager"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAO" 
  
          class="onlyfun.caterpillar.UserDAO"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAOProxy" 
  
          class="org.springframework.transaction. 
  
                   → interceptor.TransactionProxyFactoryBean"> 
  
        <property name="proxyInterfaces"> 
  
            <list> 
  
                <value>onlyfun.caterpillar.IUserDAO</value> 
  
            </list> 
  
        </property> 
  
        <property name="target" ref="userDAO"/> 
  
        <property name="transactionManager" 
  
                  ref="transactionManager"/> 
  
        <property name="transactionAttributes"> 
  
            <props> 
  
                <prop key="insert*">PROPAGATION_REQUIRED</prop> 
  
            </props> 
  
        </property> 
  
    </bean> 
  
</beans>

 

   

TransactionProxyFactoryBean需要一个TransactionManager,由于这里使用的是JDBC,所以使用 DataSourceTransactionManager,TransactionProxyFactoryBean是个代理对象,"target" 属性指定要代理的对象,事务管理会自动介入指定的方法前后,这里使用 "transactionAttributes" 属性指定,"insert*" 表示指定方法名称以insert开头的都要纳入事务管理,您也可以指定方法全名,如果在方法执行过程中发生错误,则所有先前的操作自动撤回,否则正常提交。

 

 

在 insert()方法中使用了DataSourceTransactionManager来进行事务管理,如果发生了异常,则catch区块中会进行事务的Rollback,在insert() 方法中故意写入错误的SQL(注意INSERT方法少写了一个T),因此实际上数据并不会被储存至数据库中。

    要使用MySQL数据库进行事务处理,必须建立支持事务的表格类型,例如InnoDB的表格类型,这里用来建立表格的SQL如下所示:

 

CREATE TABLE user ( 
  
    id INT(11) NOT NULL auto_increment PRIMARY KEY, 
  
    name VARCHAR(100) NOT NULL default '', 
  
    age INT 
  
) TYPE = InnoDB;

 

    另一个实现编程式事务管理的方法是使用TransactionTemplate,它需要一个TransactionManager实例,如下所示:

 

TransactionTemplate transactionTemplate = 
  
        new TransactionTemplate(transactionManager); 
  
... 
  
transactionTemplate.execute(new TransactionCallback() { 
  
    public Object doInTransaction(TransactionStatus status) { 
  
         return jdbcTemplate.update("INSERT INTO user (name,age) " 
  
               + "VALUES('" + name + "'," + age + ")"); 
  
    } 
  
});

 

    如果发生了异常,则会进行Rollback,否则提交事务,如果没有回传值,则也可以使用TransactionCallbackWithoutResult:

 

transactionTemplate.execute( 
  
        new TransactionCallbackWithoutResult() { 
  
                public void doInTransactionWithoutResult( 
  
                                TransactionStatus status) { 
  
            . ... 
  
                } 
  
            });

 

    5.3.3 JDBC声明事务管理

    Spring声明式的事务管理依赖它的AOP框架来完成。使用声明事务管理的好处是,事务管理不能侵入您所开发的组件,具体来说,DAO对象不会意识到正在事务管理之中,事实上也应当如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策略的话,也只需要在定义文件中重新配置。

    举个例子来说,可以将5.2.1节中的JdbcTemplateDemo 项目修改一下,在不修改UserDAO类的情况下,可以为它加入事务管理的服务,一个简单的方法是使用 TransactionProxyFactoryBean,指定要介入的事务管理对象及其方法,这需要在定义文件中修改,如下所示:

    DeclarativeTransactionDemo beans-config.xml

 

<?xml version="1.0" encoding="UTF-8"?> 
  
<beans xmlns="http://www.springframework.org/schema/beans" 
  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">   
     
  
    <bean id="dataSource" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DriverManagerDataSource" 
  
          destroy-method="close"> 
  
        <property name="driverClassName" 
  
                  value="com.mysql.jdbc.Driver"/> 
  
        <property name="url" 
  
                  value="jdbc:mysql://localhost:3306/demo"/> 
  
        <property name="username" value="caterpillar"/> 
  
        <property name="password" value="123456"/> 
  
    </bean> 
  
       
  
    <bean id="transactionManager" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DataSourceTransactionManager"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAO" 
  
          class="onlyfun.caterpillar.UserDAO"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAOProxy" 
  
          class="org.springframework.transaction. 
  
                   → interceptor.TransactionProxyFactoryBean"> 
  
        <property name="proxyInterfaces"> 
  
            <list> 
  
                <value>onlyfun.caterpillar.IUserDAO</value> 
  
            </list> 
  
        </property> 
  
        <property name="target" ref="userDAO"/> 
  
        <property name="transactionManager" 
  
                  ref="transactionManager"/> 
  
        <property name="transactionAttributes"> 
  
            <props> 
  
                <prop key="insert*">PROPAGATION_REQUIRED</prop> 
  
            </props> 
  
        </property> 
  
    </bean> 
  
</beans>

TransactionProxyFactoryBean需要一个TransactionManager,由于这里使用的是JDBC,所以使用 DataSourceTransactionManager,TransactionProxyFactoryBean是个代理对象,"target" 属性指定要代理的对象,事务管理会自动介入指定的方法前后,这里使用 "transactionAttributes" 属性指定,"insert*" 表示指定方法名称以insert开头的都要纳入事务管理,您也可以指定方法全名,如果在方法执行过程中发生错误,则所有先前的操作自动撤回,否则正常提交。

在"insert*" 等方法上指定了 "PROPAGATION_REQUIRED",表示在目前的事务中执行操作,如果事务不存在就建立一个新的,相关的常数意义都可以在API文件的 TransactionDefinition接口中找到。您可以加上多个事务定义,中间使用逗号 "," 区隔,例如可以加上只读,或者是指定某个异常发生时撤回操作:

package onlyfun.caterpillar; 
  
import org.springframework.context.ApplicationContext; 
  
import org.springframework.context. 
  
              support.ClassPathXmlApplicationContext; 
  
public class SpringDAODemo { 
  
    public static void main(String[] args) { 
  
        ApplicationContext context = 
  
            new ClassPathXmlApplicationContext( 
  
                    "beans-config.xml"); 
  
           
  
        User user = new User(); 
  
           
  
        user.setName("caterpillar"); 
  
        user.setAge(new Integer(30)); 
  
           
  
        IUserDAO userDAO = 
  
            (IUserDAO) context.getBean("userDAOProxy"); 
  
           
  
        userDAO.insert(user); 
  
           
  
        user = userDAO.find(new Integer(1)); 
  
           
  
        System.out.println("name: " + user.getName()); 
  
    } 
  
}您也可以设置不同的TransactionInterceptor来得到更多的管理细节,例如:
?xml version="1.0" encoding="UTF-8"?> 
  
<beans xmlns="http://www.springframework.org/schema/beans" 
  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">   
     
  
    <bean id="dataSource" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DriverManagerDataSource" 
  
          destroy-method="close"> 
  
        <property name="driverClassName" 
  
                  value="com.mysql.jdbc.Driver"/> 
  
        <property name="url" 
  
                  value="jdbc:mysql://localhost:3306/demo"/> 
  
        <property name="username" value="caterpillar"/> 
  
        <property name="password" value="123456"/> 
  
    </bean> 
  
    <bean id="transactionManager" 
  
          class="org.springframework.jdbc. 
  
                   → datasource.DataSourceTransactionManager"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
       
  
    <bean id="userDAO" 
  
          class="onlyfun.caterpillar.UserDAO"> 
  
        <property name="dataSource" ref="dataSource"/> 
  
    </bean> 
  
    <bean id="transactionInterceptor" 
  
          class="org.springframework.transaction. 
  
                   → interceptor.TransactionInterceptor"> 
  
        <property name="transactionManager" ref="transactionManager"/> 
  
        <property name="transactionAttributeSource" 
  
                  value="onlyfun.caterpillar.UserDAO.insert*= 
  
                            → PROPAGATION_REQUIRED "/> 
  
    </bean> 
  
       
  
    <bean id="userDAOProxy" 
  
          class="org.springframework.aop. 
  
                   → framework.ProxyFactoryBean"> 
  
        <property name="proxyInterfaces"> 
  
            <list> 
  
                <value>onlyfun.caterpillar.IUserDAO</value> 
  
            </list> 
  
        </property> 
  
        <property name="target" ref="userDAO"/> 
  
        <property name="interceptorNames"> 
  
            <list> 
  
                <value>transactionInterceptor</value> 
  
            </list> 
  
        </property> 
  
    </bean>

同样的,由于不再于设置文件中设置代理对象,所以直接取得"userDAO"实例进行操作即可。

首先,假设如下SQL表中有数据username=test1,passwd=test1,address=test1

CREATE TABLE `login` (
  `username` varchar(10) default NULL,
  `passwd` varchar(10) default NULL,
  `address` varchar(10) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

配置文件:

 

 



<? 
  xml version="1.0" encoding="UTF-8" 
  ?> 
  
 
  <! 
  DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"  
  > 
  
 
  < 
  beans 
  > 
  
  
  < 
  bean  
  id 
  ="dataSource" 
   class 
  ="org.apache.commons.dbcp.BasicDataSource" 
  > 
  
    
  < 
  property  
  name 
  ="driverClassName" 
  > 
  
      
  < 
  value 
  > 
  com.mysql.jdbc.Driver 
  </ 
  value 
  > 
  
    
  </ 
  property 
  > 
  
    
  < 
  property  
  name 
  ="url" 
  > 
  
      
  < 
  value 
  > 
  jdbc:mysql://localhost:3306/javaee 
  </ 
  value 
  > 
  
    
  </ 
  property 
  > 
  
    
  < 
  property  
  name 
  ="username" 
  > 
  
      
  < 
  value 
  > 
  root 
  </ 
  value 
  > 
  
    
  </ 
  property 
  > 
  
    
  < 
  property  
  name 
  ="password" 
  > 
  
      
  < 
  value 
  > 
  1234 
  </ 
  value 
  > 
  
    
  </ 
  property 
  > 
  
  
  </ 
  bean 
  > 
  
  
  < 
  bean  
  id 
  ="jdbcTemplate" 
   class 
  ="org.springframework.jdbc.core.JdbcTemplate" 
  > 
  
    
  < 
  property  
  name 
  ="dataSource" 
  > 
  
      
  < 
  ref  
  local 
  ="dataSource" 
  /> 
  
    
  </ 
  property 
  > 
  
  
  </ 
  bean 
  > 
  

 
  < 
  bean  
  id 
  ="personDAO" 
   class 
  ="SpringJDBCSupport.ReadData.PersonDAO" 
  > 
  
   
  < 
  property  
  name 
  ="jdbcTemplate" 
  > 
  
     
  < 
  ref  
  local 
  ="jdbcTemplate" 
  /> 
  
   
  </ 
  property 
  > 
  
 
  </ 
  bean 
  > 
   
 
  </ 
  beans 
  > 
  

 
 
 JavaBean:
 
 
 
   
package    SpringJDBCSupport.ReadData;
   import 
   com.mysql.jdbc.Driver;
   public 
    
  class 
   Person  
  {
  private String name;
  private String password;
  private String address;
  public Person(){
      
  }
  public Person(String name,String password,String address){
      this.name=name;
      this.password=password;
      this.address=address;
  }
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
public String toString(){
    return this.getName()+"-"+this.getPassword()+"-"+this.getAddress();
}
}

DAO:

其中getPersonByRowCallbackHandler方法根据username获得person对象

 

package    SpringJDBCSupport.ReadData;

   import    java.sql.PreparedStatement;
   import    java.sql.ResultSet;
   import    java.sql.SQLException;
   import    java.sql.Types;
   import    java.util.List;

   import    org.springframework.jdbc.core.BatchPreparedStatementSetter;
   import    org.springframework.jdbc.core.JdbcTemplate;
   import    org.springframework.jdbc.core.RowCallbackHandler;

   public     
  class 
   PersonDAO  
  {
  private JdbcTemplate jdbcTemplate;

public JdbcTemplate getJdbcTemplate() {
    return jdbcTemplate;
}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

public int insertPersonUseUpdate(Person person){
    String sql="insert into login values(?,?,?)";
    Object[] params=new Object[]{
            person.getName(),
            person.getPassword(),
            person.getAddress()
    };
    return this.getJdbcTemplate().update(sql,params);
}
public int insertPersonUseExecute(Person person){
    String sql="insert into login values(?,?,?)";
    Object[] params=new Object[]{
            person.getName(),
            person.getPassword(),
            person.getAddress()
    };
    int[] types=new int[]{
            Types.VARCHAR,
            Types.VARCHAR,
            Types.VARCHAR
    };
    return this.getJdbcTemplate().update(sql,params,types);
}
public int[] updatePersonUseBatchUpdate( final List persons){
    String sql="insert into login values(?,?,?)";
    BatchPreparedStatementSetter setter=null;
    setter=new BatchPreparedStatementSetter(){
        public int getBatchSize(){
            return persons.size();
        }
        public void setValues(PreparedStatement ps,int index) throws SQLException{
            Person persnotallow=(Person)persons.get(index);
            ps.setString(1,person.getName());
            ps.setString(2,person.getPassword());
            ps.setString(3,person.getAddress());
        }
    };
    return this.getJdbcTemplate().batchUpdate(sql,setter);
}

public Person getPersonByRowCallbackHandler(String username){

    String sql="select * from login where username=?";
    final Person persnotallow=new Person();
    final Object params[]=new Object[]{username};
    this.getJdbcTemplate().query(sql,params,new RowCallbackHandler(){
        public void processRow(ResultSet rs)throws SQLException{
            person.setName(rs.getString("username"));
            person.setPassword(rs.getString("passwd"));
            person.setAddress(rs.getString("address"));
        }
    });
    return person;
}
  
}

 

测试代码:

 

 

package    SpringJDBCSupport.ReadData;

   import    java.io.File;
   import    java.util.ArrayList;
   import    java.util.List;

   import    org.springframework.beans.factory.BeanFactory;
   import    org.springframework.beans.factory.xml.XmlBeanFactory;
   import    org.springframework.core.io.FileSystemResource;

   public       class 
   TestJDBCTemplate  
  {

    public static String filePath="";
    public static BeanFactory factory=null;
    public static void main(String[] args) {
        filePath=System.getProperty("user.dir")+File.separator+"SpringJDBCSupport"+File.separator+"ReadData"+File.separator+"hello.xml";
        factory=new XmlBeanFactory(new FileSystemResource(filePath));
        PersonDAO persnotallow=(PersonDAO)factory.getBean("personDAO");
        /*
         * 准备数据
         */
        Person p1=new Person("test1","test1","test1");
        Person p2=new Person("test2","test2","test2");
        Person p3=new Person("test3","test3","test3");
        Person p4=new Person("test4","test4","test4");
        Person p5=new Person("test5","test5","test5");
        List persnotallow=new ArrayList();
        persons.add(p3);
        persons.add(p4);
        persons.add(p5);
        //使用jdbcTemplate.update方式
    //    personDAO.insertPersonUseUpdate(p1);
        //使用jdbcTemplate.execute方式
    //    personDAO.insertPersonUseExecute(p2);
    //    //使用jdbcTemplate批处理方式
    //    personDAO.updatePersonUseBatchUpdate(persons);
        
        //使用RowCallbackHandler执行一次查询,并打印person信息
        System.out.println(personDAO.getPersonByRowCallbackHandler("test1"));
    }
    
    

}