关于hibernate的笔试题(二)
1.简单地说一下主键生成策略。
<id name="id" column="id" type="string">
<generator class="主键生成策略类型" />
</id>
在generator标签的class属性里标明主键生成策略的类型:
大概一共有十几种,常用的有:
1.Assigned(常用)
Assigned方式由程序生成主键值,并且要在save()之前指定,否则会抛出异常。
特点:逐渐的生成值完全由用户决定,于底层数据库无关。用户需要维护主键值,在调用session.save()之前要指定主键值。注意:int auto_increment类型主键除外
2.Identity(常用)
Identity当时根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。
特点:于底层数据库有关,适用于MySQl,DB2,MSSQL Server,采用数据库生成的主键,用于为long,short,int类型生成唯一标识。使用SQL Server和MySQL的自增字段,这个方法不能放到Oracle中,Oracle不支持自增字段,要设定sequence(MySQL和SQL Server中很常用)Identity无需Hibernate和用户的干涉,使用较为方便,但不便与在不同的数据库之间移植程序。
3.Sequence(常用)、
Sequence需要底层数据库支持Sequence方式,例如Oracle数据库等
特点:需要底层数据库的支持序列,支持序列的数据库有DB2,PostgreSql,oracle,SAPDb等。在不同数据库之间移植程序,特别从支持序列的数据库移植到不支持序列的数据库需要修改配置文件
4.Sequence(常用)、
Sequence需要底层数据库支持Sequence方式,例如Oracle数据库等
特点:需要底层数据库的支持序列,支持序列的数据库有DB2,PostgreSql,oracle,SAPDb等。在不同数据库之间移植程序,特别从支持序列的数据库移植到不支持序列的数据库需要修改配置文件
5.native(常用)
Native主键生成方式会根据不同的底层数据库自动选择Identity,Sequence,Hilo主键生成方式。
特点:根据不同的底层数据库采用不同的主键生成方式。由于hibernate会根据底层数据库采用不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。
6.UUid
UUid使用128位UUID算法生成主键,能够保证网络环境下的主键唯一性,生成的主键占用比较多的存储空间。
2.持久化类有三种状态,这三种状态各有什么特点?三种状态之间是怎样切换的?[可以举例说明]
1. 瞬时态(Transient),也叫临时态。处于这种状态的对象具备的特征如下:
a) 不在Session的缓存中,不与任何的Session实例相关联。
b) 在数据库中没有与之相对应的记录。(没有数据库识别值id)
2. 持久态(Persistent),处于这种状态的对象具备的特征如下:
a) 在Session的缓存中,与Session实例相关联。
b) 在数据库中存在与之相对应的记录。
3. 脱管态(Detached),也叫游离态。处于这种状态的对象具备的特征如下:
a) 不在Session的缓存中,不与任何的Session实例相关联。
b) 在数据库中存在与之相对应的记录。(有数据库识别值id)
转化:
3.简要说说hibernate一级缓存有什么作用和特点?清空缓存几个常用方法有什么区别?
一级缓存称为是Session级别的缓存,一级缓存的生命周期与Session是一致的。一级缓存其实由Session中的一组集合构成的。----笔记
Hibernate的一级缓存其实就是Session内置的一个Map,用来缓存它操作过的实体对象,对象的主关键字ID是Map的key,实体对象就是对应的值。所以,一级缓存是以实体对象为单位进行存储的,访问时也是以实体为单位的(直接访问属性是不能使用缓存的),并且要求使用主关键字ID来进行访问。
一级缓存是由Session提供的,所以它只存在于Session的生命周期中,当程序调用
save(),update(),saveorupdate()等方法以及调用查询接口list,filter,iterate时,如果session缓
存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,当Session关闭的时候该Session所管理的一级缓存也会立即被清除。
当程序调用get(),load(),iterate(查询实体对象才支持一级缓存,查询普通属性则不支持一级缓存)时,Hibernate会先到缓存中去拿,如果缓存中已经存在目标对象,则直接拿来而不再查询数据库,否则,必须发出查询语句到数据库中查。
清空缓存几个常用方法:
session.clear():清空一级缓存中所有的对象
session.evict():从一级缓存中移除一个对象
4.说一下什么是事物,它有哪些特性?如果不考虑隔离性会引发什么问题?
事务是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败!
事物的四大特性:
原子性:不可分割。
一致性:事务执行前后,数据的完整性保持一致。
隔离性:一个事务执行的过程中不应该受到其他事务的干扰。
持久性:事务一旦结束,数据持久到数据库。
如果不考虑隔离性会引发:
脏读:一个事务读到另一个事务未提交的数据。
不可重复读:一个事务读到另一个事务已经提交的update数据,导致多次查询结果不一致。
虚读:一个事务读到另一个事务已经提交的insert数据,导致多次查询结果不一致。
5.简要说说cascade与inverse有什么区别?[这两个属性的作用和区别]
cascade表示级联操作,即两个实体间存在级联关系(一个类是另一个类中的属性)时,当保存、更新或删除一个实体时,是否对关联的实体做出相应操作(数据库操作);
比如:customer类和order类。一个customer可以有多个order。
如果new了n多个订单,把订单set到customer中,想要在保存customer的时候自动保存订单,或者是要删除customer的时候自动把里面的订单全部删除,就必须要在customer.hbm.xml文件中设置:
<!-- 配置一对多的关联映射 -->
<!-- set标签:用来描述一的一方存放的多的一方的集合
* name:多的一方的集合属性名称-->
<set name="orders" cascade="save-update">
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作。
在hibernate中,通过session.save方法保存一个持久化对象这种方式称为显示保存。通过级联的方式来操作一个对象,这样的方式称为隐式操作。对order对象进行了隐式的保存操作,是因为order是一个临时状态的对象,在数据库中没有对应的记录,所以应该对order执行
inverse属性用于指示本方是否参与维护关系,设为true时不维护,设为false时维护。
一对多:该属性在多的一方。应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可以不设置inverse属性,因为默认值是false),这说明关联关系由多的一方来维护。原因:该关联关系的属性在多的一方的表中,在维护关联关系的时候在多的一方容易维护。
多对多:属性在独立表中。在任意一方设置inverse=true,另一方inverse=false;原因:如果两个多设置为true 的话,表示两方都对关联关系表(独立表)进行了同样的维护,其实只要一方维护就行了,效率上来说,这样设置是合理点的。
一对一:其实是一对多的一个特例,inverse 的设置也是一样的,主要还是看关联关系的属性在哪一方,这一方的inverse=false。
6. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many,来实现类之间的关系。