本文翻译自官网:https://jhipster.github.io/jdl/
功力有限,部分不会翻译的地方直接写译文了。由于目前JHipster的资料还比较少,先找一些英文的资料翻译翻译。
上来就找JDL也是有原因的,JDL也算是JHipster的一点门槛了,基本上要在JHipster里创建功能背后的对象,最好使用这种方式,因为JHipster会根据JDL生成对应对象需要的一堆东西,包括不仅限于CRUD操作。在网上找一些简单的例子可以知道如何创建简单的实体和关系,但是实际项目使用,你肯定会想使用JDL,而不是那个问答界面,实际操作你也会发现,用问答操作太容易出错了。
JHipster Domain Language (JDL)
JDL是JHipster的领域特殊语言(specific domain language).这种语言的目的是为了使用简单和友好的语法在一个文件(也可以是多个文件)里描述实体以及他们的关系。
你可以使用在线的JDL-Studio(https://jhipster.github.io/jdl-studio/)这个IDE去创建JDL以及UML可视化图像。你同时也可以用这个工具创建或者输出或者分享你的JDL模型的URL。
你可以使用import-jdl
子生成器使一个JDL文件生成你想要的实体。使用这个自生成器的命令是yo jhipster:import-jdl your-jdl-file.jh
。你也可以使用JHipster UML使一个JDL文件生成你想要的实体,使用这个工具的命令是在生成的JHipster应用目录下运行jhipster-uml your-jdl-file.jh
。 (JHipster UML也有专门的教程)
这些工具是使用实体子生成器的替代。设计这些工具的理念是使用可视化工具总是比使用经典Yeoman问答容易管理实体间的关系。
JDL项目是开源的,地址是https://github.com/jhipster/jhipster-core/。这个项目和JHipster一样是开源项目 (Apache 2.0 License)。这个项目也可以作为节点库来处理JDL。
(如果你喜欢这个项目,别忘了点星在github上。这句就不仔细翻译了。。)
这是这篇文章的主要内容:
- JDL Sample
- How to use it
- The language
3.1 Entity Declaration
3.2 Relationship Declaration
3.3 Enumerations
3.4 Blobs
3.5 Option declaration
3.6 Microservice-related options - Commenting
- All the relationships
- Constants
- Annexes
- Issues and bugs
JDL Sample
我们把Oracle的"人力资源"例子翻译成了JDL,地址在这里https://github.com/jhipster/jhipster-core/blob/master/lib/dsl/example.jh。这个例子同时被加载为JDL-Studio的默认例子,见地址https://jhipster.github.io/jdl-studio/
How to use it
如果你想使用JHipster UML而不是import-jdl
子生成器,你需要安装这个工具,命令是运行npm install -g jhipster-uml
。
你可以使用JDL文件去生成实体:
- 使用扩展名 '.jh'或者'.jdl'创建一个文件
- 使用JDL-STudio声明你的实体和关系,然后从这个工具里下载你的文件
- 在JHipster生成的应用文件夹中,运行命令
yo jhipster:import-jdl my_file.jdl
或者jhipster-uml my_file.jdl
然后,就好了!
如果你是团队工作,那么你的文件可能有多个。这个运行命令可以指定多个文件,不需要把多个文件合为一个。命令如下yo jhipster:import-jdl my_file1.jh my_file2.jh
或者 jhipster-uml my_file1.jh my_file2.jh
如果你想把这些用在自己的项目里,你可以添加这个依赖在本地,命令为npm install jhipster-core --save
。然后保存在你的package.json
文件中。
The language
我们尽力让语法对开发者友好,你可以使用这个语言进行三个事:
- 声明实体以及其属性
- 声明实体之间的关系
- 声明一些JHipster特定的选项
Entity declaration
实体声明的语法如下:
entity <entity name> {
<field name> <type> [<validation>*]
}
<entity name>
是实体的名字<field name>
是实体的字段属性的名字<type>
JHipster支持的字段属性<validation>
可选选项,字段是否进行校验
支持的类型以及校验如链接https://jhipster.github.io/jdl/#annexes。如果校验需要一个值,在校验后面简单增加(<value>)
即可。
这是一个JDL代码的例子:
entity A
entity B
entity C {}
entity D {
name String required,
address String required maxlength(100),
age Integer required min(18)
}
因为JDL设计理念是简单使用和简单可读,如果你的实体是空的(没有字段),你可以直接声明一个实体使用entity A
或者 entity A {}
.
注意:JHipster会增加一个默认的id
字段,所以你不用担心这个字段。
Relationship declaration
关系多的声明语法如下:
relationship (OneToMany | ManyToOne | OneToOne | ManyToMany) {
<from entity>[{<relationship name>}] to <to entity>[{<relationship name>}]
}
(OneToMany | ManyToOne| OneToOne | ManyToMany)
是关系的类型<from entity>
是拥有此关系的实体拥有者:the source<to entity>
是这个关系连接到的实体名字:the destination<relationship name>
is the name of the field having the other end as type(不会翻、、请大侠赐教,个人理解这个就是对应关系的一个名字,这个名字可以任意起的,这个名字后面加小括号指定这个关系指定的字段)required
注入的字段是否是必须的。
下面是一些简单的例子:
一个BOOK有一个,必须的,Author,一个Author有几本Books。
entity Book
entity Author
relationship OneToMany {
Author{book} to Book{writer(name) required}
}
当然,在实际例子中,你会有一大堆关系,总是写同样的三行会很无聊。所以你可以这么声明:
entity A
entity B
entity C
entity D
relationship OneToOne {
A{b} to B{a},
B{c} to C
}
relationship ManyToMany {
A{d} to D{a},
C{d} to D{c}
}
默认,连接使用id字段,但是你可以连接使用其他字段,所以你可能会这么写
entity A {
name String required
}
entity B
relationship OneToOne {
A{b} to B{a(name)}
}
Enumerations
使用JDL的Enum的语法如下:
- 在文件中声明一个枚举:
enum Language {
FRENCH, ENGLISH, SPANISH
}
entity Book {
title String required,
description String,
language Language
}
Blob (byte[])
JHipster给予你很大的自由,可以选择一个图片类型或者任何二进制类型。JDL让你一样得到这些东西:仅仅使用编辑器创建一个惯例类型(见DataType),使用下面的约定来命名:
AnyBlob
或者仅仅Blob
去创建一个任意二进制类型ImageBlob
创建一个图片类型的字段ImageBlob
创建一个CLOB的字段(long text)
Option declaration
在JHipster,你可以为你的实体指定特殊选项,例如分页或者DTO。你可以使用JDL做同样的事:
entity A {
name String required
}
entity B {}
entity C {}
dto A, B with mapstruct
paginate A, C with infinite-scroll
paginate B with pager
service A with serviceClass
service C with serviceImpl
语法中的关键字dto
, paginate
, service
及 with
就是为了支持这些特性。如果错误的选项被指定,JDL会报红色错误信息,并且会忽略这个选项,以保证不损坏JHipster的JSON文件
Service option
如果没有指定services会创建一个资源类直接调用库接口。这是默认和最简单的设置,见A。Service with serviceClass (see B) will make the resource call the service class which will call the repository interface. Service with serviceImpl (see C) will make a service interface which will be used by the resource class.接口implenment了一个impl类,这个类将会call repository interface。
如果不确定是否需要service,可以使用默认的设置,对CRUD是ok的。如果你有很多业务逻辑,要使用很多库,比较理想就是创建一个service类了。JHipster不推荐不必要的接口,但是如果你需要,你就建继承impl的service类。
entity A {}
entity B {}
entity C {}
// no service for A
service B with serviceClass
service C with serviceImpl
JDL也支持多选项设置:
entity A
entity B
...
entity Z
dto * with mapstruct
service all with serviceImpl
paginate C, with pager
注意 *
和all
是等价的。最新版本还引进了排除语法(这个语法对于设置所有实体的选项时很有用)
entity A
entity B
...
entity Z
dto * with mapstruct except A
service all with serviceImpl except A, B, C
paginate C, with pager
在JHipster里,你可以选择是否不要一些客户端代码,或者服务端代码。即使你想添加一些后缀对Angular相关的文件,你都可以这么做。在JDL,你也可以
entity A
entity B
entity C
skipClient for A
skipServer for B
angularSuffix * with mySuperEntities
最后,表名也可以指定,这样实体的名字和表名可以不一样,默认实体的名字就是表的名字。
entity A // A is the table's name here
entity B (the_best_entity) // the_best_entity is the table's name
Microservice-related options
JHipster V3,可以创建微服务。你可以指定一些选项在JDL中生存你想要的实体:微服务的名称,搜索引擎。指定微服务的名字的例子:
entity A
entity B
entity C
microservice * with mysuperjhipsterapp except C
microservice C with myotherjhipsterapp
search * with elasticsearch except C
第一种选项时用来告诉JHipster,你的微服务如何处理你的实体,第二种是指定你想使用的搜索引擎。
Commenting & Javadoc
可以给JDL文件添加Javadoc & comments。
和Java一样,下面的例子说明如何添加:
/**
* Class comments.
* @author The JHipster team.
*/
entity MyEntity { // another form of comment
/** A required attribute */
myField String required,
mySecondField String // another form of comment
}
/**
* Second entity.
*/
entity MySecondEntity {}
relationship OneToMany {
/** This is possible too! */
MyEntity{mySecondEntity}
to
/**
* And this too!
*/
MySecondEntity{myEntity}
}
这些注释会被JHipster自动加为Javadoc comments。
JDL处理自己的注释如下:
// an ignored comment
/** not an ignored comment */
//
开头的注释被人是JDL的注释,不会被转换为Javadoc。
注意JDL Studio 指定以#
开头也会忽略。
另一种形式的注释如下:
entity A {
name String /** My super field */
count Integer /** My other super field */
}
这里A的name会被注释为 My super field
,第二个字段会注释为My other super field
。逗号是不强制使用的,但是你要注意不要因为逗号出问题:
entity A {
name String, /** My comment */
count Integer
}
这里A的name不会有注释,而count会。
All the relationships
解释如何使用JDL创建关系。
One-to-One
定义一个双向关系,例如车有一个司机,司机有一个车。
entity Driver {}
entity Car {}
relationship OneToOne {
Car{driver} to Driver{car}
}
一个单向的例子,Citizen有一个Passpport,但是Passport没有权限获知他的拥有者。
entity Citizen {}
entity Passport {}
relationship OneToOne {
Citizen{passport} to Passport
}
One-to-Many
一个双向的例子,Owner有没有,一个或者多个Car对象,Car知道自己的拥有者。
entity Owner {}
entity Car {}
relationship OneToMany {
Owner{car} to Car{owner}
}
JHipster不支持这个关系单向的情况,但是如果有,会长这样
entity Owner {}
entity Car {}
relationship OneToMany {
Owner{car} to Car
}
Many-to-One
One-to-Many 关系倒过来和前面一样。这种关系单向的例子,例如Ca知道自己的拥有者
entity Owner {}
entity Car {}
relationship ManyToOne {
Car{owner} to Owner
}
Many-to-Many
最后这个例子,Car知道自己的拥有者,Driver对象可以获取自己的cars。
entity Driver {}
entity Car {}
relationship ManyToMany {
Car{driver} to Driver{car}
}
注意拥有关系的对象,在to的左边。
Constants
对于JHipster Core v1.2.7,JDL支持数值型常量。例子:
DEFAULT_MIN_LENGTH = 1
DEFAULT_MAX_LENGTH = 42
DEFAULT_MIN_BYTES = 20
DEFAULT_MAX_BYTES = 40
DEFAULT_MIN = 0
DEFAULT_MAX = 41
entity A {
name String minlength(DEFAULT_MIN_LENGTH) maxlength(DEFAULT_MAX_LENGTH)
content TextBlob minbytes(DEFAULT_MIN_BYTES) maxbytes(DEFAULT_MAX_BYTES)
count Integer min(DEFAULT_MIN) max(DEFAULT_MAX)
}
Annexes
Here is the types supported by JDL:
SQL | MongoDB | Cassandra | Validations |
---|---|---|---|
String | String | String | required, minlength, maxlength, pattern |
Integer | Integer | Integer | required, min, max |
Long | Long | Long | required, min, max |
BigDecimal | BigDecimal | BigDecimal | required, min, max |
Float | Float | Float | required, min, max |
Double | Double | Double | required, min, max |
Enum | Enum | required | |
Boolean | Boolean | Boolean | required |
LocalDate | LocalDate | required | |
Date | required | ||
ZonedDateTime | ZonedDateTime | required | |
UUID | required | ||
Blob | Blob | required, minbytes, maxbytes | |
AnyBlob | AnyBlob | required, minbytes, maxbytes | |
ImageBlob | ImageBlob | required, minbytes, maxbytes | |
TextBlob | TextBlob | required, minbytes, maxbytes |
Issues and bugs
JDL的github连接:https://github.com/jhipster/jhipster-core
JHipster贡献指南:https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md
提交issue和Requsts请使用我们的项目
- JDL issue tracker :https://github.com/jhipster/jhipster-core/issues
- JDL Pull Requests :https://github.com/jhipster/jhipster-core/pulls
请尽量精确你的问题:
- 一个Post必须只有一个问题,或者一个需求。
- 提需求是ok的,但是指派的任务必须是足够原子的,且可以被理解