一、与触发器协同工作
  当Hibernate与数据库的触发器协同工作时,会出现以下两类问题:
  1、触发器使Session缓存中的数据和数据库中的不一致
    出现此问题的原因是触发器运行在数据库内,它执行的操作对Session是透明的。
    解决方案:在执行完包含有触发器的操作之后,立刻调用Session的flush()和refresh()方法,迫使Session的缓存与数据库同步。
  2、Session的update()方法盲目的激发触发器
    这种情况主要发生在Session调用update()或saveOrUpdate()方法时,能够使一个游离对象和Session关联,此时由于缓存中不存在该对象的快照,因此肯定会执行一次update语句,进而激发触发器。如果该对象的属性和数据库中的数据一致,那么该update语句就是多余的。要避免此种情况,在<class>元素中设置select-before-update="true"即可。
二、利用拦截器生成审计日志:暂不关注。
三、Hibernate事件处理机制
  Hibernate3的核心处理模块采用了“事件\监听器”设计模式。
  Session的大部分方法都会触发特定事件,该事件由相应的监听器来处理。
  在org.hibernate.event包中提供了与Session的各个方法对应的事件类及监听器接口。
  创建及注册客户化监听器方法的一般步骤:
  1、创建客户化监听器
    A、直接实现特定的监听器接口。
    B、继承Hibernate提供的监听器接口的基础实现类,比如org.hibernate.enent.def.AbstractSaveEventListner.
    C、继承Hibernate提供的监听器接口的默认实现类。比如org.hibernate.event.def.DefaultSaveEventListner.
  2、注册客户化监听器:2种方式
    A、在Hibernate的配置文件hibernate.cfg.xml中静态注册。

<event type="load">
<listener class="mypack.MyLoadListener" />
</event>

    B、在程序中动态注册:可以注册多个。

Configuration cfg = new Configuration();
LoadEventListener[] listeners = {new MyLoadListener(),...};
cfg.getEventListeners().setLoadEventListeners(listeners);

四、批量处理数据
  批量操作带来的问题:
    A、占用大量内存,比如批量更新,需要把大量的对象先加载到内存中,然后一一更新。
    B、执行的更新语句的数目太多。
  因此,应该尽量避免在应用层进行批量操作,而应该在数据库层直接进行批量操作。若要在应用层执行批量操作,有以下四种方式:
  1、通过Session来进行批量操作
    此种做法是在处理完一个对象或一小批对象之后,立刻调用flush()方法清理缓存,然后调用clear()方法清空缓存。
    需要注意:
      合理设置hibernate.jdbc.batch_size属性。
      如果对象采用identity标识符生成器,则Hibernate无法再JDBC层进行批量插入操作。
      进行批量操作时,建议关闭二级缓存。
  2、通过StatelessSession来进行批量操作:用法和Session类似。
  3、通过HQL来进行批量操作:Query.executeUpdate()
  4、直接通过JDBC API来进行批量操作
五、使用元数据
  通过SessionFactory.getClassMetadata()和getCollectionMetadate()可以获取相应的对象来操纵元数据。
六、执行存储过程:参见JDBC的方式。

(声明:该文所有内容均来自《精通Hibernate:Java对象持久化技术详解》[孙卫琴 电子工业出版社] 一书。该文的目的仅仅作为学习笔记。若需要转载,请注明原书相关信息。)

攻城狮在路上(壹) Hibernate(七)--- 通过Hibernate操纵对象(下)的更多相关文章

  1. 攻城狮在路上(壹) Hibernate(十三)--- Hibernate的检索方式(上)

    Hibernate提供了以下几种检索对象的方式: A.导航对象图检索方式. B.OID检索方式.Session.get() load(); C.HQL检索方式.Query. D.QBC检索方式.Que ...

  2. 攻城狮在路上(壹) Hibernate(六)--- 通过Hibernate操纵对象(上)

    一.Hibernate缓存简介: Session接口是Hibernate向应用程序提供的操纵数据接口的最主要接口,它提供了基本的保存.更新.删除和加载Java对象的方法. Session具有一个缓存, ...

  3. 攻城狮在路上(壹) Hibernate(四)--- 对象标识符(OID)生成机制

    Hibernate使用对象标识符(OID)来建立内存中对象和数据库表中记录的对应关系,对象的OID和数据库的主键对应.为了保证OID的唯一性和不可变性,应该让Hibernate来为OID赋值.Hibe ...

  4. 攻城狮在路上(壹) Hibernate(十八)--- 管理Hibernate的缓存

    一般Session的缓存被称为Hibernate的第一级缓存,SessionFactory的外置缓存是一个可配置的缓存插件,称为Hibernate的第二级缓存.一.缓存的基本原理: 1.持久化层的缓存 ...

  5. 攻城狮在路上(壹) Hibernate(十六)--- Hibernate声明数据库事务

    一.数据库事务的概念: 数据库的ACID特征:Atomic.Consistency.Isolation.Durability.原子性.一致性.隔离性.持久性.不同的隔离级别引发的不同问题. 事务的AC ...

  6. 攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型

    Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性.分为两种:内置映射类型和客户化映射类型.一.内置映射类型: 1.Java基本类型的Hibernate映射类型: Ja ...

  7. 攻城狮在路上(壹) Hibernate(二)--- 第一个hibernate程序

    1.直接通过JDBC API持久化实体域对象: A.java.sql常用接口和类: DriverManager:驱动程序管理器,负责创建数据库连接. Connection:代表数据库连接. State ...

  8. 攻城狮在路上(壹) Hibernate(十二)--- Hibernate的检索策略

    本文依旧以Customer类和Order类进行说明.一.引言: Hibernate检索Customer对象时立即检索与之关联的Order对象,这种检索策略为立即检索策略.立即检索策略存在两大不足: A ...

  9. 攻城狮在路上(壹) Hibernate(三)--- 属性访问、命名策略、派生属性、指定包名等

    一.hibernate访问持久化类属性的策略: 在<property>元素中的access属性用于指定Hibernate访问持久化类属性的方式. 常见的方式如下: 1.property:默 ...

随机推荐

  1. CentOS完美搭建Redis3.0集群并附测试

    线上的统一聊天和推送项目使用的是redis主从,redis版本2.8.6 redis主从和mysql主从目的差不多,但redis主从配置很简单,主要在从节点配置文件指定主节点ip和端口:slaveof ...

  2. jquery实现input输入框实时输入触发事件代码 ---jQuery 中bind(),live(),delegate(),on() 区别

    复制代码 代码如下: <input id="productName" name="productName" value="" /> ...

  3. ajax调用aspx.cs中的WebMethod

    前台: <script language="javascript" src="../js/jquery-1.8.2.js"></script& ...

  4. Unity3d《Shader篇》绘制圆角图片

    Pass { CGPROGRAM // Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it does not contain a s ...

  5. 使用swift 中的注意,不断完善中

    1. 应该充分利用swfit的新特性 比如如果按照oc里的习惯,调用一个delegate中都optional函数应该这样写 if delegate != nil && delegate ...

  6. FFPlay-noConsole-ver-20160409-snapshot

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 F ...

  7. [Error] Error parsing XML: unbound prefix

    发生该错误的代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  8. Effective C++ -----条款05:了解C++默默编写并调用哪些函数

    面对“内含reference成员或者含const成员”的class内支持赋值操作,你必须自己定义copy assignment操作符. 如果某个base classes将copy assignment ...

  9. String.prototype.substr()

    概述 substr() 方法返回字符串中从指定位置开始到指定长度的子字符串. 语法 str.substr(start[, length]) 参数 start 开始提取字符的位置.如果为负值,则被看作  ...

  10. LeetCode 242 Valid Anagram

    Problem: Given two strings s and t, write a function to determine if t is an anagram of s. For examp ...