跟我学Spring3(8.2):对ORM的支持之集成Hibernate3
8.2 集成Hibernate3
Hibernate是全自动的ORM框架,能自动为对象生成相应SQL并透明的持久化对象到数据库。
Spring2.5+版本支持Hibernate 3.1+版本,不支持低版本,Spring3.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吧:
1、准备jar包:
首先准备Spring对ORM框架支持的jar包:
org.springframework.orm-3.0.5.RELEASE.jar //提供对ORM框架集成 |
下载hibernate-distribution-3.6.0.Final包,获取如下Hibernate需要的jar包:
|
下载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:
1
2
3
4
5
6
|
package cn.javass.spring.chapter7;
public class UserModel {
private int id;
private String myName;
//省略getter和setter
}
|
3、Hibernate映射定义(chapter8/hbm/user.hbm.xml),定义对象和数据库之间的映射:
1
2
3
4
5
6
7
8
9
10
|
<?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):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package cn.javass.spring.chapter8;
//省略import
public class HibernateTest {
private static SessionFactory sessionFactory;
@BeforeClass
public 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对象进行创建和删除表:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@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对象进行持久化数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@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);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@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>() {
@Override
public 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实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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" ;
@Override
public void save(UserModel model) {
getHibernateTemplate().save(model);
}
@Override
public 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:
4、dao定义配置,在chapter8/applicationContext-hibernate.xml中添加如下配置:
1
2
3
4
|
<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):
1
2
3
4
5
6
7
8
9
10
11
12
|
@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(增删改查)我们使用注解类来示例,让我们看具体示例吧:
1、首先定义带注解的模型对象UserModel2:
- 使用JPA注解@Table指定表名映射;
- 使用注解@Id指定主键映射;
- 使用注解@ Column指定数据库列映射;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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属性指定注解模型来定义映射元数据;
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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 :
1
2
3
|
<bean id= "hibernateTemplate" class = "org.springframework.orm.hibernate3.HibernateTemplate" >
<property name= "sessionFactory" ref= "sessionFactory" />
</bean>
|
3、最后进行CURD测试吧:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@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方式简单许多,而且支持注解方式配置映射元数据,从而减少映射定义配置文件数量。
跟我学Spring3(8.2):对ORM的支持之集成Hibernate3相关推荐
- 【第一章】 Spring概述 —— 跟我学Spring3
为什么80%的码农都做不了架构师?>>> 1.1 Spring概括 1.1.1 Spring是什么 Spring是一个开源的轻量级Java SE(Java 标准版本)/Ja ...
- 跟我学spring3 电子书下载(完)
感谢iteye各位网友对我的支持,在此谢过了! 一.<跟我学spring3>电子书下载地址: <跟我学spring3> (1-7 和 8-13) http://jinnian ...
- 一、《跟我学spring3》电子书下载地址:
<跟我学spring3> (1-7 和 8-13) http://jinnianshilongnian.iteye.com/blog/pdf 跟我学spring3系列 word原版 下载 ...
- 最新 跟我学spring3 电子书下载
下载地址:http://jinnianshilongnian.iteye.com/blog/pdf 注:图片因为是外链,无法生成在pdf中(最好还是看博客吧). 目录: [第二章] IoC 之 2.1 ...
- AgileEAS.NET 4.0重构裁剪,新的ORM、支持Linq,正式支持WPF,开放更多的接口
很久没有和大家交流了,今天出来给大家汇报一下AgileEAS.NET平台的最新进展: AgileEAS.NET是一套企业级的快速开发平台或者说是中间件,主要服务于中小软件企业,以提高软件企业的有效生产 ...
- asp.net mysql 读写分离_[ASP.net教程]SqlSugar ORM已经支持读写分离
[ASP.net教程]SqlSugar ORM已经支持读写分离 0 2016-11-26 23:00:12 目前只有MYSQL版 3.5.2.9 支持,其库版本12月3号更新该功能 用例讲解using ...
- Spring3.0.5源码扩展支持AOP 获取HttpServletResponse
Spring3.0.5源码扩展支持AOP 获取HttpServletResponse.老项目直接升级Spring版本风险无法评估,所以直接扩展Spring包支持低版本没有的功能. 目录 Spring扩 ...
- Resource通配符路径 ——跟我学spring3
转自: https:// jinnianshilongnian.iteye.com/blog/1416322 转载于:https://www.cnblogs.com/sharpest/p/108852 ...
- 【第二章】 IoC 之 2.1 IoC基础 ——跟我学Spring3
2.1.1 IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器 ...
最新文章
- 英特尔支持员工自带设备办公
- 最长子序列和 动态规划python_算法基础之python实现动态规划中数字三角形和最长上升子序列问题...
- Android 五大存储方式具体解释
- python 下载文件 限速-Python网络爬虫---scrapy通用爬虫及反爬技巧
- 小程序监听android返回键,微信小程序左上角返回按钮触发事件
- Call to localhost/127.0.0.1:9000 failed on connection exception:java.net.ConnectException的解决方案
- 一个很详细的web.xml配置文件详解
- KCP - A Fast and Reliable ARQ Protocol
- android 2d 漫画界面,开源漫画项目,部分界面仿有妖气
- 2017知乎看山杯总结(多标签文本分类)
- Html5开发小游戏看你有多色
- leetcode 有效的括号
- 如果iis的配置文件 applicationHost.config坏掉了, 会在 C:\inetpub\history\ 中存储历史备份。复制过去还原就可以了-摘自网络...
- 用 js 开启本地服务器,实现短信发送
- LINUX暂停、挂起进程,开启进程
- jmeter监听器之用表格察看结果(View Results in Table)
- Java自动化测试调试中遇到的问题
- 几种常见的开发语言对比
- 互联网最后一个绯闻女友出嫁 大众点评联姻腾讯
- apache IOUtils的读取文件并转化为clazz
热门文章
- 【错误记录】Ubuntu 修改 hosts 文件 ( 使用 gedit /etc/hosts 命令打开并修改 hosts 文件 )
- 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 调试进程 ATTACH 附着目标进程 | 读取目标函数寄存器值并存档 )
- 【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 修改 7zr 交叉编译脚本 Android.mk | 交叉编译 lib7zr.so 动态库 )
- 【运筹学】运输规划、表上作业法总结 ( 运输规划模型 | 运输规划变量个数 | 表上作业法 | 最小元素法 | 差额 Vogel 法 ★ | 闭回路法 ) ★★★
- 【鸿蒙 HarmonyOS】UI 组件 ( 多选按钮 | Checkbox 组件 )
- 【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
- 【Android FFMPEG 开发】FFMPEG AVFrame 图像格式转换 YUV - RGBA ( 获取 SwsContext | 初始化图像数据存储内存 | 图像格式转换 )
- 【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 )
- 字符编码以及文件处理