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.其他都一样。