Hibernate学习笔记(四)映射关系标识符

1.主键
在关系数据库中,用主键来标识记录并保证每条记录的唯一性。作为主键的字段必须满足一下条件:
1.不允许为空。
2.每条记录具有唯一的主键值,不允许主键值重复。
3.每条记录的主键值永远不会改变。

自然主键:具有业务含义的字段。尽管也是可行的,但是不能满足不断变化的业务需求,一旦出现了允许客户重名的业务需求,就必须修改数据模型,
    重新定义表的主键,给数据库的维护增加了难度。
代理主键:不具备业务含义的字段,该字段一般取名为“ID”。代理主键通常为整数类型,因为整数类型比字符串类型要节省更多的空间。

2.把主键定义为自动增长类型
在MySql中如果把表的主键设为auto_increment类型,数据库就会自动为主键赋值。
e.g. create table CUSTOMER(ID int auto_increment primary key not null, NAME varchar(15));  起始为1,步长1

在MS SQLService中如果把表的主键设为identity类型,数据库就会自动为主键赋值。
e.g. create table CUSTOMER(ID int identity(1,1) primary key not null, NAME varchar(15));   起始为1,步长1
identity(x,y) x表示起始值,y表示增量。

从序列(Sequence)中获取自动增长的标识符
在Orcle数据库中,可以为每张表创建一个单独的序列,然后从这个序列中获得自动增加的标识符,把它赋值给主键。
e.g. create sequence CUSTOMERS_ID_SEQ increment by 2 start with 1。 起始值为1,增量为2.
  定义CUSTOMERS_ID_SEQ序列,就可以访问序列的curval和nextval属性。curval返回序列的当前值,nextval现增加序列的值,然后返回增加后的序列值。
使用e.g. create table CUSTOMER(ID int primary key not null, NAME varchar(15));
insert into CUSTOMER values(CUSTOMERS_ID_SEQ.nextval,'tom');

3.Java语言按内存地址区分不同的对象
(1)比较两个变量所引用的对象的内存地址是否相同,"=="运算符就是比较内存地址的。此外,在Object类中定义的equals(Object o)方法,
        也是按内存地址来比较的。如果用户自定义的类没有覆盖Object类的equals(Object o)方法,也是按内存地址来比较的。
(2)Java中重写Object方法的有String,Date及Java包装类:Byte,Integer,Short,Character,Long,Float,Double和Boolean。

4.Hibernate用对象标识符(OID)来区分对象
关系数据库按主键值来识别或区分同一张表的不同记录。OID是关系数据库中的主键在Java对象模型中的等价物。
e.g.Transaction tx = session.beginTransaction();
Customer c1 = (Customer)session.get(Customer.class,new Long(1));
Customer c2 = (Customer)session.get(Customer.class,new Long(1));
Customer c3 = (Customer)session.get(Customer.class,new Long(3));
说明:第一次加载OID为1的Customer时,先从数据库的CUSTOMERS表中查询ID为1的记录,再创建相应的Customer实例,
把它保存在Session缓存中,最后把这个对象的引用赋值为变量c1。
    第二次加载OID为1的Customer对象时,直接把Session缓存中的OID为1的Customer对象的引用赋值为c2,因此c1和c2引用同一个Customer对象。
    第三次加载OID为3的Customer对象时,由于Session缓存中不存在这样的对象,所以步骤同第一步。

与表的代理主键对应,OID也是整数类型,Hibernate允许在持久化类中把OID定义为以下整数类型。
short(或Short):2个字节,取值范围:-2^15~2^15-1
int(或Integer):4个字节,取值范围:-2^31~2^31-1
long(或Long):8个字节,取值范围:-2^63~2^63-1

为了保证持久化对象的OID的唯一性和不可变形,通常由Hibernate或底层数据库来给OID赋值。因此可以把持久化类的OID的setId()方法设为private类型,
以禁止Java应用程序随便修改OID。而把getId()设为public类型,这使得Java应用程序可以读取持久化对象的OID。

在对象-关系映射文件中,<id>元素用来设置对象的标识符
e.g.<id name="id" type="long" column="ID">
<generator class="increment">
</id>

Hibernate提供的内置标识符生成器
increment:适用于代理主键,由hibernate自动以递增的方式生成标识符,每次增量为1。
  说明:increment标识符生成器仅仅在只有单个Hibernate应用进餐方位数据的情况下才能有效工作,在同一个进程中创建多个SessionFactory实例,
        也会导致插入操作的失败。仅能运行在单个服务器上,如果运行在多个服务器上,会失效。
identity:适用于代理主键,由底层数据库生成标识符。前提条件是底层数据库支持自动增长字段类型。OID必须为long,int或short类型。
例如:DB2,MySQL,MS SQL Server,Sybase和HypersonicSQL
sequence:适用于代理主键,Hibernate根据底层数据库的序列来生成标识符,前提条件是底层数据库支持序列。OID必须为long,int或short类型。
例如:DB2,PostgreSQL,Oracle和SAP DB
hilo:适用于代理主键,hibernate根据high/low算法来生成标识符。Hibernate把特定表的字段作为“high”值。
在默认情况下选用hibernate_unique_key表的next_hi字段。
native:适用于代理主键,根据底层数据库对自动生成标识符的支持能力,来选择identity,sequence或hilo。

你可能感兴趣的:(java,Hibernate)