Spring对Hibernate的支持

来源:互联网 发布:药房进销存软件 编辑:程序博客网 时间:2024/06/05 03:26

1.jar包支持

  • Hibernate框架需要的jar包
    hibernate-core.xxx.jar(9个包)
    mysql-connector-java-xxx.jar
  • Spring框架需要的jar包
    spring-context.xxx.jar(5个包)
    spring.aop.xxx.jar(4个包)
    spring-orm-xxx.jar (Spring对Hibernate的支持包)
    spring-tx-xxx.jar (Spring的事务支持)

2. applicationContext.xml 配置文件

Spring对hibernate配置文件的整合有两种方式:

1.当我们需要hibernate.cfg.xml配置文件时,在applicationContext.xml中的SessionFactory的bean的configLocation来获取hibernate.cfg.xml.

    <!-- spring-org.jar中的包,提供对SessionFactory的Bean支持-->    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactory">        <!-- 获取src根目录下hibernate.cfg.xml配置文件(前提是在src根目录下包含hibernate.cfg.xml文件) -->        <property name="configLocations">             <value>classpath:hibernate.cfg.xml</value>         </property>     </bean>

2.舍弃hibernate.cfg.xml文件,对hibernate所有的配置都由SessionFactory的数据源Bean来管理,代码如下:

    <!-- spring-org.jar中的包,提供对SessionFactory的Bean支持-->    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactory">        <!--dataSource属性,值为一个dataSource (数据源)bean-->        <property name="dataSource" ref="daraSource"></property>        <!--mappingDirectoryLocations属性,用于配置hibernate实体类映射文件的路径>        <property name="mappingDirectoryLocations">            <list>                <!-- 指定Xxx.hbm.xml文件所在的路径,spring会在此目录下寻找所有的hbm.xml文件 -->                <value>classpath:org/ch/pojo</value>            </list>        </property>        <!--hibernateProperties属性,配置hibernate的一些其余的配置,包括数据库方言、sql语句输出、数据表自动创建等等-->        <property name="hibernateProperties">            <props>                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>                <prop key="hibernate.format_sql">true</prop>                <prop key="hibernate.show_sql">true</prop>                <prop key="hbm2ddl.auto">update</prop>                <!---一般不配置,Spring可以配置自动管理事务-->                <!--<prop key="current_session_context_class">thread</prop>-->            </props>        </property>    </bean>
    <!--org.springframework.jdbc.datasource.DriverManagerDataSource类用于封装对数据库的基本配置的信息,包括用户名、密码、驱动、数据源地址等等-->    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">        <property name="driverClassName" value="com.mysql.jdbc.Driver" />        <property name="url" value="jdbc:mysql://localhost:3306/hibernate" />        <property name="username" value="root" />        <property name="password" value="123" />    </bean>

3.初始化IoC容器

Java环境下,我们通过ClassPathXmlApplication类来初始化IoC容器
Web环境下,我们不能再使用ClassPathXmlApplication,而是使用ApplicationContext的一个子接口WebApplicationContext。
初始化WebApplicationContext的代码如下:

<!--this.getServletContext表示获取当前项目运行环境,也就是Application对象-->WebApplicationContext webAppContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());_______________________________________________________________________________<!--写到这一步是无法找到applicationContext.xml文件,所以需要在web.xml做如下配置--><!--监听器,此监听器是实现于ServletContextListener接口,表示对application启动和销毁的监听,此监听器会在应用启动的时候便初始化ioc容器--><listener>    <listener-class>        org.springframework.web.context.ContextLoaderListener    </listener-class></listener><!--指定spring xml存在的路径,根据路径初始化ioc容器--><context-param>    <param-name>contextConfigLocation</param-name>    <param-value>classpath:applicationContext.xml</param-value></context-param><!--在web.xml中配置好监视器和环境路径后,便可以初始化IoC容器,通过webAppContext对象获取Bean--><!--通过Bean的id值获取SessionFactory对象-->SessionFactory sessionFacory = webAppContext.getBean("sessionFacory");

4.Spring的Hibernate的事务支持

Spring同样对Hibernate的事务具有同样的支持,可以帮助Hibernate进行事务的管理。
对此Spring提供了两种不同的方式

1.通过HibernateTemplate

Hibernate中对事务的管理举例如下,对数据库的插入操作

//Hibernate的插入操作public void save(User user) {     Session session=null;     try {         session=sessionFactory.getCurrentSession(); //通过sessionFactory获取Session对象        session.beginTransaction();                 //Session开启事务         session.save(user);                         //Session执行插入操作        session.getTransaction().commit();          //Session事务提交    } catch (Exception e) {         e.printStackTrace();         session.getTransaction().rollback();        //如果出现异常,事务回滚    }finally{         if(s!=null){         session.close();                           //最后关闭Session    }     }     System.out.println("insert success!!"); 

HibernateTemplate对session.save(user)前后的操作全部进行了封装,只对外提供了进行数据库增删改查的操作接口,这样的话让我们编写代码更加方便。
使用HibernateTemplate的话,就需要通过向java代码中注入HibernateTemplate代替SessionFactory,直接使用HibernateTemplate的方法去操作Hibernate。

使用HibernateTemplate的步骤:

1. 在applicationContext.xml 中初始化HibernateTemplate,并注入sessionFactory对象
    <!-- 配置事务管理器 指定其作用的sessionFactory把事务交给Spring去处理 --><bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">    <property name="sessionFactory" ref="sessionFactory"></property></bean><!-- HibernateTemplate的bean对象--><bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">    <property name="sessionFactory" ref="sessionFactory"></property></bean>
2.在applicationContext.xml配置事务的传播特性和事务的切入点
<!-- 配置事务的传播特性 --><tx:advice id="txAdvice" transaction-manager="transactionManager">    <tx:attributes>        <tx:method name="save*" propagation="REQUIRED"/>        <tx:method name="delete*" propagation="REQUIRED"/>        <tx:method name="update*" propagation="REQUIRED"/>        <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>        <tx:method name="*" read-only="true"/>    </tx:attributes></tx:advice><!-- 那些类的哪些方法参与事务 类似于aop:aspect的用法--><aop:config>    <aop:pointcut id="allServiceMethod" expression="execution(* com.coe.service.*.*(..))"/>    <aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice"/></aop:config>

以上代码中tx:method标签的propagation属性用来配置事务的传播特性,以下为属性的可选值
a. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启;
b. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行;
c. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常;
d. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;
e. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务;
f. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常;
g. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

3.HibernateTemplate中常用的方法

deleteAll(Collection entities): 删除集合内全部持久化类实例
find(String queryString): 根据HQL查询字符串来返回实例集合
findByNamedQuery(String queryName): 根据命名查询返回实例集合
get(Class entityClass, Serializable id): 根据主键加载特定持久化类的实例
save(Object entity): 保存新的实例
saveOrUpdate(Object entity): 根据实例状态,选择保存或者更新
update(Object entity): 更新实例的状态,要求entity是持久状态
setMaxResults(int maxResults): 设置分页的大小

2.使用HibernateDaoSupport

不用SessionFactory,也不用get和set这个HIbernateTemplate,只需要从HibernateDaoSupport继承:

//继承HibernateDaoSupport,并实现其接口public class LogDaoImpl extends HibernateDaoSupport implements LogDao{ public void save(Log log) {     this.getHibernateTemplate().save(log);     //或直接this.save(log);     System.out.println("Log add success!!");     } } 

给dao类注入sessionFactory,有人会问我们的dao类中并没有sessionFactory对象,其实这里是一个父类中的sessionFactory对象。

<bean id="logDao" class="cn.edu.hpu.dao.Impl.LogDaoImpl">     <property name="sessionFactory" ref="sessionFactory"></property> </bean> 

使用HibernateDaoSupport更方便。但是类继承了HibernateDaoSupport,不能再继承别的类,因此有些不方便。
即使使用HibernateDaoSupport,也需要配置transactionManager和配置事务的传播特性等,也就说与hibernatetemplate的区别是一个注入hibernatetemplate一个注入sessionfaotry.其他都一样。

原创粉丝点击