Spring 框架入门教程
1. 1. Spring 框架 2. 2. Spring 5 3. 3. Spring WebFlux 4. 4. 先介绍一下 Spring 5. 5. 什么是 Spring 依赖注入 6. 6. 什么是 Spring IoC 容器 和 Bean 7. 7. Spring Bean 的生命周期 8. 8. Spring REST 开发 9. 9. Spring REST XML 10. 10. Spring RestTemplate 开发 11. 11. Spring AOP 切面编程 12. 12. Spring AOP 方法调优 13. 13. Spring 注解详解 14. 14. Spring 核心注解之 @Autowired 15. 15. Spring 核心注解之 @RequestMapping 16. 16. Spring MVC 开发样例 17. 17. Spring MVC 开发指南 18. 18. Spring MVC 异常处理机制 19. 19. Spring MVC Validator 20. 20. Spring MVC 拦截器 21. 21. Spring MVC 文件上传 22. 22. Spring MVC 国际化(i18n) 23. 23. Spring MVC Hibernate MqSQL 24. 24. Spring ORM 25. 25. Spring ORM JPA 26. 26. Spring Data JPA 27. 27. Spring 事务管理 28. 28. 常用的 Spring JdbcTemplate 29. 29. Spring Security 简介 30. 30. Spring Security 教程 31. 31. Spring Security UserDetailsService 32. 32. Spring MVC 登录注销简单案例 33. 33. Spring Security Roles 34. 34. Spring Boot Tutorial 35. 35. Spring Boot Components 36. 36. Spring Boot CLI Hello World 37. 37. Spring Boot Initilizr Web 38. 38. Spring Boot Initilizr IDE 39. 39. Spring Boot Initilizr CLI 40. 40. Spring Boot Initilizr Tools 41. 41. Spring Boot MongoDB 42. 42. Spring Boot Redis Cache 43. 43. Spring Boot 常见面试问题 44. 44. Spring Batch 45. 45. Spring Batch 批处理示例 46. 46. Spring AMQP 47. 47. Spring RabbitMQ 48. 48. Spring AMQP RabbitMQ 49. 49. Apache ActiveMQ 安装与启动 50. 50. Spring ActiveMQ 教程 51. 51. Spring ActiveMQ 示例 52. 52. Spring JDBC 53. 53. Spring DataSource JNDI 54. 54. Spring Hibernate 55. 55. Spring Primefaces JPA 56. 56. Spring Primefaces MongoDB 57. 57. Spring Primefaces Hibernate 58. 58. SpringRoo Primefaces Hibernate 59. 59. Spring JSF 60. 60. Spring JDF Hibernate 61. 61. Spring Data MongoDB 62. 62. Spring 常见面试问题

54. Spring Hibernate

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。对于这个迁移,我们只需要进行以下配置更改。

  1. 将hibernate版本更改为4.3.5.Finalpom.xml文件文件,如上面的注解所示。
  2. 更改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.

您可以从下面的链接下载最终的项目,并与更多配置一起玩来了解更多。