spring与hibernate的整合目的就是为了让 IOC 容器来管理 Hibernate 的核心接口SessionFactory以及让 Hibernate 使用上 Spring 的声明式事务来进行事务操作.

【1】Hibernate使用XML方式与Spring整合

即,Model上面不添加注解,使用*.hbm.xml方式与数据库进行关联。

① applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

<!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>

<context:component-scan base-package="com"></context:component-scan>

<!-- 配置 C3P0 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>

<!-- 配置 SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<!-- 如果不想使用额外的hibernate.cfg.xml,则需要进行如下设置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="mappingLocations" value="classpath:com/jane/ssh/entities/*.hbm.xml"></property>
</bean>
<!-- 这里配置与MyBatis整合Spring很类似 -->

<!-- 配置 Spring 的声明式事务 -->
<!-- 1. 配置 hibernate 的事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 2. 配置事务属性 -->
<!-- 配置哪些方法要加入事务控制 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读事务 -->
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<!-- 以下方法都是可能涉及写改的方法,就无法设置为只读 -->
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>


<!-- 3. 配置事务切入点, 再把事务属性和事务切入点关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.jane.ssh.service.*.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

<!-- 开启HibernateTemplate,并且为其注入SessionFactory
使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取
注意:这里之所以配置这个是因为Dao继承了HibernateDaoSupport
-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>


</beans>

② hibernate.cfg.xml

由于数据源,*.hbm.xml都在applicationContext.xml中进行了配置,故而hibernate.cfg.xml极其简化:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>
<!-- 配置 hibernate 的基本属性 -->

<!-- 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

<!-- 是否显示及格式化 SQL -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

<!-- 生成数据表的策略 -->
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>

<!-- 配置使用的二级缓存的产品 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

<!-- 配置启用查询缓存 -->
<property name="cache.use_query_cache">true</property>

</session-factory>


</hibernate-configuration>

【2】Hibernate注解版与Spring整合

即,Model上面添加注解,此时不再存在*.hbm.xml。

① applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

<!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>

<context:component-scan base-package="com"></context:component-scan>

<!-- 配置 C3P0 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>

<!-- 配置 SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<!-- 如果实体类使用了注解,通常会使用如下方式
通过扫描包方式设置Spring取哪个包查找相应的实体类 -->
<property name="packagesToScan">
<value>com.jane.ssh.entities</value>
</property>
-->
</bean>

<!-- 配置 Spring 的声明式事务 -->
<!-- 1. 配置 hibernate 的事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 2. 配置事务属性 -->
<!-- 配置哪些方法要加入事务控制 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读事务 -->
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<!-- 以下方法都是可能涉及写改的方法,就无法设置为只读 -->
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>


<!-- 3. 配置事务切入点, 再把事务属性和事务切入点关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.jane.ssh.service.*.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

<!-- 开启HibernateTemplate,并且为其注入SessionFactory
使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取
注意:这里之所以配置这个是因为Dao继承了HibernateDaoSupport
-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>


</beans>

② hibernate.cfg.xml

由于数据源,*.hbm.xml都在applicationContext.xml中进行了配置,故而hibernate.cfg.xml极其简化:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>
<!-- 配置 hibernate 的基本属性 -->

<!-- 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

<!-- 是否显示及格式化 SQL -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

<!-- 生成数据表的策略 -->
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>

<!-- 配置使用的二级缓存的产品 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

<!-- 配置启用查询缓存 -->
<property name="cache.use_query_cache">true</property>

</session-factory>


</hibernate-configuration>

当然,通常情况下,会去掉hibernate.cfg.xml,而将Hibernate相关属性配置在sessionFactory中。


③ 常见的Hibernate注解示例如下:

package domain;
import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Entity
@Table(name="article_inf")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Article implements Serializable{
private static final long serialVersionUID = 48L;
@Id @Column(name="article_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;

@ManyToOne(targetEntity=Login.class)
@JoinColumn(name="user_id",referencedColumnName="user_id",nullable=false)
private Login login;

@Column(name="boss_id")
private Integer bossId;

@Temporal(TemporalType.TIMESTAMP)
@Column(name="create_date")
private Date createDate;

@Temporal(TemporalType.TIMESTAMP)
@Column(name="modify_date")
private Date modifyDate;

@Column(name="article_authority")
private Integer authority;

@Column(name="title")
private String title;

@Column
private String writer;

@ElementCollection(targetClass=String.class)
@CollectionTable(name="art_content",joinColumns=@JoinColumn(name="article_id",nullable=false))
@Column(name="content",length=5000) @OrderColumn(name="No_")
private List<String> contents=new LinkedList<>();

@OneToMany(targetEntity=ArticlePictures.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
private List<ArticlePictures> pictures=new LinkedList<>();

@OneToMany(targetEntity=ArticleComments.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
private List<ArticleComments> comments=new LinkedList<>();

@OneToMany(targetEntity=ArticleVisitors.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
private List<ArticleVisitors> visitors=new LinkedList<>();

@OneToMany(targetEntity=ArticleCharm.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
private List<ArticleCharm> charm=new LinkedList<>();

//id
public void setId(Integer id){
this.id=id;
}
public Integer getId(){
return id;
}
//login
public void setLogin(Login login){
this.login=login;
}
public Login getLogin(){
return login;
}
//bossId
public void setBossId(Integer bid){
this.bossId=bid;
}
public Integer getBossId(){
return bossId;
}
//createDate
public void setCreateDate(Date date){
this.createDate=date;
}
public Date getCreateDate(){
return createDate;
}
//modifyDate
public void setModifyDate(Date date){
this.modifyDate=date;
}
public Date getModifyDate(){
return modifyDate;
}
//authority
public void setAuthority(Integer author){
this.authority=author;
}
public Integer getAuthority(){
return authority;
}
//title
public void setTitle(String title){
this.title=title;
}
public String getTitle(){
return title;
}
//writer
public void setWriter(String writer){
this.writer=writer;
}
public String getWriter(){
return writer;
}
//contents
public void setContents(List<String> con){
this.contents=con;
}
public List<String> getContents(){
return contents;
}
//pictures
public void setPictures(List<ArticlePictures> pic){
this.pictures=pic;
}
public List<ArticlePictures> getPictures(){
return pictures;
}
//comments
public void setComments(List<ArticleComments> coms){
this.comments=coms;
}
public List<ArticleComments> getComments(){
return comments;
}
//visitors
public void setVisitors(List<ArticleVisitors> visitors){
this.visitors=visitors;
}
public List<ArticleVisitors> getVisitors(){
return visitors;
}
//charm
public void setCharm(List<ArticleCharm> charm){
this.charm=charm;
}
public List<ArticleCharm> getCharm(){
return charm;
}
}

至于Hibernate注解有哪些,注解如何使用,请参考系列博文:Spring Data JPA那些事。毕竟,JPA的默认实现就是Hibernate。