主键生成策略是指 <grnerator class="native"/>
1、 native
对于 oracle 采用 Sequence 方式,对于MySQL 和 SQL Server 采用identity(自增主键生成机制),native就是将主键的生成工作交由数据库完成,hibernate不管(很常用)
2、Assigned
在插入数据的时候主键由用户自己添加,hibernate也不管(很常用)
3、increment
插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法
4、sequence
调用数据库的sequence来生成主键,要设定序列名,不然hibernate无法找到:
<param name="sequence">NAME_SEQ</param>(Oracle中很常用)
5、identity
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)
6、hilo
使用hilo生成策略,要在数据库中建立一张额外的表,默认表名为hibernate_unique_key,默认字段为integer类型,名称是next_hi(比较少用)
我们也可以自己设置自定义的表名和字段名
<id name="id" type="integer">
<column name="id"/>
<generator class="hilo">
<param name="my_unique_key"/>
<param column="next_hi"/>
</generator>
</id>
7、sehilo
通过hilo算法实现,但是主键历史保存在Sequence中,适用于支持 Sequence 的数据库,如 Oracle(比较少用)
8、uuid.hex
hibernate会算出一个128位的唯一值插入
9、uuid.string
hibernate会算出一个16位的值插入
10、foreign
使用外部表的字段作为主键
11、select
使用触发器生成主键(主要用于早期的数据库主键生成机制,少用)
Hibernate中复合主键的配置
(1)复合主键的概念:
复合主键是由多个字段组成的主键,有时根据业务的需求,一个id作为主键不能够代替所代表的内容,所以要用实例类的中的两个属性来表示
(2)在xml文件中复合主键的配置
第一种方式
class User
{
String name;
Stirng add;
int age;
..........
}
如果name和add是联合主键,那么配置可以如下:
<composite-id>
<key-property name="name"/>
<key-property name="addr"/>
</composite-id>
第二种方式:
class User
{
UserKey id;
int age;
......
}
class UserKey
{
String name;
String add;
}
<composite-id class="com......UserKey" name="id">
<key-property name="name"/>
<key-property name="add"/>
</composite-id>
注:
符合主键的表述方式为
<composite-id>
<key-property name="xxx"/>
<key-property name="x"/>
<composite-id>
一 检索策略分类和介绍
hiebenate检索策略分为类级别的检索策略包括:立即检索、延迟检索。关系级别的检索策略包括:立即检索、延迟检索、迫切左外连接检索。
类级别的检索默认的检索策略是立即检索。在Hibernate映射文件中,通过在<class>上配置 lazy属性来确定检索策略。对于Session的检索方式,类级别检索策略仅适用于load方法;也就说,对于get、qurey检索,持久化对象都会被立即加载而不管lazy是false还是true.一般来说,我们检索对象就是要访问它,因此立即检索是通常的选择。由于load方法在检索不到对象时会抛出异常(立即检索的情况下),因此我个人并不建议使用load检索;而由于<class>中的lazy属性还影响到多对一及一对一的检索策略,因此使用load方法就更没必要了。
关系级别的检索策略主要体现在set集合标签中,对检索策略的影响取决于lazy和fecth属性:
Lazy:主要决定orders集合被初始化的时机,即到底是在加载Customer对象时就被初始化,还是在程序访问orders集合时被初始化
Fetch:取值为select或subselect时,决定初始化orders的查询语句的形式,若取值为join,则决定orders集合被初始化的时机
若把fecth设置为join,lazy属性将被忽略
注:fetch默认值是select,lazy的默认值是true
fetch 属性有三种值
1.当用到fetch=join时一定是迫切左外连接检索.
2.当用到fetch=select一定不采用迫切左外连接检索,检索方式与lazy保持一致.
3.当用到fetch=subselect,检索多个Customer时,采用嵌套的子查询订单.
注:fecth和lazy相比,fecth的优先级高
当fecth设置为join的时候,不管lazy是什么值,最终的结果都是一样的。
当fecth=select时,lazy=true时,结果为:立即检索
当fecth=select,lazy=false时,结果为:延迟检索
当fecth=select,lazy=extra时,结果为:延迟检索
当fecth=subselect,lazy也有三种情况,
1.立即检索
优点:对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以从一个对象导航到关联的对象
缺点:
(1)select()语句多
(2)可能会加载应用程序不需要访问的对象,浪费许多内存空间
优先考虑使用的场合
(1)类级别
(2)应用程序需要立即访问的对象
(3)使用了二级缓存
2.延迟检索
优点:由应用程序决定需要加载哪些对象,可以避免执行多余 的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并节省内存空间
缺点:应用程序如果希望访问游离状态的代理类实例,必须保证它在持久化状态时已经被初始化。
优先考虑使用的场合
(1)一对多或者多对多关联
(2)应用程序不需要立即访问或者根本不会访问的对象
3.迫切左外连接检索
优点:
(1)对应用程序完全透明,不管对象处于持久化状态还是游离状态,都可从一个对象导航到另一个对象。
(2)使用了外连接,select语句少
缺点:
(1)可能会加载应用程序不需要访问的对象,浪费内存。
(2)复杂的数据库表连接也会影响检索性能。
优先考虑使用的场合
(1)多对一
(2)需要立即访问的对象
(3)数据库有良好的表连接性能。