跳到主要内容

简单映射

@Entity

Entity注解用于修饰不可变接口,表示一个ORM实体。

Book.java
@Entity
public interface Book {
...省略其他代码...
}
信息

为什么实体类型是接口而非类?

Jimmer实体具备

, 并非简单的POJO,内部有精巧的运作机制,无法靠开发人员手工编写或lombok辅助完成。

所以,Jimmer让开发人员编写接口,由预编译器 (对Java而言即AnnotationPrcoessor,对Kotlin而言即KSP) 在编译时实现这些接口。

@Table

@Table注解为实体指定表名。如果没有使用@Table注解,例如

BookStore.java
@Entity
public interface BookStore {
...省略其他代码...
}

Jimmer会根据命名策略推导BookStore接口对应的表名。

如果默认的命名策略未被用户覆盖,接口BookStore的表名为BOOK_STORE。所以,之前的代码和这里的代码等价:

BookStore.java
@Entity
@Table(name = "BOOK_STORE")
public interface BookStore {
...省略其他代码...
}

@Column

@Column注解为普通非关联属性指定数据库列。如果没有使用@Column注解,例如

Author.java
@Entity
public interface BookStore {

String firstName();

...省略其他代码...
}

Jimmer会根据命名策略推导firstName属性对应的列名。

如果默认的命名策略未被用户覆盖,属性firstName的列名为FIRST_NAME。所以,之前的代码和这里的代码等价:

Author.java
@Entity
public interface BookStore {

@Column(name = "FIRST_NAME")
String firstName();

...省略其他代码...
}
警告

@Column仅用于明确指定非关联属性列名,对于多对一或一对一关联属性的外键列名,必须通过@JoinColumn指定。请参见关联映射以了解更多。

@Id

声明某个属性是id属性,如下

Book.java
@Entity
public interface Book {

@Id
long id();
}
警告

Id字段必须非空 (对Java而言,这个例子中使用long,而非Long

和JPA中鼓励把id声明成可null类型不同,Jimmer不通过这种方法来表达插入数据时不指定id,Jimmer对象本身的动态性可以轻松表达此问题。

请参见可空性

@GeneratedValue

在上面的例子中,被@Id修饰的主键属性本身是业务字段,插入数据时必须指定。

然而,更多时候,我们期望主键属性本身没有业务意义,这样插入数据时就可以不指定,而是自动生成。自动生成id的策略有

  • 数据库自动编号
  • 数据库序列
  • UUID
  • 雪花ID

@GeneratedValue@Id配合使用,为Id指定自动增长策略。

数据库自动编号

Book.java
@Entity
public interface Book {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
long id();
}

数据库序列

Book.java
@Entity
public interface Book {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
long id();
}

这里,并没有通过@GeneratorValuesequenceName指定数据库中的序列名称,Jimmer会根据命名策略推导序列名。

如果默认的命名策略未被用户覆盖,这里的序列名为BOOK_ID_SEQ。所以,之前的代码和这里的代码等价。

Book.java
@Entity
public interface Book {

@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
sequenceName = "BOOK_ID_SEQ"
)
long id();
}

UUID

@GeneratedValue的generatorType属性指定为org.babyfish.jimmer.sql.meta.UUIDIdGenerator,即可用于随机生成UUID

Book.java
@Entity
public interface Book {

@Id
@GeneratedValue(generatorType = UUIDIdGenerator.class)
UUID id();
}

用户自定义IdGenerator

当以上Id增长策略都无法满足要求时,可以自定义Id生成策略。

Jimmer提供了一个UserIdGenerator<T>接口

UserIdGenerator.java
package org.babyfish.jimmer.sql.meta;

public interface UserIdGenerator<T> extends IdGenerator {

T generate(Class<?> entityType);
}

用户可以通过实现此接口,实现任何Id生成算法,包括雪花ID。

MyGenerator.java
package com.mycompany.myproject.common;

public class MyIdGenerator implements UserIdGenerator<Long> {

@Override
public Long generate(Class<?> entityType) {
return ...省略自定义id生成逻辑...
}
}
Book.java
@Entity
public interface Book {

@Id
@GeneratedValue(generateType = MyIdGenerator.class)
Long id();
}
警告

用户实现的Id生成类MyIdGenerator本身是没有范型参数的,但需要为超接口UserIdGenerator指定范型参数。

被修饰的Id属性的类型必须和该范型参数一致,否则会导致异常。