# 实体定义

实体可以认为是对数据库表的映射,实体的字段即为列的映射,有了这一份数据,可以通过调用简单的方法快速进行数据访问、生成SQL,可以控制字段级别的可操作性,甚至快速生成对应的CRUD接口等。

实体常用可见:

在实体生效范围内,创建Class类并使用@Entity注解定义实体,实体名默认为类名(若类名以Entity结尾,则以去掉Entity后缀作为实体名),映射的数据库表名默认为实体名驼峰转下划线格式,且首字母小写:

import fly.core.data.annotation.Entity;

// 默认实体名:FlyUser,默认映射数据库表名:fly_user
@Entity
public class FlyUserEntity {}

# @Entity

@Entity为定义实体的注解,可配置属性如下:

注解属性 说明 类型 默认值
name 实体名称 String 类名,默认移除Entity后缀
table 数据库表名 String 实体名驼峰转下划线格式,首字母小写
sortable 可排序的字段列表 String[] -
filterable 可过滤的字段列表 String[] -
searchable 可搜索字段,使用参考快速搜索 String[] -
writable 可写的字段列表,即在创建、修改操作中是否允许外部传入字段值 String[] -
autoDdl 是否自动建表,自动补充字段及关系外键等,见数据库管理 AutoDdl AutoDdl.SUPPORTED
autoDdlProperty 是否自动建表的配置属性。使用:@Entity(autoDdlProperty = "${auto-ddl-property}"),然后通过Spring或环境变量等方式配置auto-ddl-property: DISABLED String -
indexes 使用参考定义索引 Index[] -
keys 使用参考唯一键 Key[] -
foreignKeys 使用参考定义外键 ForeignKey[] -
listeners 监听使用Dao进行实体新增/更新等操作,使用参考监听器 Class<?>[] -

# 定义字段

字段在实体中,可以作为对数据库表的列的映射。

字段命名规则:类属性要作为字段时,建议使用驼峰命名,默认字段名为属性名,字段对应的数据库列名默认为字段名驼峰转下划线格式,且首字母小写。

# 主键字段

主键一般为自动生成,框架根据常见场景提供了几个不同生成策略的主键字段注解:

注解 生成策略 类型参考
@AutoIncrement 数据库自增 Integer
@UUID 生成长度为36的随机字符串 String
@ShortUUID 生成长度为22的随机字符串 String
@SnowflakeID 生成18位的数值 Long
@Entity
public class FlyUserEntity {
    
    @UUID
    protected String id;
    
    // get/set
    
}

若不需要自动生成,可以使用无生成策略的主键字段注解@Id@Id可配置属性如下:

注解属性 说明 类型 默认值
generator Id生成策略,相当于在属性上添加@Generator注解。设置为none表示不需要自动生成Id String auto,根据属性类型自动处理

# 普通字段

对于主键外的普通列,可使用@Column或者@NullColumn注解定义字段。@Column注解默认字段不可为空,@NullColumn注解认为字段可为空,@Column中可以通过nullable属性修改字段是否为空的状态。

@Column
protected String name;

@Column(nullable = true)
protected String title;

@NullColumn(name = "description")
protected String desc;

@Column字段注解可配置属性综合如下(@NullColumn相似,只是部分默认值有所不同):

注解属性 说明 类型 默认值
name 数据库列名 String 字段名下划线格式
domain 指定字段定义域名称 String -
definition 等同于注解value()字段定义表达式,可以定义数据库列类型等 String -
unique 是否唯一,用于ddlAuto数据库管理 boolean false
nullable 是否允许为null boolean false
length 数据库列长度 int -
precision 数据库列数值精度 int -
scale 数据库列数值范围 int -
columnDefault @ColumnDefault - 字段在数据库中的默认值,用于ddlAuto数据库管理 String -
expression @ValueExpression - 创建和更新时字段的求值表达式 String -
defaultExpression @DefaultExpression - 创建时若未传入字段值,执行该表达式取默认值 String -
insertExpression 创建时字段的求值表达式 String -
updateExpression 更新时时字段的求值表达式 String -
insertable 是否允许在创建时写入数据库 boolean true
updatable 是否允许在更新时写入数据库 boolean true
settable @Settable - 是否允许由外部赋值 boolean -
onInsertNotSettable 当插入记录时发现不可赋值字段时的处理方式:DENY为拒绝赋值并抛出异常;IGNORE为忽略字段 OnNotSettable DENY
onUpdateNotSettable 当更新记录时发现不可赋值字段时的处理方式 OnNotSettable DENY
writeProtected 是否开启写保护,写保护字段不能直接写入,需要在dao创建或更新时执行额外的方法:dao.withProtected().update(entity) boolean false
sortable @Sortable - 是否允许排序 boolean false
searchable @Searchable - 是否作为快捷搜索字段 boolean false
filterable @Filterable - 是否允许过滤 boolean false
filteredByDefault 是否在查询中默认作为过滤条件 boolean false
filteredExpression 默认过滤条件的求值表达式,表达式结果作为字段过滤条件,与filteredByDefaultfilteredIf组合使用 String -
filteredIf 表达式,在filteredByDefault的基础上再次动态判断是否过滤filteredExpression String -

部分属性有同名独立注解,独立注解内部也能够设置字段的其他属性,如@ValueExpression(settable = true),若一个类属性上有多个注解,且都设置了同一个字段属性:

@Column(writable = false)
@ValueExpression(settable = true)
protected String appId;

一般只有与注解的默认值不同时才会将值设置入字段(自定义注解除外,如常用注解),再此基础上根据基础注解处理的优先级从低到高为:

  • @Column/@NullColumn
  • 类似@Writable的独立注解

大部分情况下,字段的属性配置优先级可以参考如上。

# 定义表达式

表达式解析类:fly.data.relational.domain.DomainParser

varchar(200) not null default 'test'

一个表达式可以同时定义字段名、数据类型或其他属性,不同属性由空格分隔,部分特殊配置可能会跨空格解析。

  • 列类型
varchar(200)

支持类型可见fly.data.common.jdbc.JdbcTypeMapping.getTypeCode(String typeName)方法,不区分大小写,类型后若带括号,只有一个数值则为长度type(length),有两个数值则为精度及范围type(precision,scale)

常用类型有:

varchardatatimetimestampbooleanlongvarcharintlong

  • 匹配格式:{property}({value})

{property}来源于fly.data.relational.domain.DomainBuilder,如DomainBuilder内有属性String expr,则:

'expr(#vars.now)' -> @Column(expr = "#vars.now")

对于Boolean类型的属性,若要设为true,也可以简写为:

'expr(#vars.now) writable' -> @Column(expr = "#vars.now", writable = true)
  • 特殊配置
配置 说明
auto_increment / increment 数据库自增
primary / primary key 是否为主键
optional / null / not null / required 影响nullable,是否可为null
default {value} 数据库列默认值

# 定义域

了解字段表达式后,对于一些通用的字段配置可以抽出作为一个定义域,在@Column(domain = "name")中使用,方便统一管理。在YAML格式的配置文件中进行定义,文件读取优先级从低到高为:

  • classpath*:META-INF/domains/*.yml

  • classpath*:META-INF/domains.yml

  • classpath:domains/*.yml

  • classpath:domains.yml

示例:

/resources/domains.yml

json1: varchar(200) null default '{}'
@Column(domain = "json1", length = "500")
protected String json;

domain指定定义域,json字段根据名称获取对应的字段配置,这里注解配置的优先级会高于定义域(需与注解默认值不同才会生效),如果需要自定义部分配置可以直接在注解中调整。

# 常用注解

框架提供常用使用场景的字段注解,下列说明是指配置注解后默认生效的状态,注解内部可以对部分字段属性做修改,具体可进注解内查看。

注解包路径为:fly.core.data.domains

字段注解 默认作用
@CreatedAt 表示创建时间字段,创建时自动填充系统当前时间,设置后字段不可修改,忽略外部传值
@CreatedBy 表示创建人字段,创建时自动填充当前用户id,设置后字段不可修改,忽略外部传值
@CreatedByName 表示创建人名称字段,创建时自动填充当前用户name,设置后字段不可修改,忽略外部传值
@CreatedFrom 表示从哪个客户端创建,创建时自动填充当前客户端id,设置后字段不可修改,忽略外部传值
@Deleted 表示软删除字段,默认0未删除、1已删除,设置后字段不可外部传值
@Password 表示密码字段,指定序列化器为password,长度默认200
@TenantId 表示租户字段,创建时自动填充当前用户或客户端的租户id,设置后字段不可修改
@UpdatedAt 表示更新时间字段,更新时自动填充系统当前时间,忽略外部传值
@UpdatedBy 表示更新人字段,更新时自动填充当前用户id忽略外部传值
@UpdatedByName 表示更新人字段,更新时自动填充当前用户name忽略外部传值
@CreatedBy
protected String createdBy;

# 定义索引

@Entity注解的indexes属性或者直接在实体类上使用@Index注解进行索引定义:

@Entity(
	indexes = {
    	@Index(name = "idx_login_name", columns = "loginName", unique = false)
    }
)
public class UserEntity {
    
    @Id
    protected String id;
    
    @Column
    protected String loginName;
    
    // get/set
    
}

示例中idx_login_name为索引名称,columns为索引包括的字段,unique表示该索引是否为唯一索引。

定义索引可以用于在数据迁移ddlAuto自动构建数据库表中自动创建索引。

# 唯一键

@Entity注解的keys属性或者直接在实体类上使用@Key注解进行唯一键定义:

@Entity(
	keys = {
        @Key(name = "ak_auth_code", fields = {"authorId", "code"})
    }
)
public class Entity {
    
    @Id
    private String id;
    
    @Column
    @ManyToOne(Author.class)
    private String authorId;
    
    @Column
    private String code;
    
    // get/set
    
}

唯一键可以在数据访问的修改/删除/查询方法中起到类似主键ID的作用,同时在数据迁移ddlAuto自动构建数据库表中自动创建唯一索引。

# 定义外键

@Entity注解的foreignKeys属性或者直接在实体类上使用@ForeignKey注解进行外键定义:

@Entity(
	foreignKeys = {
    	@ForeignKey(name = "fk_org_parent", columns = "parentId", foreignEntity = Org.class, foreignColumns = "id")
	}
)
public class Org {
    
    @Id
    protected String id;
    
    @Column
    protected String name;
    
    @NullColumn("varchar(36)")
    protected String parentId;
    
    // get/set
    
}

示例中外键名称为fk_org_parentcolumnsforeignColumns为外键对应的字段,严格按照顺序对应,foreignEntity为外键关联的实体类。

用于在数据迁移ddlAuto自动构建数据库表中自动创建外键约束。

# 数据模型

数据模型相当于实体的拓展,根据增、改、查询等场景,一个实体可以有多个数据模型,不同数据模型拥有的属性可能不同,又可以共享实体及实体中同名属性的字段定义

使用@MappingToEntity注解的valuename属性指定映射的实体,注意,数据模型必须有有效的映射实体,没有将抛出异常

@MappingToEntity(Entity.class)
public class EntityCreateParams {}
注解属性 说明 类型 默认值
value 映射的实体类,优先根据value查找实体 Class<?> Void.class
name 映射的实体名,若value不是有效值(等于Void.class或为当前类),才根据name查找实体 String -
顶部