Spring对ORM的支持之集成Hibernate3

2024-09-04 04:32

本文主要是介绍Spring对ORM的支持之集成Hibernate3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Hibernate是全自动的ORM框架,能自动为对象生成相应SQL并透明的持久化对象到数据库。

Spring2.5+ 版本支持Hibernate 3.1+ 版本,不支持低版本,Spring 3.0.5 版本提供对Hibernate 3.6.0 Final 版本支持。

8.2.1  如何集成

Spring通过使用如下Bean进行集成Hibernate:

  • LocalSessionFactoryBean :用于支持XML映射定义读取:

configLocation和configLocations:用于定义Hibernate配置文件位置,一般使用如classpath:hibernate.cfg.xml形式指定;

mappingLocations :用于指定Hibenate映射文件位置,如chapter8/hbm/user.hbm.xml;

hibernateProperties:用于定义Hibernate属性,即Hibernate配置文件中的属性;

dataSource:定义数据源;

hibernateProperties、dataSource用于消除Hibernate配置文件,因此如果使用configLocations指定配置文件,就不要设置这两个属性了,否则会产生重复配置。推荐使用dataSource来指定数据源,而使用hibernateProperties指定Hibernate属性。

  • AnnotationSessionFactoryBean:用于支持注解风格映射定义读取,该类继承LocalSessionFactoryBean并额外提供自动查找注解风格配置模型的能力:

annotatedClasses:设置注解了模型类,通过注解指定映射元数据。

packagesToScan:通过扫描指定的包获取注解模型类,而不是手工指定,如“cn.javass.**.model”将扫描cn.javass包及子包下的model包下的所有注解模型类。

接下来学习一下Spring如何集成Hibernate吧:

、准备jar 包:

首先准备Spring对ORM框架支持的jar包:

org.springframework.orm-3.0.5.RELEASE.jar  //提供对ORM框架集成

下载hibernate-distribution-3.6.0.Final包,获取如下Hibernate需要的jar包:

hibernate3.jar                       //核心包

lib\required\antlr-2.7.6.jar              //HQL解析时使用的包

lib\required\javassist-3.9.0.GA.jar       //字节码类库,类似于cglib

lib\required\commons-collections-3.1.jar  //对集合类型支持包,前边测试时已经提供过了,无需再拷贝该包了

lib\required\dom4j-1.6.1.jar            //xml解析包,用于解析配置使用

lib\required\jta-1.1.jar                 //JTA事务支持包

lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar //用于支持JPA

下载slf4j-1.6.1.zip(http://www.slf4j.org/download.html),slf4j是日志系统门面(Simple Logging Facade for Java),用于对各种日志框架提供给一致的日志访问接口,从而能随时替换日志框架(如log4j、java.util.logging):

slf4j-api-1.6.1.jar              //核心API

slf4j-log4j12-1.6.1.jar          //log4j实现

将这些jar包添加到类路径中。

2、 对象模型定义,此处使用第七章中的UserModel 

java代码:
package cn.javass.spring.chapter7;
public class UserModel {private int id;private String myName;//省略getter和setter
}

3、 Hibernate 映射定义(chapter8/hbm/user.hbm.xml ),定义对象和数据库之间的映射:

java代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping><class name="cn.javass.spring.chapter7.UserModel" table="test"><id name="id" column="id"><generator class="native"/></id><property name="myName" column="name"/></class>
</hibernate-mapping>

4、    数据源定义,此处使用第7 章的配置文件,即“chapter7/ applicationContext-resources.xml ”文件。

5、    SessionFactory 配置定义(chapter8/applicationContext-hibernate.xml ):

java代码:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource"/> <!-- 指定数据源 --><property name="mappingResources">     <!-- 指定映射定义 --><list><value>chapter8/hbm/user.hbm.xml</value></list></property><property name="hibernateProperties">   <!--指定Hibernate属性 --><props><prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop></props></property>
</bean>

6、    获取SessionFactory 

java代码:

package cn.javass.spring.chapter8;
//省略import
public class HibernateTest {private static SessionFactory sessionFactory;@BeforeClasspublic static void beforeClass() {String[] configLocations = new String[] {"classpath:chapter7/applicationContext-resources.xml","classpath:chapter8/applicationContext-hibernate.xml"};ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);sessionFactory = ctx.getBean("sessionFactory", SessionFactory.class);
}
}

此处我们使用了chapter7/applicationContext-resources.xml定义的“dataSource”数据源,通过ctx.getBean(“sessionFactory”, SessionFactory.class)获取SessionFactory。

7、 通过SessionFactory 获取Session 对象进行创建和删除表:

java代码:
@Before
public void setUp() {//id自增主键从0开始final String createTableSql = "create memory table test" + "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " + "name varchar(100))";sessionFactory.openSession().createSQLQuery(createTableSql).executeUpdate();
}
@After
public void tearDown() {final String dropTableSql = "drop table test";sessionFactory.openSession().createSQLQuery(dropTableSql).executeUpdate();
}

使用SessionFactory创建Session,然后通过Session对象的createSQLQuery创建本地SQL执行创建和删除表。

8、 使用SessionFactory 获取Session 对象进行持久化数据:

java代码:
@Test
public void testFirst() {Session session = sessionFactory.openSession();Transaction transaction = null;try {transaction = beginTransaction(session);UserModel model = new UserModel();model.setMyName("myName");session.save(model);} catch (RuntimeException e) {rollbackTransaction(transaction);throw e;} finally {commitTransaction(session);}
}
java代码:
private Transaction beginTransaction(Session session) {Transaction transaction = session.beginTransaction();transaction.begin();return transaction;
}
private void rollbackTransaction(Transaction transaction) {if(transaction != null) {transaction.rollback();}
}
private void commitTransaction(Session session) {session.close();
}

使用SessionFactory获取Session进行操作,必须自己控制事务,而且还要保证各个步骤不会出错,有没有更好的解决方案把我们从编程事务中解脱出来?Spring提供了HibernateTemplate模板类用来简化事务处理和常见操作。

8.2.2 使用HibernateTemplate

HibernateTimplate模板类用于简化事务管理及常见操作,类似于JdbcTemplate模板类,对于复杂操作通过提供HibernateCallback回调接口来允许更复杂的操作。

接下来示例一下HibernateTemplate的使用:

java代码:
@Test
public void testHibernateTemplate() {
HibernateTemplate hibernateTemplate =
new HibernateTemplate(sessionFactory);final UserModel model = new UserModel();model.setMyName("myName");hibernateTemplate.save(model);//通过回调允许更复杂操作hibernateTemplate.execute(new HibernateCallback<Void>() {@Overridepublic Void doInHibernate(Session session)throws HibernateException, SQLException {session.save(model);return null;}});
}

通过new HibernateTemplate(sessionFactory) 创建HibernateTemplate模板类对象,通过调用模板类的save方法持久化对象,并且自动享受到Spring管理事务的好处。

而且HibernateTemplate 提供使用HibernateCallback回调接口的方法execute用来支持复杂操作,当然也自动享受到Spring管理事务的好处。

8.2.3  集成Hibernate及最佳实践

类似于JdbcDaoSupport类,Spring对Hibernate也提供了HibernateDaoSupport类来支持一致的数据库访问。HibernateDaoSupport也是DaoSupport实现:

接下来示例一下Spring集成Hibernate的最佳实践:

1、  定义Dao 接口,此处使用cn.javass.spring.chapter7.dao. IUserDao 

2、  定义Dao 接口实现,此处是Hibernate 实现:

java代码:
package cn.javass.spring.chapter8.dao.hibernate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.javass.spring.chapter7.UserModel;
import cn.javass.spring.chapter7.dao.IUserDao;
public class UserHibernateDaoImpl extends HibernateDaoSupport implements IUserDao {private static final String COUNT_ALL_HQL = "select count(*) from UserModel";@Overridepublic void save(UserModel model) {getHibernateTemplate().save(model);}@Overridepublic int countAll() {Number count = (Number) getHibernateTemplate().find(COUNT_ALL_HQL).get(0);return count.intValue();}
}

此处注意首先Hibernate实现放在dao.hibernate包里,其次实现类命名如UserHibernateDaoImpl,即×××HibernateDaoImpl,当然如果自己有更好的命名规范可以遵循自己的,此处只是提个建议。

3 、进行资源配置,使用resources/chapter7/applicationContext-resources.xml 

、dao 定义配置,在chapter8/applicationContext-hibernate.xml 中添加如下配置:

java代码:
<bean id="abstractDao" abstract="true"><property name="sessionFactory" ref="sessionFactory"/>
</bean>   
<bean id="userDao"  class="cn.javass.spring.chapter8.dao.hibernate.UserHibernateDaoImpl" parent="abstractDao"/>

首先定义抽象的abstractDao,其有一个sessionFactory属性,从而可以让继承的子类自动继承sessionFactory属性注入;然后定义userDao,且继承abstractDao,从而继承sessionFactory注入;我们在此给配置文件命名为applicationContext-hibernate.xml表示Hibernate实现。

5、  最后测试一下吧(cn.javass.spring.chapter8. HibernateTest ):

java代码:
@Test
public void testBestPractice() {String[] configLocations = new String[] {"classpath:chapter7/applicationContext-resources.xml","classpath:chapter8/applicationContext-hibernate.xml"};ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);IUserDao userDao = ctx.getBean(IUserDao.class);UserModel model = new UserModel();model.setMyName("test");userDao.save(model);Assert.assertEquals(1, userDao.countAll());
}

和Spring JDBC框架的最佳实践完全一样,除了使用applicationContext-hibernate.xml代替了applicationContext-jdbc.xml,其他完全一样。也就是说,DAO层的实现替换可以透明化。

8.2.4  Spring+Hibernate的CRUD

Spring+Hibernate CRUD(增删改查)我们使用注解类来示例,让我们看具体示例吧:

、首先定义带注解的模型对象UserModel2 

  • 使用JPA注解@Table指定表名映射;
  • 使用注解@Id指定主键映射;
  • 使用注解@ Column指定数据库列映射;
java代码:
package cn.javass.spring.chapter8;
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
@Table(name = "test")
public class UserModel2 {@Id @GeneratedValue(strategy = GenerationType.AUTO)private int id;@Column(name = "name")private String myName;//省略getter和setter
}

2、  定义配置文件(chapter8/applicationContext-hibernate2.xml ):

2.1、         定义SessionFactory 

此处使用AnnotationSessionFactoryBean通过annotatedClasses属性指定注解模型来定义映射元数据;

java代码:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>  <!-- 1、指定数据源 --><property name="annotatedClasses">           <!-- 2、指定注解类 --><list><value>cn.javass.spring.chapter8.UserModel2</value></list>
</property><property name="hibernateProperties"><!-- 3、指定Hibernate属性 --><props><prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop></props></property>
</bean>

2.2、 定义HibernateTemplate  

java代码:
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"><property name="sessionFactory" ref="sessionFactory"/>
</bean>

、最后进行CURD 测试吧:

java代码:
@Test
public void testCURD() {String[] configLocations = new String[] {"classpath:chapter7/applicationContext-resources.xml","classpath:chapter8/applicationContext-hibernate2.xml"};ApplicationContext ctx =  new ClassPathXmlApplicationContext(configLocations);HibernateTemplate hibernateTemplate =  ctx.getBean(HibernateTemplate.class);UserModel2 model = new UserModel2();model.setMyName("test");insert(hibernateTemplate, model);select(hibernateTemplate, model);update(hibernateTemplate, model);delete(hibernateTemplate, model);
}private void insert(HibernateTemplate hibernateTemplate, UserModel2 model) {hibernateTemplate.save(model);
}
private void select(HibernateTemplate hibernateTemplate, UserModel2 model) {UserModel2 model2 = hibernateTemplate.get(UserModel2.class, 0);Assert.assertEquals(model2.getMyName(), model.getMyName());List<UserModel2> list = hibernateTemplate.find("from UserModel2");Assert.assertEquals(list.get(0).getMyName(), model.getMyName());
}
private void update(HibernateTemplate hibernateTemplate, UserModel2 model) {model.setMyName("test2");hibernateTemplate.update(model);
}
private void delete(HibernateTemplate hibernateTemplate, UserModel2 model) {hibernateTemplate.delete(model);
}

Spring集成Hibernate进行增删改查是不是比Spring JDBC方式简单许多,而且支持注解方式配置映射元数据,从而减少映射定义配置文件数量。

这篇关于Spring对ORM的支持之集成Hibernate3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135000

相关文章

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.