Java语言按内存地址来识别或区分同一个类的不一样对象,而关系数据库按主键值来识别或区分同一个表的不一样记录。Hibernate使用OID来统一二者之间的矛盾,OID是关系数据库中的主键(一般为代理主键)在Java对象模型中的等价物。java
在运行时,Hibernate根据OID来维持Java对象和数据库表中记录的对应关系。例如:数据库
Transaction tx = session.beginTransaction(); Customer c1=session.get(Customer.class, Long.valueOf(1)); Customer c2=session.get(Customer.class, Long.valueOf(1)); Customer c3=session.get(Customer.class, Long.valueOf(3)); System.out.println(c1==c2); System.out.println(c1==c3); tx.commit();
在以上程序中,三次调用了Session的get()方法,分别加载OID为1或3的Customer对象。如下是Hibernate三次加载Customer对象的流程:缓存
所以,表达式c1== c2的结果为true,表达式c1==c3的结果为false。markdown
与表的代理主键对应,OID也是整数类型,Hibernate容许在持久化类中把与代理主键对应的OID定义为如下类型:session
为了保证持久化对象的OID的惟一性和不可变性,一般由Hibernate或底层数据库来给OID赋值。所以,能够把持久化类的OID的setId()方法设为private类型,以禁止Java应用程序随便修改OID。而把getId()方法设为public 类型,这使得Java应用程序能够读取持久化对象的OID:ide
private Long id; private void setId(Long id){ this.id=id; } public Long getId(){ return id; }
在持久化类中,用来自JPA API的@Id注解和@GeneratedValue注解来映射对象标识符,例如:ui
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="ID") private Long id;
以上@Id注解代表id属性是OID,@GeneratedValue注解设定如何为OID赋值,它的strategy属性指定标识符生成策略。JPA API经过GenerationType枚举类型定义了四种标识符生成策略:this
对于以上标识符生成策略,Hibernate会经过相应的标识符生成器来实现这些标识符生成策略。例如如下代码经过@SequenceGenerator注解设置了具体的序列化标识符生成器:atom
@Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "sequence-generator" ) @SequenceGenerator( //具体的序列化标识符生成器 name = "sequence-generator", sequenceName = "hibernate_sequence" ) @Column(name="ID") private Long id;