Spring是最常用的J2EE框架之一Hibernate是最流行的ORM框架。这就是为什么户管理系统在企业应用程序中经常使用组合。最近我写了很多关于Spring教程和Hibernate教程,所以一个帖子spring hibernate集成已经很久了。
目录
户管理系统
今天在本教程中,我们将使用Spring4并将其与Hibernate3集成,然后将同一个项目更新为使用Hibernate4。由于Spring和Hibernate都有很多版本,Spring Orm工件同时支持hibernate3和hibernate4,所以列出我在项目中使用过的所有依赖项是很好的。
请注意,我已经注意到所有的spring和hibernate版本都不兼容,下面的版本对我很有用,所以我认为它们是兼容的。如果你使用其他版本java.lang.NoClassDefFoundError
, then it means that they are not compatible. Mostly it’s because Hibernate classes are moved from one package to another causing this error. For example org.hibernate.engine.FilterDefinition
class is moved to org.hibernate.engine.spi.FilterDefinition
in latest hibernate versions.
- Spring框架版本:4.0.3.RELEASE
- Hibernate Core和Hibernate EntityManager版本:3.6.9.Final和4.3.5.Final
- Spring Orm版本:4.0.3.RELEASE
数据库设置
我在我的项目中使用MySQL数据库,如下所示安装程序.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;
springhibernate集成示例项目结构
下图显示了项目的最终结构,我们将逐一介绍每个组件。
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上下文和springtx用于核心spring功能。请注意,我使用的是版本4.0.3.RELEASE。
- Spring Orm依赖于Spring Orm支持,这是spring项目中hibernate集成所必需的。
- hibernate entitymanager和hibernate核心依赖关系。注意,版本是3.6.9.Final,对于使用Hibernate4,我们只需要将其更改为4.3.5.Final,如上面所述pom.xml文件文件。
- 用于数据库连接的mysql连接器java for mysql驱动程序。
模型类或实体Bean
我们可以使用Hibernate基于XML的映射以及基于JPA注解的映射。这里我使用JPA注解进行映射,因为hibernate提供了JPA实现。
package com.journaldev.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 pankaj
*
*/
@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对象保存到表中,第二个方法将从表中获取所有记录并返回Person列表。
package com.journaldev.dao;
import java.util.List;
import com.journaldev.model.Person;
public interface PersonDAO {
public void save(Person p);
public List<Person> list();
}
上面的DAO类实现如下所示。
package com.journaldev.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.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会话事务管理。但是我们也可以使用Spring声明性事务管理@Transactional
annotation, read more at Spring事务管理.
用于hibernate3集成的Spring Bean配置文件
让我们先看看hibernate3集成所需的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"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
<property name="username" value="pankaj" />
<property name="password" value="pankaj123" />
</bean>
<!-- Hibernate 3 XML SessionFactory Bean definition-->
<!-- <bean id="hibernate3SessionFactory"
>
<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"
>
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.journaldev.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">
<property name="sessionFactory" ref="hibernate3AnnotatedSessionFactory" />
</bean>
</beans>
有两种方法可以向Hibernate提供数据库连接详细信息,第一种方法是将所有内容传递给HibernatehibernateProperties
and second by creating a DataSource and then passing it to hibernate. I prefer the second approach, that’s why we have 阿帕奇 Commons DBCP dependency to create a BasicDataSource
by setting database connection properties.
对于Spring和Hibernate3集成,Spring对象关系映射提供两个类–;org.springframework.orm.hibernate3.LocalSessionFactoryBean
when hibernate mappings are XML based and org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
for annotations based mapping. I have provided simple bean configuration of LocalSessionFactoryBean
in comments, if you are using XML based mappings. AnnotationSessionFactoryBean
extends LocalSessionFactoryBean
class, so it has all the basic properties for hibernate integration.
这些属性是可以自我理解的,并且大部分与hibernate相关,所以我将不详细介绍它们。但是如果你想知道从哪里来的话Hibernate属性,注解类接下来,您需要查看bean类的源代码。
注意bean的定义珀森道,就像我前面说的,如果我们必须切换到其他ORM框架,我们需要在这里更改实现类,并设置我们需要的任何其他属性。
spring4hibernate3测试程序
我们的设置已经就绪,让我们编写一个简单的程序来测试我们的应用程序。
package com.journaldev.main;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.journaldev.dao.PersonDAO;
import com.journaldev.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("Pankaj"); person.setCountry("India");
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=Pankaj, country=India
Person List::id=1, name=Pankaj, country=India
Person List::id=2, name=Pankaj, country=India
Person List::id=3, name=Pankaj, country=India
spring4hibernate4集成变更
现在让我们将应用程序更改为使用Hibernate 4而不是Hibernate 3。对于这个迁移,我们只需要进行以下配置更改。
- 将hibernate版本更改为4.3.5.Finalpom.xml文件文件,如上面的注解所示。
- 更改Spring Bean配置文件,到目前为止,您一定已经知道Spring Bean配置文件是spring和hibernate框架集成的关键。下面的Spring Bean配置文件将适用于spring4和hibernate4版本。
<?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" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/TestDB" /> <property name="username" value="pankaj" /> <property name="password" value="pankaj123" /> </bean> <!-- Hibernate 4 SessionFactory Bean definition --> <bean id="hibernate4AnnotatedSessionFactory" > <property name="dataSource" ref="dataSource" /> <property name="annotatedClasses"> <list> <value>com.journaldev.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"> <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" /> </bean> </beans>
对于Hibernate4,我们需要使用
org.springframework.orm.hibernate4.LocalSessionFactoryBean
for SessionFactory bean, Spring ORM has merged both the classes for Hibernate 3 and there is a single class now, this is good to avoid confusion. All the other configurations are same as before.
就这样,我们的项目成功地迁移到了Hibernate4,整洁就是这样。只要换一下SpringHibernateMain
class to use spring4.xml
for beans configuration and it will work fine, you will get same output as before.
您可以从下面的链接下载最终的项目,并与更多配置一起玩来了解更多。