`
weigang.gao
  • 浏览: 463202 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

ID生成策略(3)

 
阅读更多

id生成策略是什么意思呢?我们原来些的程序是每次id都要我们手工去设定它,手动设定很不方便,很容易重复。在我们实际工作当中我们的数据库表会建成什么样啊?在mysql我一般是用自增字段auto increment,在oracle我们一般是用sequence,所以说如果我把表建成auto_increment,那么我们的实体类(Student)中的id就不用手动去指定它的值了,就需要靠我们的程序或数据库来帮我们生成,hibernate或JPA就已经实现了这样的能力。

 

id可以由generator来生成,而且generator可以有各种各样的具体的值,每个值都指定了不同生成方式,常见的取值如下:

identity

对 DB2,MySQL,SQL server的内置标识字段提供支持。返回的标识符是 long,short 或者 int 类型的。如果用MySQL的话也就是auto_increment

 

sequence:oracle中采用sequence来自动帮我们产生一个id值

 

uuid:如果你想产生一个唯一的,独一无二的id,返回的是一个字符串。注意:数据库应该是字符串

 

native:根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个。如果我们使用native的话,在MySQL中就会使用identity,而在oracle中就会使用sequence

 

1.xml生成id

          a) generator

          b)常用四个id生成策略:native identiy sequence uuid

 

2.annotation生成id

@generateValue(注意是javax.persistence.generateValue(在ejb3-persistence.jar里面),而不是使用hibernate的扩展org.hibernate.annotations.Generated。)

如果使用hibernate的扩展org.hibernate.annotations.Generated,就可以使用hibernate自己的id生成策略了,eg,hilo,sequence hilo。

JPA1.0(EJB3中定义的规范)它的id生成策略非常简单,就只有4种,默认的id生成策略是auto,相当于native。如果我们用mysql,它就会用auto_increment;如果我们用oracle,它就会用sequence。

和EJB3相比,hibernate提供更多的id生成器,hibernate的扩展。

 

 

2.1)@generator的默认值AUTO(相当于native)

              i .默认:对MySQL,使用auto_increment

              ii. 对oracle使用hibernate_sequence(名称固定),如果不指定序列的名字,应用程序只会创建一个sequence,即hibernate_sequence。所有的表都共用这个sequence

2.2)@generator指定id生成策略IDENTITY,SEQUENCE.

              1.IDENTITY 在DB2,MySQL,sql server中使用

             @GeneratedValue(strategy=GenerationType.IDENTITY)

              2.SEQUENCE在oracle中使用

               @GeneratedValue(strategy=GenerationType.SEQUENCE)

 

2.3). 指定数据库创建的sequence的名字,oracle中默认的sequence的名字是hibernate_sequence

                i.   @SequenceGenerator


 

2.4) 使用表生成器 @TableGenerator 来生成id

@TableGenerator(

                name="table_seq",

                table="generator_table", //指定创建的表名

                pkColumnName="key",   

                valueColumnName="value",

                pkColumnValue="teacher",   //指定key的Name

                allocationSize=1  //  指定value的初始值value

 

)

会生成如下一个表:

代码中的实现:


 

3.联合主键(2个类之间是组合关系):一般情况下我们能用一个做主键的,就不要用二个做主键

使用annotation有3种方式:

 1.把联合主键类(StudentPK)注解为@Embeddable,并将在实体类(Student)中将联合主键注解为@Id(需要编写联合主键)

 2.在实体类(Student)中将联合主键注解为@EmbeddedId(需要编写联合主键)

 3.第三种方式最符合我们编程的习惯:需要编写联合主键类(StudentPK有2个属性id和name),但联合主键上不需要任何注解。

将实体类(Student)注解为@IdClass(value=”联合主键类.class”)并在实体类中2个主键(id和name)上加@Id,以后load的时候还是要用到联合主键

 

 联合主键:1.StudentPK  implements java.io.Serializable 

为什么要实现Serializable这个接口呢??因为对于Student这条记录在数据库可能存在多条记录,这多条记录如果放到内存中就是多个对象,每个Student中都有一个主键对象StudentPK,如果我们将来系统如果要做集群,好多台服务器共同要对外服务,这台服务器有问题,可以把这台服务器里面的student对象传给另外一台服务器,大家看我是不是要实现序列话呀,要不然我就不能把这台服务器上的student对象传到另一台服务器上了

第二种情况:现在假如我的内存满了,我内存满了的时候我可以使用虚拟内存,把我们内存中的一部分对象转到虚拟内存当中,这个就需要序列话

为什么联合主键要重写equals和hashCode()呢??因为我们不仅要保证这条记录在数据中这条记录唯一,而且要保证在这条记录在内存中唯一,这条记录在内存中唯一,就是通过equals和hashCode来判断的;在数据库中的唯一性是通过联合主键来判断的

     a)  xml:compsite-id

           i 为什么要重写equals和hashCode

 

           ii . 为什么要实现serializable

  • 大小: 29.2 KB
  • 大小: 1.3 KB
  • 大小: 29.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics