• spring对hibernate的支持详解 <转+部分自增>


    支持1: 利用ioc为dao注入sessionFactory; 

    1.管理SessionFactory

       使用Spring整合Hibernate时我们不需要hibernate.cfg.xml文件。首先,在applicationContext.xml中配置数据源(dataSource)bean和session工厂(sessionFactory)bean。其中,在配置session工厂bean时,应该注入三个方面的信息:

          ●数据源bean

          ●所有持久化类的配置文件

          ●Hibernate的SessionFactory的属性;其中SessionFactory的属性信息又包括(1,Hibernate的连接方法; 2,不同数据库连接,启动时的选择。)

    --以下代码可以利用myeclipse工具自动生成;

    <beans //此处省略一些元数据..
    
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver">
            </property>
            <property name="url" value="jdbc:mysql://localhost:3306/mysql"></property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource">
                <ref bean="dataSource" />
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">
                        org.hibernate.dialect.MySQLDialect
                    </prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
            <property name="mappingResources">
                <list>
                    <value>com/dto/Student.hbm.xml</value>
                </list>
            </property>
        </bean>
    </beans>

    存在问题:虽然sessionFactory注入了, 但是还是需要我们手工管理session 以及 事务. 操作笨重;如下:

    public class StudentDAO implements StudentDAOIf {
        private SessionFactory sessionFactory;  
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
        public void saveStudent(Student stu) {
            Session session = sessionFactory.openSession();
            session.beginTransaction();
            session.save(stu);
            session.getTransaction().commit();
            session.close();
        }
    }
    View Code


     测试:

    public static void main(String[] args) {
    //启动spring: ApplicationContext context
    = new ClassPathXmlApplicationContext("applicationContext.xml"); StudentDAOIf dao = (StudentDAOIf)context.getBean("stu3DAO"); Student s2 = new Student(); s2.setEmail("xxsseee"); s2.setName("jjkkee"); s2.setAge(23); dao.saveStudent(s2); }

     ------------------------------------------------------------------------------------------------------------

    支持2: 利用spring 中提供的 HibernateTemplate 组件, 简化session以及事务的管理过程.
    如:ht.save(o); ht.update(o); ht.delete(o)

    pring提供了HibernateTemplate,用于持久层访问,该模板无需打开Session及关闭Session。它只要获得SessionFactory的引用,将可以只能地打开Session,并在持久化访问结束后关闭Session,程序开发只需完成持久层逻辑,通用的操作(如对数据库中数据的增,删,改,查)则有HibernateTemplate完成。

    HibernateTemplate有三个构造函数,不论是用哪一种构造,要使HibernateTemplate能完成持久化操作,都必须向其传入一个SessionFactory的引用。

    --存在问题: 在每个dao中为了创建template都存在如下代码, 操作笨重
    private HibernateTemplate template;
    public void setSessionFactory(SessionFactory sessionFactory) {
    template = new HibernateTemplate(sessionFactory);
    }

    HibernateTemplate的用法有两种,一种是常规的用法,另一种是复杂的用。

    第一种:常规的用法

    HibernateTemplate通过它自己的delete(Object entity) ,find(String queryString),save(Object entity)等等常用的方法即可完成大多数DAO对象的增,删,改,查等操作。

    第二种:复杂的用法

    HibernateTemplate的复杂的用法是通过如下的两个方法来完成的:

                ●Object execute(HibernateCallback action)

                ●List execute(HibernateCallback action)

    其中,这两个方法都需要一个HibernateCallback实例,开发者通过HibernateCallback,可以完全使用Hibernate灵活的方式来访问数据库,解决了Spring封装Hibernate后灵活不足的缺陷。HibernateCallback是一个接口,该接口只有一个方法doInHibernate(org.hibernate.Session session),该方法只有一个参数Session。

    通常,程序中采用实现HibernateCallback的匿名内部类来获取HibernateCallback的实例,方法doInHibernate就是Spring执行的持久化操作。具体的代码实例如下:

           public class PersonDaoImpl {
                     private SessionFactory sessionFactory;
                     public void setSessionFactory(SessionFactory sessionFactory) {
                             this.sessionFactory = sessionFactory;
                     }
                     public List findPersonByName(final String name) {
                             HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
                             return (List)hibernateTemplate.execute(
                                      public Object doInHibernate(Session session) throws Hibernate Exception {
                                               List result =session.createCriteria(Person.clsss).add(Restrictions.like("name",name+"%")).list();
                                              return result;
                                       }
                             );
                     }
            }

     注:在方法doInHibernate内可以访问Session,该Session对象是绑定到该线程的Session实例,该方法内的持久层操作与不使用Spring时的持久层操作完全相同,这保证了对于复杂的持久层访问时,依然可以使用Hibernate的访问方式。

    3.DAO的实现

       DAO的实现有两种方式:一,继承HibernateDaoSupport实现DAO;二,基于Hibernate3.0实现DAO。

          一,继承HibernateDaoSupport实现DAO

             Spring为Hibernate的DAO提供了工具类HibernateDaoSupport。该类主要提供了如下两个方法来方便DAO的实现:

             ●public final HibernateTemplate getHibernateTemplate()

             ●public final void setSessionFactory(SessionFactory sessionFactory)

             其中,setSessionFactory方法用来接收Spring的ApplicationContext依赖注入的SessionFactory实例;getHibernateTemplate方法则用来根据刚才的SessionFactory产生Session,最后由HibernateTemplate来完成数据库访问。

          二,基于Hibernate3.0实现DAO

            在Hibernate处于事务的管理下时(通常Spring为Hibernate提供事务管理),通过SessionFactory的getCurrentSession()方法可以返回当前的Session,如果当前的JTA事务关联的Session不存在,则系统打开一次新的Session,并关联到当前的JTA事务;如果当前JTA事务关联的Session已经存在,则直接返回该Session。获得了当前的Session后就可以进行持久化操作了。

          可见,不论使用上面的哪一种方式实现DAO都需要用Spring来注入SessionFactory实例。

    4.事务的管理

       Hibernate建议所有的对数据库的访问都应放在事务内进行,即使进行的只是读操作。Spring同时支持编程式事务和声明式事务。通常推荐使用声明式事务。

       编程式事务管理:

       编程式事务提供了TransactionTemplate模板类,用的时候必须向其体提供一个PlatformTransactionManager实例。只要TransactionTemplate获取了PlatformTransactionManager的引用,TransactionTemplate就可以完成事务操作了。TransactionTemplate提供了一个execute方法,它接收一个TransactionCallback实例。TransactionCallback包含如下方法:

          ●Object doInTransaction(TransactionStatus status)

    这是需要有返回值的情况。如果不需要有返回值的话,我们可以用TransactionCallbackWithOutResult类来代替TransactionCallback类,它也有一个方法:

          ●void doInTransaction(TransactionStatus status)

       在这个两个方法中,在出现异常时,TransactionStatus的实例status可以调用setRollbackOnly()方法进行回滚。

       一般情况下,向execute方法传入TransactionCallback或TransactionCallbackWithOutResult实例时,采用的是匿名内部类的形式。

       声明式事务管理:

       声明式事务管理的配置方式通常有三种:

          ●使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。

          ●使用BeanNameAutoProxyCreator,根据bean name自动生成事务代理的方式,这是直接利用Spring的AOP框架配置事务代理的方式,需要对Spring的AOP框架有所了解。

          ●使用DefaultAdvisorAutoProxyCreator,这也是直接利用Spring的AOP框架配置事务代理的方式,只是这种配置方式的可读性不如使用BeanNameAutoProxyCreator的配置方式。
    ------------------------------------------------------------------

    <?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/test</value>
           </property>
           <property name="username">
               <value>root</value>
           </property>
           <property name="password">
               <value>8093</value>
           </property>
        </bean>

        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
       <ref local="dataSource"/>
    </property>
    <property name="mappingResources">
       <list>
        <value>user.hbm.xml</value>
       </list>
    </property>
    <property name="hibernateProperties">
       <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
       </props>
    </property>
    </bean> 

        <bean id="userDAO" class="com.dang.action.UserDAOImpl">
    <property name="sessionFactory">
       <ref local="sessionFactory"/>
    </property>
    </bean> 

    <bean name="/regedit" class="com.dang.action.RegeditAction">
         <property name="userDAO">
            <ref bean="userDAO"/>
         </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
           <property name="sessionFactory">
               <ref local="sessionFactory" />
           </property>
        </bean>

       <bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
         <property name="transactionManager">
             <ref bean="transactionManager" />
         </property>
         <property name="target">
             <ref local="userDAO" />
         </property>
         <property name="transactionAttributes">
             <props>
                <prop key="create*">PROPAGATION_REQUIRED</prop>
             </props>
         </property>
       </bean>
    </beans>

  • 相关阅读:
    将16进制的颜色值变成UIColor
    验证邮箱地址方法
    iOS 推送通知详解
    在UITextView中添加placeholder
    移除所有子视图removeAllSubviews
    如何书写高质量的jQuery代码
    reset.css
    CSS3笔记
    10个可以直接拿来用的JQuery代码片段
    js定时器
  • 原文地址:https://www.cnblogs.com/sunliqing/p/3478557.html
Copyright © 2020-2023  润新知