- 浏览: 176866 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
xoxoj:
如果发现input输入框里包含这些全角的内容,jquery应该 ...
全角正则 -
TJYCHYANGCHENHUI:
不对吧!你的第一句话说错了好吧,在没有开启事务的情况下,sa ...
hibernate入门(三)Session中的主要方法 -
leonardleonard:
好帖
js公共函数(utils.js) -
xyqqjy:
朋友你和我的现状很像啊!
我离职快一年了,一直没有再做开发这一 ...
浮躁,我 -
djy1135:
确实需要静一下心! 一样一样来吧。 东西学不半扔了,跟没学差 ...
浮躁,我
1.事务引发的三层架构MVC讨论:
在前面的程序代码中多次用到了事务:
Transaction tx = s.beginTransaction();
对应的jdbc代码:connection. setAutoCommit(false);
.....
.....数据处理
.....
tx.commit();
对应的jdbc代码:connection.commit();
tx.rollback();
对应的jdbc代码:connection.rollback();
以上的三处事务相关的代码统称为“事务边界”。其实hibernate的事务本质是依赖jdbc的事务来实现,其实对于事务而言,它是应该由业务逻辑层来实现,但是事务所依赖的对象又出现在Model层,所以想严格按照MVC的原理来实现将相当难(在前面我们所写的代码中事务的处理是不符合mvc模式得),但是利用推出的EJB,SPRING这些框架将能达到此目的,下图展示了三层架构,与原始的MVC相比,多了一个持久层。
2.模拟session context[OSIV]:
>>步骤一,重写工具类,核心代码如下:
package com.asm.hibernate.utils;
public class HibernateUtilOSV {
private static SessionFactory sf;
private static ThreadLocal session = new ThreadLocal();
private HibernateUtilOSV() {
}
public static Session getThreadLocalSession() {
Session s = (Session) session.get();
if (s == null) {
s = getSession();
session.set(s);
}
return s;
}
public static void closeSession() {
Session s = (Session) session.get();
if (s != null) {
s.close();
session.set(null);
}
}
static {
Configuration cf = new Configuration();
cf.configure();
sf = cf.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sf;
}
public static Session getSession() {
return sf.openSession();
}
}
>>步骤二、导入servlet包,使用Filter. 内容如下:
package com.asm.hibernate.osv;
public class OpenSessionViewFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
Session s = null;
Transaction tx = null;
try {
s = HibernateUtilOSV.getThreadLocalSession();
tx = s.beginTransaction();
arg2.doFilter(arg0, arg1);
tx.commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
} finally {
HibernateUtilOSV.closeSession();
}
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
>>步骤三、Userdao:
package com.asm.hibernate.osv;
public class UserDao {
static void addUseDao(User user) {
HibernateUtilOSV.getThreadLocalSession().save(user);
}
}
原理流程分析:当有被Filter监测的请求到达此Filter时,Filter会利用工具类来获得一个Session,并用这个session打开事务,然后再把请求传给下一个Filter.当所有操作执行完成后再返回到这个Filter,如果没有任何异常便可以提交事务,否则回滚事务。这样便可以有效保证事务的完整性,而且有利于懒加载,因为在整个请求的过程中,Session一直未关闭,所以在filter不断向下传递的过程中可以放心的使用session来完成懒加载,这也是解决懒加载的一种方式。其实OpenSessionInView主要解决了两个问题:一是实现事务在逻辑层控制,二是利于懒加载的实现。 下面再来看看工具类:此工具类主要完成了两个工作:一是生成一个线程级的Session,即是说在一个线程的事务开启到事务结束,一直用的是同一个Session,这样有利于保证事务的完整性,而工具类主要借助了ThradLocal来生成这个线程级的Session。 二是完成Session的关闭。
3.使用Hibernate自带的SessionContext
>>步骤一、在主配置文件中增加如下内容:
<property name="current_session_context_class">thread</property>以支持事务边界。 说明:它实质也是利用ThreadLocal来管理Session实现多个操作共享一个Session,避免反复获取Session,并控制事务边界。需要注意的是,当我们打开此功能后再通过SessionFactory.getCurrentSession()来获取一个Session,这个Session不能调用close方法,因为当我们提交事务或者回滚事务都会引起这个Session关闭,而通常的事务最会被提交或回滚,所以我们永远不要在这样的Session中调用close方法。同样的它的一个重要作用就是在生成页面时保持Session打开(即OpenSessionInView),因此为懒加载提供了方便。 除了配置为thread外还可以配置值为“jta” ,配置成jta后主要JTA事务管理器来管理事务,jta事务管理器主要用在有多个数据库的情况
>>步骤二、重写工具类:核心代码如下:
package com.asm.hibernate.utils;
public class HibernateUtilSelf {
private static SessionFactory sf;
private HibernateUtilSelf() {
}
public static Session getThreadLocalSession() {
Session s = sf.getCurrentSession();
if (s == null) {
s = getSession();
}
return s;
}
static {
Configuration cf = new Configuration();
cf.configure();
sf = cf.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sf;
}
public static Session getSession() {
return sf.openSession();
}
}
>>编写测试类:
package com.asm.hibernate.osv;
public class UserTest {
public static void main(String[] args) {
User user = new User();
user.setName("richie");
user.setDate(new Date());
addUser(user);
}
static void addUser(User user) {
Session s = null;
Transaction ts = null;
try {
s = HibernateUtilSelf.getThreadLocalSession();
ts = s.beginTransaction();
s.save(user);
ts.commit();
} catch (HibernateException e) {
if (ts != null)
ts.rollback();
throw e;
} finally {
if (s != null)
// s.close(); //注意这里不能使用close,并注意下面的打印结果
System.out.println("s=" + s);
}
}
}
执行后的结果为:s=SessionImpl(<closed>)
4.悲观锁:
悲观地认为每个事务在操纵数据时,肯定会有其它的事务同时访问该数据资源,当前事务为防止自身受到影响,先将相关数据资源锁定,直到事务结束后释放锁定。
实现方式一:利用LockMode实现数据锁;原理是使用带有LockMode参数的load方法来实现数据加锁,LockMode主要有以下几种锁定方式:
锁定方式 功能
LockMode.NONE Hibernate的默认值,首先到缓存中检索,检测不到时连数据库
LockMode.READ 不管缓存,直接到数据库中加载。如果在实体配置文件中配置了版本元素,则比较缓存中的版本与数据库中的版本是否一致
LockMode.UPGRADE 在READ的基础上,如果数据库支持悲观锁,则执行select...for update,否则执行变通的select语句。
UPGRADE_NOWAIT 主要是针对Oracle数据库,在UPGRADE的基础上,如果执行select语句不能获得锁,则会抛出锁定异常
实现方式二、通过逻辑实现锁定数据;原理是在实体类的数据库表中设定一个boolean的字段,当这个字段为true,表示该数据正在被访问,此时记录被锁定。如果为false,则表示可以访问。 过程:(1)当访问的数据为false时,表示可以访问,此时修改字段为true,以避免其它对象访问,操作完成后再设此字段为false,以让等待的对象访问 (2)当访问数据据为true,表示不可被访问。
5.乐观锁:
乐观地认为每个事务在操纵数据时,很少有或者不会其它事务同时访问数据资源,因而不会在数据库层锁定,而是通过逻辑来实现版本控制。
实现方式一:<version>方式:为了方便操作新建一个名为OptimizeLock的项目.
>>步骤一,拷贝以前的User类及相应的实体配置文件等相关文件。
>>步骤二,在User类中增加private int version;及相应的get/set方法。Version名字可以随意取。
>>步骤三、修改配置文件:增加<version name="version"></version>属性,并注意在<class>元素中使用optimistic-lock="version"属性,这也是官方推荐使用的属性值。但不能使用none,因为它不支持乐观锁,也可这样说,即使我们为乐观锁做好了一切准备,但我们不想在某个实体对象中使用时,只需要配置optimistic-lock为none即可。
>>步骤四、编写测试类
package com.asm.hibernate.test;
public class VersionUserTest {
public static void main(String[] args) {
addUser();
update(1);
}
static void update(int id) {
Session s1 = null;
Session s2 = null;
Transaction tx1 = null;
Transaction tx2 = null;
try {
s1 = HibernateUtil.getSession();
tx1 = s1.beginTransaction();
User user1 = (User) s1.get(User.class, id);
System.out.println(user1.getName());
s2 = HibernateUtil.getSession();
tx2 = s2.beginTransaction();
User user2 = (User) s2.get(User.class, id);
user1.setName("user1Name");
user2.setName("user2Name");
tx1.commit();
tx2.commit();
} catch (HibernateException e) {
....
} finally {
....
}
}
static void addUser() {
...主要作用是增加一条记录以实现操作。
}
}
分析:在进行分析前,先提下笔者曾范的一个测试错误,由于是复制以前的代码,由于以前在User的配置文件中配置了二级缓存的“<cache usage="read-only"/>” ,这样执行时总是报“Can't write to a readonly object” 。由这点大家可以再细想下悲观锁的更多细节问题。下面来谈version,当我们向数据表中添加一个version字段,hibernate会控制此字段,当访问一条记录时,同时访问此记录的版本信息,如果对该记录做了修改,在提交事务时,hibernate会将访问时的版本信息与数据库中的版本信息进行对比,如果一致则提交修改并将原版本信息加1,否则撤销本次修改。 上面的两个session并分别有开启了两个事务,当提交第一个事务时,符合要求进行了提交。但我们再来提交第二个事务时,由于第一个事务修改了版本信息,尽管user1和user2最初获得的版本是一样得,但由于第一个事务提交修改了数据库中版本信息,所以第二个事务将不能被提交(如不能明白,请仔细阅读本段中的黑体字部份)。 请这样测试:执行完后(会报“Transaction not successfully started”异常)查数据表,然后再交换以上两个事务提交的顺序再执行,再查数据表。 另请不要深究异常处理。
实现方式二、<timestamp>
基本和方式一相同,只是在User类中增加一个Date类型的属性,同时在实体配置文件配置如下内容: <timestamp name="实体类的中Date类型的属性"></timestamp>
发表评论
-
hibernate入门(十二)一些细节问题分析
2010-07-29 11:17 7191. 实体配置文件中的类型问题 : 在前 ... -
hibernate入门(十)缓存
2010-07-29 11:11 6791. 模拟缓存并简要说明缓存实现原理 在myhib ... -
hibernate入门(九)关联关系中的高级应用_概述关联关系中的懒加载
2010-07-29 11:09 8065. 概述关联关系中的懒加载: (1) 一对 ... -
hibernate入门(九)关联关系中的高级应用_懒加载
2010-07-29 11:07 7194. 懒加载: 在前面我们已经对懒加载有所提及,现 ... -
hibernate入门(九)关联关系中的高级应用_继承关系
2010-07-29 10:59 9343. 继承关系 : 在前面的部门员工实例 ... -
hibernate入门(九)关联关系中的高级应用_inverse属性
2010-07-29 10:43 823inverse 的作用:询问是否放弃维护关系,默认是fals ... -
hibernate入门(九)关联关系中的高级应用_级联操作
2010-07-29 10:40 8301. 级联操作 : ... -
hibernate入门(八)其它集合类型
2010-07-29 10:38 791说明:在前面我们已经使用过set 集合类型,其实除了set ... -
hibernate入门(七)关联关系讨论_组件关系映射
2010-07-29 10:36 738典型实例:每个人有不同的名字,或者多个人可以是同一个名字,对于 ... -
hibernate入门(七)关联关系讨论_多对多关系映射
2010-07-29 10:31 747典型实例:一个学生可以有多个老师,同样一个老师可以有多个学生, ... -
hibernate入门(七)关联关系讨论_一对一关系映射
2010-07-29 10:27 885典型的实例:一个人有一个身份证,而一个身份证只属于某一个人。以 ... -
hibernate入门(七)关联关系讨论_一对多关系映射
2010-07-29 10:25 6692 .一对多关系映射: 上面提到的多个员工对应 ... -
hibernate入门(七)关联关系讨论_多对一关系映射
2010-07-29 10:22 7911 .多对一关系映射 : 一个部门有可以有多 ... -
hibernate入门(六)基本应用实例:Dao设计
2010-07-29 10:20 9721 .总体设计:设计User 对象及相关实体配置文件,工具 ... -
hibernate入门(五)完善工具类及HQL QBC初步相关
2010-07-29 10:17 10351 .无聊的讨论 : 在前面我们写了一个 ... -
hibernate入门(四)对象三种状态
2010-07-29 10:12 8331 .瞬时(transient ) ... -
hibernate入门(三)Session中的主要方法
2010-07-29 10:09 10521 .保存数据:save ,presist 说明 ... -
hibernate入门(二)优化代码
2010-07-29 10:07 7371 .为会么要优化 ... -
hibernate入门(一)第一个应用实例
2010-07-29 10:03 826一 、第一个应用实例 ...
相关推荐
本文是开发基于spring的web应用的入门文章,前端采用Struts MVC框架,中间层采用spring,后台采用Hibernate。 本文包含以下内容: •配置Hibernate和事务 •装载Spring的applicationContext.xml文件 •...
hibernate pdf 电子书 hibernate 入门 基本配置 持久化类 集合类 映射 事务和并发
Hibernate入门 OR映射技术 通过Hibernate API操纵数据库 检索策略和方式 数据库事务、并发、缓存与性能优化 高级配置。
文档内容包括:Hibernate入门、OR映射技术、通过Hibernate API操纵数据库、检索策略和方式、数据库事务、并发、缓存与性能优化、高级配置
第一章:Hibernate入门 包括:是什么、ORMapping原理、能干什么、有什么、怎么做(做什么) 第二章:Hibernate的HelloWorld 第三章:Hibernate的配置 包括:cfg配置、mapping配置、组件映射、事务配置、缓存配置 ...
Hibernate3.2官方中文参考手册,内容涉及Hibernate入门知识、配置、集合类映射、关联关系映射、组件、事务并发、批量处理、对象事件等知识。
Hibernate入门 OR映射技术 通过Hibernate API操纵数据库 检索策略和方式 数据库事务、并发、缓存与性能优化 高级配置
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门; 2. 体系结构(Architecture); 3. 配置; 4. 持久化类(Persistent Classes); 5. 对象/关系数据库映射基础(Basic O/R Mapping); 6. 集合类(Collections)映射; 7. 关联关系映射; 8. 组件(Component)...
手把手教会你使用hibernate Hibernate入门 OR映射技术 通过Hibernate API操纵数据库 检索策略和方式 数据库事务、并发、缓存与性能优化 高级配置
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
Hibernate4(关系映射,事务,原理,性能和二级缓存,最佳实践) Hibernate4(基本开发,入门,配置,CRUD)
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
详细介绍Hibernate 入门、继承映射、集合映射、实体映射、事务管理。
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
struts hibernate dwr 与Spring完全结合,实现用户列表、信息增、删、改、查、维护时用户重名提示等功能,还包括页面自动转码设置(web.xml),Hibernate管理服务按Bean名称拦截并进行Spring事务管理,完全由Spring...
Hibernate3.2官方中文参考手册,内容涉及Hibernate入门知识、配置、集合类映射、关联关系映射、组件、事务并发、批量处理、对象事件等知识。