2011年11月07日 星期一 上午 8:50


Dao 的支持类可以有好多,如: JdbcDaoSupport , HibernateDaoSupport ,JdoDaoSupport等,下面对最常用的HibernateDaoSupport与JdbcDaoSupport做一小总结:
一、在Spring框架中实现连接数据库方式:
1、、借助类HibernateDaoSupport的简约化实现:
借助这个类必须需要HIbernate框架,用到HIbernate里提供的HibernateTemplate模板,从而进行增、删、改、查操作。
TestA.java:

public class TestA extends HibernateDaoSupport{
 public void test(){
      HibernateTemplate template = this.getHibernateTemplate();
      List list = template.find("from User");
      for(int i=0;i<list.size();i++){
       User u = (User)list.get(i);
       System.out.println(u.getUserid()+" "+u.getEmail());
      }
 }

 public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            TestA t = (TestA)ctx.getBean("testa");
            t.test();
 }
 }


需要在Spring的配置文件applicationContext.xml中控制反转用到连接数据库中的类是注入SessionsFactory,如下:
applicationContext.xml:

<bean id="testa" class="com.sun.demo.TestA">
         <property name="sessionFactory">
         <ref bean="mySessionFactory"/>
         </property>
         </bean>


2、、借助类JdbcDaoSupport的简约化实现:
借助这个类不需要HIbernate框架,也不需要有ORM的对象关联映射。但它和HibernateDaoSupport很类似,有JdbcTemplate来实现增、删、改、查操作。
TestA.java:

public class TestA extends JdbcDaoSupport{
     public void test(){
         int n = this.getJdbcTemplate().queryForInt("select max(userid) from User");
         System.out.println(n);
     }
 public static void main(String[] args) {
 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
 TestA ta = (TestA)ctx.getBean("testa");
         ta.test(); 
 }
 } 
 需要在Spring的配置文件applicationContext.xml中控制反转用到连接数据库中的类是注入DataSource,如下:
 applicationContext.xml:
         <bean id="testa" class="com.sun.demo.TestA">
         <property name="dataSource">
         <ref bean="myDataSource"/>
         </property>
         </bean>
         
 二、编程式事务管理、声明式事务管理中HibernateDaoSupport与JdbcDaoSupport的应用:
 1、编程式事务管理:
 1>、JdbcDaoSupport编程式事物管理,必须继承JdbcDaoSupport类,得到JdbcTemplate从而实现事务管理;

 TestA.java:
 public class TestA extends JdbcDaoSupport{
 public void test(){
      PlatformTransactionManager ptm = new DataSourceTransactionManager(this.getDataSource());
      TransactionTemplate tst = new TransactionTemplate(ptm);
      tst.execute(new TransactionCallback(){
    public Object doInTransaction(TransactionStatus status) {
       getJdbcTemplate().update("update User set password='1230' where userid='1001'"); 
       getJdbcTemplate().update("update User set where userid='100000001'");
       getJdbcTemplate().update("update User set phone='phone'");
       return null;
    }
      });
 }


 public static void main(String[] args) {
     ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
     TestA t = (TestA)ctx.getBean("testa");
     t.test();
 }
 }
 需要在Spring的配置文件applicationContext.xml中控制反转用到连接数据库中的类是注入DataSource,如下:
 applicationContext.xml:
 <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
     
     ... ...
     
     <property name="defaultAutoCommit">
     <value>false</value>
     </property>
 </bean>
     
         <bean id="testa" class="com.sun.demo.TestA">
         <property name="dataSource">
         <ref bean="myDataSource"/>
         </property>
         </bean>
 2>、HibernateDaoSupport编程式事物管理,必须继承HibernateDaoSupport类,得到HibernateTemplate从而实现事务管理;
 TestB.java:
 public class TestB extends HibernateDaoSupport{
 public void test(){
      HibernateTransactionManager hm = new HibernateTransactionManager(this.getSessionFactory());
      TransactionTemplate ttm = new TransactionTemplate(hm);
      ttm.execute(new TransactionCallback(){
    public Object doInTransaction(TransactionStatus status) {
     User u1 = new User();
     u1.setUserid("3001");
     u1.setPassword("3001");
     getHibernateTemplate().save(u1);
     
     User u2 = new User();
     u2.setUserid("3001");
     u2.setPassword("3002");
     getHibernateTemplate().save(u2);
     return null;
    }
      });
 }

 public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            TestB t = (TestB)ctx.getBean("testb");
         t.test();
 }
 }
 需要在Spring的配置文件applicationContext.xml中控制反转用到连接数据库中的类是注入SessionsFactory,如下:
 applicationContext.xml:
 <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
     
     ... ...
     
     <property name="defaultAutoCommit">
     <value>false</value>
     </property>
 </bean>
     
      <bean id="testb" class="com.sun.demo.TestB">
      <property name="sessionFactory">
      <ref bean="mySessionFactory"/>
      </property>
      </bean>


2、声明式事务管理:   
1>、JdbcDaoSupport声明式样事物管理,必须继承JdbcDaoSupport类;

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

 <property name="defaultAutoCommit">
 <value>false</value>
 </property>
 </bean>

    需要在Spring配置文件中配置声明事务处理,用JdbcDaoSupport提供的DataSourceTransactionManager如下:
         <!-- 事务管理配置 -->
         <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource">
         <ref bean="myDataSource"/>
         </property>
         </bean>
        
         <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
         <property name="transactionManager" ref="transactionManager"/>
         <!-- 事务管理属性 -->
         <property name="transactionAttributes">
            <props>
            <prop key="updateUser">PROPAGATION_REQUIRED</prop>
            </props>
         <!-- 事务管理目标bean -->
         </property>
         <property name="target" ref="userdao"></property>
         </bean>
         
         <bean id="userdao" class="com.sun.demo.UserDao">
         <property name="dataSource">
         <ref bean="myDataSource"/>
         </property>
         </bean>IUserDao.java://定义接口
 public interface IUserDao {
 public void updateUser();
 }UserDao.java:
 public class UserDao extends JdbcDaoSupport implements IUserDao{
        public void updateUser(){
         this.getJdbcTemplate().update("update User set password='password1' where userid='1001'");
            this.getJdbcTemplate().update("update User set password='password9999999999999999999999999999999' where userid='1002'");
        }
 }TestA.java://调用updateUser()方法
 public class{
     
     public void test(){
           ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        IUserDao u = (IUserDao)ctx.getBean("baseTransactionProxy");
           u.updateUser();
     }


 public static void main(String[] args) {
            TestA t = new TestA();
            t.test();
 }
 }
 2>、HibernateDaoSupport声明式事物管理,必须继承HibernateDaoSupport类;
 IUserDao.java://定义接口
 public interface IUserDao {
 public void updateUser();
 }
 UserDao.java:
 public class UserDao extends HibernateDaoSupport implements IUserDao{
        public void updateUser(){
               User u1 = new User();
               u1.setUserid("1001");
               u1.setPassword("5001");
               this.getHibernateTemplate().update(u1);
               
               
               User u2 = new User();
               u2.setUserid("1003");
               u2.setPassword("20015555555555555555555555555555555555555555555");
               this.getHibernateTemplate().update(u2);
        }
 }

测试:

public class TestA{
     
     public void test(){
           ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        IUserDao userdao= (IUserDao)ctx.getBean("userproxy");
           userdao.updateUser();
     }


 public static void main(String[] args) {
            TestA t = new TestA();
            t.test();
 }
 }


需要在Spring配置文件中配置声明事务处理,用JdbcDaoSupport提供的HibernateTransactionManager如下:

applicationContext.xml:
         <!-- 事务管理配置 -->
         <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <property name="sessionFactory">
         <ref bean="mySessionFactory"/>
         </property>
         </bean>
         
         <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
         <property name="transactionManager" ref="transactionManager"/>
         <!-- 事务管理属性 -->
         <property name="transactionAttributes">
            <props>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            </props>
         <!-- 事务管理目标bean -->       
         </property>
         </bean>
         
         <bean id="userdao" class="com.sun.demo.UserDao">
         <property name="sessionFactory">
         <ref bean="mySessionFactory"/>
         </property>
         </bean>
         
         <bean id="userproxy" parent="baseTransactionProxy">
         <property name="target" ref="userdao"></property>
         </bean>

               断尘居

                            年轻人要少一些浮躁、多一些真才实学

 

Spring的JdbcDaoSupport的批量操作  


由于数据的批量处理(比如往RDBMS插入几万条数据)非常耗资源,因此建议在所有场合能够借助于JDBC完成,而不要去采用Hibernate API。本文主要围绕Spring内置的各类JDBC API抽象支持展开的。

1.1.  JdbcTemplate 内置的batchUpdate(final String[] sql)

这一方法适合于小批量数据的CUD(增、更新、删除)操作,而且SQL类型不限。由于其内部使用了Statement语句,所以数据的操作效率一般。

1.2.  JdbcTemplate 内置的batchUpdate(String sql, final BatchPreparedStatementSetter pss)

这一方法也仅仅适合于小批量数据的CUD(增、更新、删除)操作,但始终是同一SQL(参数具有多样性)。由于其内部使用了PreparedStatement语句,所以数据的操作效率还是不错的。下面给出了操作示例:

 

final int[] no = new int[]{7369,7499,7521,7566,7654,7698};
 
jt.batchUpdate("update emp set sal = ? where empno = ?", 
          new BatchPreparedStatementSetter(){
                    public void setValues(PreparedStatement ps, int i)
throws SQLException {
                        ps.setInt(1, no[i]);
                        ps.setFloat(2, no[i]);
                   }
                    public int getBatchSize() {
                        return no.length;
                    }
          });

 

1.3.  BatchSqlUpdate

这一方法适合于各种批量数据的CUD(增、更新、删除)操作,但始终是同一SQL(参数具有多样性)。由于其内部使用了PreparedStatement语句,所以数据的操作效率还是不错的。下面给出了操作示例:

DataSource ds = gbfa.getBean("dataSource");
 
final int[] no = new int[]{7369,7499,7521,7566,7654,7698};
 
BatchSqlUpdate bsu = new BatchSqlUpdate(ds, "update emp set sal=? where empno = ?");
bsu.setBatchSize(4);
bsu.setTypes(new int[]{Types.FLOAT, Types.INTEGER});
for(int i = 0; i < no.length; ++i){
log.info(bsu.update(new Object[]{no[i],no[i]})) ;
}
bsu.flush();

 

       同JdbcTemplate内置的batchUpdate(String sql, final BatchPreparedStatementSetter pss)相比,BatchSqlUpdate会自动分批待批量处理的数据。比如,如果需要批量操作10万条数据,则可以控制其batchSize,从而在 时间(RDBMS可知性)和空间(内存)上达到平衡。

       务必注意,在使用BatchSqlUpdate的最后,不要忘记手工调用其暴露的flush()方法。