hibernate学习笔记(三)

hibernate的一些杂记:
1.sessionFactory的用法:
SessionFactory是线程安全的,构造 SessionFactory 很消耗资源
sessionFactory = new Configuration().configure().addClass(**).addClass(**).buildSessionFactory();
Session session = sessionFactory.openSession();
在这里addClass的好处是不需要在hibernate.cfg.xml中声明domain中各个实体对应的配置文件
2.二级缓存
二级缓存中的类缓存,只适用于ID查询的方式(get()或load()),对于HQL的方式不可以,这个时候可以配置查询缓存,使用查询缓存需要先在hibernate.cfg.xml中开启查询缓存,然后在查询到时候setCacheable(true).
时间戳缓存:指定hibernate的二级缓存会自动检测,如果使用了update或delete语句,则会把数据清出缓存,重新查询。注::但是这是一级缓存session中的内容不会被刷新,所以要手动refresh().
list()方法默认不会使用缓存,除非调用了SetCacheable(true),但是如果HQL一变或者参数一遍,缓存就失效了,但是用iterate()查询,就可以。
3.iterate()查询的原理:
先执行一个查询,查询所有的符合条件的ID,再使用每一个对象时,会根据ID去缓存中查,如果查得到直接使用,如果查不到,那么就查出缓存中没有的相应数据。
4.关于级联
在设置了关联关系以后,如果主从对象存在级联关系,可以用cascade属性来设置,在使用时应仔细分析对象的级联关系,是否需要级联删除等操作。
5.在使用的时候
从对象的角度来说:让双方都设置关联关系比较好。所以用inverse属性配置是否由对方维护关联关系。一般都是让一的一方去放弃维护关联关系。为了使查询的集合元素有顺序,可以配置order-by属性
从数据库的角度来说,只要让一方设置关联就可以。所以在用时候可以让一的一方维护多的一方,也可以让多的一方维护一的一方。这样都会比双方同时维护性能要好。但是这样做的效果缺点是:代码不清晰。
注::在一对多中,维护关联关系就是指更新外键的值
在save的时候应该先保存无外键的一方,再保存有外键的一方(基于外键的一对一也同样),这样会节省一个update语句
6.主键生成策略:native---数据库的自动增长(oracle不支持)(identity,sequence[oracle],hilo)increment存在多线程问题。联合主键
7.DML语句不经过缓存,要手动session.refresh();
8.  Query和Criteria接口
都是查询接口,Query实例包装了HQL查询语句,hql是面向对象的,他引用类名及类的属性名,而不是表名和字段名。Criteria接口完全封装了基于字符串形式的查询语句,比Query接口更面向对象,他擅长执行动态查询
9.  Hibernate访问持久化类属性的策略
propertye(默认值):
表明hibernate通过getXXX和setXXX来访问类属性。推荐使用。提高域模型透明性。
field
hibernate通过java反射机制直接访问类属性。对于没有get与set方法的属性可设置该访问策略。
noop
它映射Java持久化类中不存在的属性,即主要用于HQL(用query接口测试,使用hql语句)中,当数据库中有某列,而实体中不存在的情况。
<!-- 该属性在Customer类中有get与set方法 -->
<property name="name" column="name"type="string"/> 
<!-- 该属性在Customer类中不存在get和set方法 -->
<property name="name" column="name"type="string" access="field" />
<!-- 该属性在Customer类中不存在,但在数据库存在该字段。
使用noop处理,查询的时候忽略该字段-->
<property name="name"column="name" type="string" access="noop"/>
10.利用<property>元素的formula属性,用来设置一个sql表达式,hibernate将根据它来计算出派生属性的值。
如果指定了formula 属性,则就会insert=”false” update=”false”
11.java与Hibernate如何区分对象

Java语言按内存地址(==)或equals()方法区分不同的对象

Hibernate中用对象表示符(OID)来区分对象

OID是关系数据库中的主键在java对象模型中的等价物。在运行时,hibernate根据OID来维持java对象和数据库记录的对应关系。

Hibernate使用OID来区分对象,不是equals()方法!所以不重写持久化类的hashCode()与equals()方法Hibernate也可以正确运行(但要放到HashSet等集合中时要注意需要重写这两个方法)。

12.  List是有序集合,因此持久化到数据库时必须增加一列来表示集合元素的次序

集合属性只能以接口声明(当持久化某个实例时, Hibernate 会自动把程序中的集合实现类替换成 Hibernate 自己的集合实现类)

list元素要求用list-index的子元素来映射有序集合的次序列。

集合的属性的值会存放有另外的表中,须以外键关联,用 Key 元素来映射外键列

13.在映射一对多的双向关联关系时,应该在one方把inverse属性设为true, 这可以提高性能

在建立两个对象的关联时,应该同时修改关联两端的相应属性,这样才会使程序更加健壮,提高业务逻辑层的独立性,使业务逻辑层的程序代码

不受Hibernate实现类的影响。同理,当删除双向关联的关系时,也应该修改关联两端的对象的相应属性.

14.update 、saveOrUpdate、 meger区别与用法

Hibernate 的用户曾要求一个既可自动分配新持久化标识(identifier)保存瞬时(transient)对象,又可更新/重新关联脱管(detached)实例的通用方法。saveOrUpdate() 方法实现了这个功能。

hibernate学习笔记(三)


saveOrUpdate() 用途和语义可能会使新用户感到迷惑。首先,只要你没有尝试在某个 session 中使用来自另一 session 的实例,你就应该不需要使用 update(), saveOrUpdate(),或 merge()。有些程序从来不用这些方法。

通常下面的场景会使用 update() 或 saveOrUpdate()

saveOrUpdate() 做下面的事:

merge() 可非常不同:


上一篇:svn服务端的安装与使用方式简介(一)


下一篇:svn服务端的安装与使用方式简介(二)