本文主要介绍:

1 悲观锁和乐观锁

2 使用版本号控制并发访问

3 flush方法和批量更新的问题

4 DetachedCriteria

5 N + 1 次查询

6 使用sql进行查询

7 注解方式

一、悲观锁和乐观锁

问题:有两个人,同时打开了一个贴子,进行编辑,结果会怎么样? 后提交的,有可能会把先提交的冲掉。

比如一个贴子,发表者是张三

第一个人,改成李四,第二个改成王五,后提交,结果最后是王五,李四没了

==悲观锁: 操作员得到数据以后,别人就不能修改,直到他修改完成,事务提交后才能进行

==乐观锁: 加标志位,以标位(版本号)的形式进行控制

假如说读过来的时候它的版本号是0,然后它就会去提交,提交会更新这个版本号,比如给它加一,如果同时有另一个人也读了这个版本是0的数据,他后提交,提交的时候,发现版本号不是0了,证明这东西被别人动过了,要么重新读入,要么放弃修改。

Hibernate支持乐观锁。当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data)。Hibernate有2种机制可以解决这个问题:

乐观锁和悲观锁。这里我们只讨论乐观锁。

Hibernate乐观锁,能自动检测多个事务对同一条数据进行的操作,并根据先胜原则,提交第一个事务,其他的事务提交时则抛出org.hibernate.StaleObjectStateException异常。

二、使用版本号控制并发访问

1) 在数据库中增加一个字段, versionNo (叫什么名都可以),整型 (或timestamp 型)

2) 对应的实体类中,也加一个相同的字段

3) 在配置文件  Userinfo.xml  中增加一个配置    <version name="versionNo" />  //放在id之后,所有的其他属性之前

//例子
Userinfo user1=(Userinfo) HibUtil.get(Userinfo.class,505 );
Userinfo user2=(Userinfo) HibUtil.get(Userinfo.class,505 ); //user1 和 user2 对应着数据库中的同一条数据 try{
user1.setUserName("这是张三给起的名");
HibUtil.update(user1);
user2.setUserName("这是赵明明给启的名");
HibUtil.update(user2);
}
catch(StaleObjectStateException ex ){
System.out.println("数据已被别人修改!保存失败");
} /*org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction */

三、flush方法和批量更新的问题

//例一
public static void main(String[] args) {
Session s=HibUtil.getSession(); Userinfo user=new Userinfo();
user.setUserName("aaa"); Userinfo user2=new Userinfo();
user2.setUserName("aaa"); Transaction tx=s.beginTransaction(); s.save(user); //key
s.save(user2); // //s.flush(); //强制进行缓存的同步 System.out.println("--------我是不是先打印???----------"); //横线出现在save之前 tx.commit(); HibUtil.closeSession(); }

说明:

1)如果主键生成器是hilo

在不写 flush的情况下,可以发现横线是先输出,再执行save,因为hibernate总是试图把进行数据库访问的操作往后拖。上面的两条save语句,实际上是先把数据添到一级缓存中了,在最后commit 的时候,再进行数据库访问

2)如果加上 s.flush(); 表示强制要求hibernate刷新一级缓存中的数据,这时hibernate被迫,要将缓存中的数据存到数据库中,所以必须执行sql语句, 横线就会出现在save 之后了。

3)如果 主键生成器改成 native , 由于hibernate只有在知道主键的情况下才能进行一级缓存的填充,而native主键生成器是必须把数据保存到数据库以后才能得到生成的主键的,所以save方法会先执行。

用StatelessSession接口:它不和一级缓存、二级缓存交互,也不触发任何事件、监听器、拦截器,通过该接口的操作会立刻发送给数据库,与JDBC的功能一样。

StatelessSession s = sessionFactory.openStatelessSession(); 该接口的方法与Session类似

StatelessSession 没有 save 但有 insert

四、DetachedCriteria

最大的好处,是可以在Session外进行创建

 //例子
public class UserAction {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in); System.out.println("请输入用户名");
String userName=scan.nextLine(); System.out.println("请输备注");
String note=scan.nextLine(); DetachedCriteria dc= DetachedCriteria.forClass(Userinfo.class); if(userName!=null && (!"".equals(userName))){
dc.add(Restrictions.eq("userName", userName));
}
if(note!=null && (!"".equals(note))){
dc.add(Restrictions.eq("note", note));
} UserDao dao=new UserDao();
List<Userinfo> userList=dao.search(dc); System.out.println("================结果================");
for (Userinfo u : userList) {
System.out.println(u);
}
} } public class UserDao { // 多条件查询
public List<Userinfo> search(DetachedCriteria dc) {
try {
Session s = HibUtil.getSession();
Criteria c = dc.getExecutableCriteria(s);
return c.list();
} finally {
HibUtil.closeSession();
}
} }

五、N + 1 次查询

用Query.iterator可能会有 N+1次查询。n+1次查询,是指第一次,只查出来id, 然后才查它的内容,而且多数是从缓存里拿的。

// 注意,这里在使用 q.iterate() 这种迭代的时候才会出现 N+1 次查询 

                public static void queryUser(){
Session s=HibUtil.getSession();
Query q=s.createQuery("from UserInfo");
Iterator<UserInfo> it=q.iterate(); while(it.hasNext()){
UserInfo u=it.next();
System.out.println(u.getUserName());
} s.close();
}

六、使用sql进行查询

例一:

 public static void main(String[] args) {
List<Userinfo > userList=getUserList();
for (Userinfo u : userList) {
System.out.println(u);
}
} public static List<Userinfo> getUserList() {
try {
Session s = HibUtil.getSession();
// s.createQuery(queryString);
String sql = "select * from userinfo"; //用的sql语句,后面是表名
SQLQuery q = s.createSQLQuery(sql).addEntity(Userinfo.class); //不要忘了指定类型
return q.list();
} finally {
HibUtil.closeSession();
}
}

例二 :

使用sql进行关联查询,返回的结果 List<Object[]>

//main 方法 :
List<Object[]> listObj=getUserList2();
for (Object[] fields : listObj) {
for (Object field : fields) {
System.out.print(field +"\t");
} System.out.println();
} public static List<Object[]> getUserList2(){
try {
Session s = HibUtil.getSession();
String sql="select a.id,a.fahao,b.name from nigu a left join niguan b on a.niguan_id=b.id";
SQLQuery q = s.createSQLQuery(sql);
return q.list(); } finally {
HibUtil.closeSession();
}
}

例三:

使用Dto进行数据传输  (Dto 是数据传输对象)

//main 方法:
List<NiGuDto> niguList=getUserList3();
for (NiGuDto n : niguList) {
System.out.println(n);
} public static List<NiGuDto> getUserList3(){
try {
Session s = HibUtil.getSession();
String sql="select a.id,a.fahao,b.name from nigu a left join niguan b on a.niguan_id=b.id";
Query q=s.createSQLQuery(sql);
q.setResultTransformer(Transformers.aliasToBean(NiGuDto.class)); //进行数据传输对象的处理 return q.list(); } finally {
HibUtil.closeSession();
}
}

七、注解方式

1) 导包

2) 配置

@Entity
@Table(name="User_info")
public class Userinfo implements java.io.Serializable {
private String note;
private Integer versionNo;
private Integer id; //主键相关的注解一般都放在get方法
private String userName; @Id
@GeneratedValue
public Integer getId() {
return this.id;
} ....
}

注意:

//1.在主配置文件中要加入
<mapping class="cat.beans.Userinfo" /> //2.在工具类中的
//Configuration cxf=new Configuration(); 要换成下面的写法
Configuration cxf=new AnnotationConfiguration(); //3.3 要这样做

Java框架之Hibernate(四)的更多相关文章

  1. java框架篇---hibernate入门

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDB ...

  2. JAVA框架:hibernate(四)

    一.绑定本地session 原理:之前connection实现事务一个道理,2种方法:1.变量下传.2.因为servlet是单线程,和本地当前线程绑定. 配置: 1)配置核心配置文件hibernate ...

  3. Java框架之Hibernate(三)

    本文主要讲解: 1 级联 cascade 关键字 2 级联删除 3 inverse 关键字 4 懒加载 5 缓存的模拟 6 Hibernate 的一级缓存 7 Hibernate 的二级缓存 一.级联 ...

  4. Java框架之Hibernate(一)

    一.Hibernate - 核心接口 它是  JBoss Community team (社区团队) 开发的.Hibernate 是一个开源的,对象关系模型框架 (ORM),它对JDBC进行了轻量的封 ...

  5. java框架之Hibernate(2)-持久化类&主键生成策略&缓存&事务&查询

    持久化类 概述 持久化:将内存中的对象持久化到数据库中的过程就是持久化.Hibernate 就是用来进行持久化的框架. 持久化类:一个 Java 对象与数据库的表建立了映射关系,那么这个类在 Hibe ...

  6. Java框架之Hibernate(二)

    本文主要介绍: 1 Criteria 接口 2 用 myeclipse 反向生成 3 hibernate  主键生成策略 4 多对一 5 一对多 6 使用List 集合的一对多 7 多对多 一.Cri ...

  7. JAVA框架之Hibernate框架的学习步骤

    首先介绍一下Java三大框架的关系 以CRM项目即客户关系管理项目示例 hibernate框架的学习路线: 1.学习框架入门,自己搭建框架,完成增删改查的操作 2.学习一级缓存,事物管理和基本查询 3 ...

  8. java框架之Hibernate(1)-简介及初使用

    简介 hibernate 是一个开源 ORM ( Object / Relationship Mipping ) 框架,它是对象关联关系映射的持久层框架,它对 JDBC 做了轻量级的封装,而我们 ja ...

  9. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

随机推荐

  1. 1267 - Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' | 1267 - Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (Latin,COERCIBL)

    select * FROM information_schema.columns WHERE table_schema = "databaseName" and collation ...

  2. 十条很实用的jQuery代码片段

    本文转自:http://developer.51cto.com/art/201604/509093.htm 作者:核子可乐译来源:51CTO 原文标题:10 jQuery Snippets for E ...

  3. 具体解释Java虚拟机类载入

    概述 在Java语言里面,类型的载入.连接和初始化过程都是在程序运行期间完毕的.虚拟机把描写叙述类的数据从Class文件或其他地方载入到内存,并对数据进行校验.转换解析和初始化,终于形成能够被虚拟机直 ...

  4. ArtDialog V6的简单使用

    artDialog v6 -- 经典的网页对话框组件,内外皆用心雕琢. 兼容性 測试通过:IE6~IE11.Chrome.Firefox.Safari.Opera 授权协议 免费,且开源.基于LGPL ...

  5. Python爬虫(二十四)_selenium案例:执行javascript脚本

    本章叫介绍如何使用selenium在浏览器中使用js脚本,更多内容请参考:Python学习指南 隐藏百度图片 #-*- coding:utf-8 -*- #本篇将模拟执行javascript语句 fr ...

  6. 怎样在Spark、Flink应用中使用Protobuf 3的包

    如果在在Spark.Flink应用中使用Protobuf 3的包,因为Spark默认使用的是2.5版本的包,提交任务时,可能会报如下异常: com.google.protobuf.CodedInput ...

  7. 《深入浅出Netty》【PDF】下载

    <深入浅出Netty>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 本文档主要讲述的是深入浅出Netty: ...

  8. Microsoft Visual Studio 2012旗舰版(VS2012中文版下载)官方中文版

    Microsoft Visual Studio 2012 Ultimate旗舰版(VS2012中文版下载)是一个最先进的开发解决方案,它使各种规模的团队能够设计和创建出使用户欣喜的引人注目的应用程序. ...

  9. PHP中静态方法和实例化方法的区别

    在PHP中类为什么要使用静态方法,有什么好处 不需要实例化?? 可以提高运行效率?? 这是一个经常被时时提出来的问题,很多时候我们以为理解了.懂了,但深究一下,我们却发现并不懂. 方法是我们每天都在写 ...

  10. 童话故事 --- 什么是SQL Server Browser

    高飞狗这几天特别郁闷,不知该如何通过TCP/IP协议连接SQL Server数据库.好在功夫不负有心人,经过几天的刻苦研究,终于得到了答案. 高飞狗呼叫UDP1434端口,"叮铃铃,叮铃铃- ...