Spring Hibernate集成示例教程(Spring 4 + Hibernate 3和Hibernate 4)
Spring是最常用的Java EE框架之一,而Hibernate是最流行的ORM框架。
这就是为什么Spring Hibernate组合在企业应用程序中大量使用的原因。
最近,我为Spring教程和Hibernate教程写了很多书,因此关于Spring Hibernate集成的帖子由来已久。
Spring Hibernate
今天,在本教程中,我们将使用Spring 4并将其与Hibernate 3集成,然后更新同一项目以使用Hibernate4。
由于Spring和Hibernate都有很多版本,并且Spring ORM工件同时支持Hibernate 3和Hibernate 4。
,最好列出我在项目中使用过的所有依赖项。
请注意,我注意到所有Spring和休眠版本都不兼容,以下版本对我有用,因此我认为它们兼容。
如果您正在使用其他版本并获取到java.lang.NoClassDefFoundError,则意味着它们不兼容。
主要是因为Hibernate类从一个包移到另一个包导致此错误。
例如,在最新的休眠版本中,将org.hibernate.engine.FilterDefinition类移至org.hibernate.engine.spi.FilterDefinition。
- Spring Framework版本:4.0.3.3
- Hibernate Core和Hibernate EntityManager版本:3.6.9.Final和4.3.5.Final
- Spring ORM版本:4.0.3.3
数据库设置
我正在为项目使用MySQL数据库,因此下面的setup.sql脚本将为该示例创建必要的表。
CREATE TABLE `Person` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '', `country` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; commit;
Spring Hibernate集成示例项目结构
下图显示了最终的项目结构,我们将逐一介绍每个组件。
Maven依赖
我们将首先在pom.xml文件中查找所有必需的依赖项及其版本。
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples</groupId>
<artifactId>SpringHibernateExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
<!-- Hibernate/JPA -->
<!-- <hibernate.version>4.3.5.Final</hibernate.version> -->
<hibernate.version>3.6.9.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
<dependencies>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Spring ORM support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>
Spring和Hibernate集成项目的重要依赖项是:
spring-context和spring-tx用于核心Spring功能。
请注意,我正在使用版本4.0.3.RELEASE。依赖Spring-orm来获得Spring ORM的支持,在我们的Spring项目中进行休眠集成是必需的。
Hibernate框架的hibernate-entitymanager和hibernate-core依赖项。
注意,版本是3.6.9.Final,要使用Hibernate 4,我们需要将其更改为4.3.5.Final,如上pom.xml文件中所述。mysql-connector-java用于数据库连接的MySQL驱动程序。
模型类或者实体Bean
我们可以使用基于Hibernate XML的映射以及基于JPA注释的映射。
其中我使用JPA注释进行映射,因为hibernate提供了JPA实现。
package com.theitroad.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Entity bean with JPA annotations
* Hibernate provides JPA implementation
* @author hyman
*
*/
@Entity
@Table(name="Person")
public class Person {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString(){
return "id="+id+", name="+name+", country="+country;
}
}
DAO类
我们将在DAO类中实现两个方法,第一个方法将Person对象保存到表中,第二个将从表中获取所有记录并返回Persons列表。
package com.theitroad.dao;
import java.util.List;
import com.theitroad.model.Person;
public interface PersonDAO {
public void save(Person p);
public List<Person> list();
}
上面的DAO类实现如下。
package com.theitroad.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.theitroad.model.Person;
public class PersonDAOImpl implements PersonDAO {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void save(Person p) {
Session session = this.sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.persist(p);
tx.commit();
session.close();
}
@SuppressWarnings("unchecked")
@Override
public List<Person> list() {
Session session = this.sessionFactory.openSession();
List<Person> personList = session.createQuery("from Person").list();
session.close();
return personList;
}
}
注意,这是我们使用Hibernate相关类的唯一地方。
这种模式使我们的实现灵活且易于从一种技术迁移到另一种技术。
例如,如果我们要使用iBatis ORM框架,我们所需要做的就是为iBatis提供DAO实现,然后更改spring bean配置文件。
在上面的示例中,我正在使用Hibernate会话事务管理。
但是我们也可以使用带有@Transactional注释的Spring声明式事务管理,更多内容请参见Spring Transaction Management。
用于Hibernate 3集成的Spring Bean配置文件
首先让我们看一下Hibernate 3集成所需的spring bean配置,稍后我们将详细研究。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:tx="https://www.springframework.org/schema/tx" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" <property name="url" value="jdbc:mysql://localhost:3306/TestDB" <property name="username" value="hyman" <property name="password" value="hyman123" </bean> <!-- Hibernate 3 XML SessionFactory Bean definition--> <!-- <bean id="hibernate3SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" <property name="mappingResources"> <list> <value>person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect </value> </property> </bean> --> <!-- Hibernate 3 Annotation SessionFactory Bean definition--> <bean id="hibernate3AnnotatedSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" <property name="annotatedClasses"> <list> <value>com.theitroad.model.Person</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.show_sql">false</prop> </props> </property> </bean> <bean id="personDAO" class="com.theitroad.dao.PersonDAOImpl"> <property name="sessionFactory" ref="hibernate3AnnotatedSessionFactory" </bean> </beans>
我们可以通过两种方式向Hibernate提供数据库连接详细信息,首先是将所有内容传递给" hibernateProperties",其次是创建一个DataSource,然后将其传递给休眠状态。
我更喜欢第二种方法,这就是为什么我们有Apache Commons DBCP依赖项来通过设置数据库连接属性来创建" BasicDataSource"的原因。
对于Spring和Hibernate 3集成,Spring ORM提供了两个类–休眠映射基于XML时的org.springframework.orm.hibernate3.LocalSessionFactoryBean和基于注释的映射的org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean。
如果您使用的是基于XML的映射,则在注释中提供了LocalSessionFactoryBean的简单bean配置。
AnnotationSessionFactoryBean扩展了LocalSessionFactoryBean类,因此它具有休眠集成的所有基本属性。
这些属性是可以自我理解的,并且大多与休眠有关,因此我将不对其进行详细介绍。
但是,如果您想知道hibernateProperties,annotatedClasses来自何处,则需要研究bean类的源代码。
请注意personDAO的bean定义,就像我之前说的,如果我们必须切换到其他ORM框架,则需要在此处更改实现类并设置所需的任何其他属性。
Spring 4 Hibernate 3测试程序
现在我们的设置已经准备就绪,让我们编写一个简单的程序来测试我们的应用程序。
package com.theitroad.main;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.theitroad.dao.PersonDAO;
import com.theitroad.model.Person;
public class SpringHibernateMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
PersonDAO personDAO = context.getBean(PersonDAO.class);
Person person = new Person();
person.setName("hyman"); person.setCountry("San Franceco");
personDAO.save(person);
System.out.println("Person::"+person);
List<Person> list = personDAO.list();
for(Person p : list){
System.out.println("Person List::"+p);
}
//close resources
context.close();
}
}
当我们执行上述程序时,由于没有正确设置日志记录,因此会得到很多与Hibernate相关的输出,但这超出了本教程的范围。
但是,我们得到了程序生成的以下输出。
Person::id=3, name=hyman, country=San Franceco Person List::id=1, name=hyman, country=San Franceco Person List::id=2, name=hyman, country=San Franceco Person List::id=3, name=hyman, country=San Franceco
Spring 4 Hibernate 4集成更改
现在,让我们将应用程序更改为使用Hibernate 4而不是Hibernate3。
对于此迁移,我们只需要进行以下配置更改。
将pom.xml文件中的休眠版本更改为4.3.5.Final,如上面的注释所示。
更改spring bean配置文件,到现在为止,您必须已经知道Spring bean配置文件是spring和hibernate框架集成的关键。
下面的spring bean配置文件将适用于Spring 4和Hibernate 4版本。
对于hibernate 4,我们需要为SessionFactory bean使用org.springframework.orm.hibernate4.LocalSessionFactoryBean,Spring ORM合并了Hibernate 3的两个类,现在有一个类,这样可以避免混淆。
所有其他配置与以前相同。

