@Id @GeneratedValue(strategy=GenerationType.IDENTITY) long id;
对java的字段做@GeneratedValue标注,字段的值能自动生成。一般用于主键的值的自动生成,但是ObjectDB 也支持做了这个标注的非主键字段。
字段值的自动生成策略有以下几种:
- Auto Strategy (全局数字生成器,为无主键的Entity生成自动的对象ID,commit入库时生成)
- Identity Strategy(数据库为每种类型提供一个默认的数值一个生成器,commit入库时生成,)
- Sequence Strategy(用户自定义一个自动生成值序列的Sequence,做持久化操作时就生成,不能确保值的连续性,)
- Table Strategy(用户自定义一个自动生成值序列的Sequence,做持久化操作时就生成,不能确保值的连续性,)
Auto
ObjectDB为每个数据库维护一个特殊的全局数字生成器。此数字生成器用于为未定义主键字段的实体对象生成自动对象ID(如前一节所述)。
对于定义为自动生成值的主键,如果没有指定生成策略,那么默认就是使用此全局数字生成器。
@Entity
public class MyEntity{
@Id @GeneratedValue long id;
// @Id @GeneratedValue( strategy=GenerationType.Auto) long id;
}
Identity
@Entity
public class MyEntity{
@Id @GeneratedValue( strategy = GenerationType.IDENTITY ) long id;
}
Sequence
首先需要用户自定义一个Sequence-可以用注解的方式,然后为某个或者某些字段指定用此Sequence生成字段值。
@Entity
@SequenceGenerator( name="seq1", initialValue=1, allocationSize=100) // 此注解定义了一个Sequence,会在数据库中创建相应的Sequence
public class MyEntity{
@Id @GenertatedValue( strategy=GenerateType.SEQUENCE, generate="seq1" ) long id;
}
Seqence方式中,字段的值是在用户做持久化操作时就给定了,这是在commit入库之前的发生的,这种方式下应用程序和数据库有数据的往返。而Auto和Identity方式,入库时数据库直接自动生成数值并立即入库,不需将生成的值返回给应用程序。因此,为了提高效率,当应用程序一次请求Seqence生成的值的时候,数据库会批量生成allocationSize个的数值,一次性返回给应用程序一组数值。当Seqence的Current+1还在此数值范围内时,对Seqence的请求全都由应用程序自己控制。
Table
TABLE 策略和 SEQUENCE 策略非常相似,二者的区别在于,SEQUENCE保存的是下一个将要被取用的值,而TABLE保留的是最后一个被取用的值。因此从SEQUENCE取用值时,SEQUENCE将直接返回当前保存的值;而TABLE被取用时则返回当前保存的值+1后的值。那么对于第一个生成的值:SEQUENCE是直接取用户设置的initialValue,而TABLE则是取initialValue+1。
@Entity
@TableGenerator(name="tab", initialValue=0, allocationSize=50)
public class EntityWithTableId {
@GeneratedValue(strategy=GenerationType.TABLE, generator="tab")
@Id long id;
}
对于关系型数据库,Oracle和DB2仅支持Sequence,SQL Server和Sybase仅支持Identity,而mysql则是支持auto Increment。但是对于所有类型的数据库,都可以设置GenerationType.AUTO,因为ORM会自己根据数据库类型(schema)来自动选择用SEQ还是Identity,这也是设置了@GeneratedValue的字段的默认生成策略,