JPA 注解支持

8.1 注解介绍

对 JPA 注解的支持非常有限,仅支持以下注解的部分属性:

  • @Table: 用于实体类,必须指定该注解,否则不会被识别为实体类

    • name: 设置表名
  • @Column: 设置字段的列信息

    • name: 列名
    • insertable: 是否可插入
    • updatable: 是否可更新
    • scale: 小数位数
  • @Id: 主键标记

  • @Transient: 排除字段,没有标记该字段的所有字段都会作为表字段处理

  • @OrderBy: 设置字段排序,空值时为 ASC,除此之外,值只能为 ASCDESC

除了上面提到的有限支持外,其他的 JPA 注解都不支持,如果有好的建议或者应用场景,可以提交 issue 或者 PR 增加额外的支持。

除了 JPA 这几个注解外,还支持 @Entity.Table@Entity.Column 注解,这些注解可以混用,相同含义的配置中,JPA优先级更高。

8.2 JPA 示例

  1. @Table(name = "user")
  2. public class User {
  3. @Id
  4. @Column
  5. private Long id;
  6. @Column(name = "name")
  7. private String username;
  8. @Column
  9. @Entity.Column(selectable = false)
  10. private String sex;
  11. //忽略其他
  12. }

8.3 扩展实现

8.3.1 查找实体类类型

首先通过 JpaEntityClassFinder 支持添加了 javax.persistence.Table 注解的实体类。

  1. public class JpaEntityClassFinder extends GenericEntityClassFinder {
  2. @Override
  3. public boolean isEntityClass(Class<?> clazz) {
  4. return clazz.isAnnotationPresent(Table.class);
  5. }
  6. @Override
  7. public int getOrder() {
  8. return super.getOrder() + 100;
  9. }
  10. }

8.3.2 构建 EntityTable 信息

然后通过 JpaEntityTableFactory 读取 javax.persistence.Table 注解的配置信息。

  1. public class JpaEntityTableFactory implements EntityTableFactory {
  2. @Override
  3. public EntityTable createEntityTable(Class<?> entityClass, Chain chain) {
  4. EntityTable entityTable = chain.createEntityTable(entityClass);
  5. if (entityClass.isAnnotationPresent(Table.class)) {
  6. Table table = entityClass.getAnnotation(Table.class);
  7. if(entityTable == null) {
  8. entityTable = EntityTable.of(entityClass);
  9. }
  10. if (!table.name().isEmpty()) {
  11. entityTable.table(table.name());
  12. }
  13. }
  14. return entityTable;
  15. }
  16. @Override
  17. public int getOrder() {
  18. return EntityTableFactory.super.getOrder() + 100;
  19. }
  20. }

在实现中先执行了 chain.createEntityTable 调用工厂链的后续方法创建 EntityTable,因此 JPA 注解实现支持和 @Entity.Table 注解混用。

如果 chain 方法没有返回 EntityTable,就根据 javax.persistence.Table 注解创建。

如果返回了 EntityTable,就用 javax.persistence.Table 注解的配置覆盖 EntityTable 的配置,也就是 JPA 注解优先级高于默认的 @Entity.Table 注解。

8.3.3 构建 EntityColumn 信息

最后通过 JpaEntityColumnFactory 构建 EntityColumn 信息,这部分逻辑和上面类似,仍然支持 @Entity.Column 注解,而且 JPA 的优先级更高。

  1. public class JpaEntityColumnFactory implements EntityColumnFactory {
  2. @Override
  3. public Optional<List<EntityColumn>> createEntityColumn(EntityTable entityTable, EntityField field, Chain chain) {
  4. //代码太长,省略
  5. }
  6. @Override
  7. public int getOrder() {
  8. return EntityColumnFactory.super.getOrder() + 100;
  9. }
  10. }

在上面具体代码的实现中,会先判断 @Transient 注解,只要标记了该注解就会忽略。

然后是读取 JPA 中的 @Column 注解,支持下面的属性:

  • name: 列名
  • insertable: 是否可插入
  • updatable: 是否可更新
  • scale: 小数位数

还支持 JPA 的 @Id 设置主键字段。

支持 @OrderBy 设置字段的排序,这里有一定的限制,不能指定多个字段,只能为空(默认 ASC)或者为 ASCDESC

除了上面提到的有限支持外,其他的 JPA 注解都不支持,如果有好的建议或者应用场景,可以提交 issue 或者 PR 增加额外的支持。