jhipster,中文释义: Java 热爱者!
JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
JHipster 可以通过代码生成,让你快速开发web应用和微服务。
安装
- 安装Java,Git Node.js
- 安装 JHipster
npm install -g generator-jhipster
- 建议安装最新的7.0版本,
- 创建应用目录
mkdir myApp && cd myApp
- 运行
jhipster
命令,根据提示设置应用 - 可以通过JDL Studio 来生成
jhipster-jdl.jh
文件 - 然后通过
jhipster jdl jhipster-jdl.jh
来生成代码,JDL
后续会重点介绍
JDL 入门
JDL 是jhipster的数据模型定义文件,通过这个文件我们可以定义数据结构,然后jhipster基于这个JDL,就可以生成实体类、服务类以及前端页面。
例如,我们要开发投诉建议,假如设计的数据表如下:
字段 | comment | 类型 | 备注 |
---|---|---|---|
record_id | 主键 | Bigint | 自增 |
feedback_type | 反馈类型 | unsigned tinyint | 枚举值:[1:意见与建议;5:投诉] |
title | 标题 | varchar(64) | |
content | 问题描述 | varchar(512) | |
feedback_status | 反馈状态 | unsigned tinyint | 枚举值:[1:待提交;5:待回复;10:待确认;15:已解决;] |
last_reply_time | 最后回复时间 | timestamp | 与feedback_status联合使用,当状态为2的时候,更新此时间,用于超时判断 |
close_type | 关闭类型 | unsigned tinyint | 枚举值:[1:正常关闭;5:超时关闭;] |
created_date | 创建时间 | timestamp | |
created_by | 创建者 | char(32) |
使用jhipster
,我们可以用jdl
来定义:
/**
* 反馈记录表
*/
entity FeedbackRecord {
/** 反馈类型*/
feedbackType FeedbackType,
/** 问题描述 */
title String,
/** 反馈状态 */
feedbackStatus FeedbackStatus,
/** 是否已完成 */
lastReplyTime Integer,
/** 关闭类型 */
closeType FeedbackCloseType,
/** 创建时间 */
createdDate Instant,
/** 创建者 */
createdBy String
}
/** 反馈类型 */
enum FeedbackType {
ADVICE,
COMPLAINTS
}
/** 反馈状态 */
enum FeedbackStatus {
TO_BE_SUBMIT, TO_BE_REPLY, TO_BE_CONFIRMED
}
/** 关闭类型 */
enum FeedbackCloseType {
NORMALLY, TIMEOUT
}
dto * with mapstruct
service all with serviceImpl
paginate all with pagination
详细讲解:
实体和字段
entity 表示一个实体,可以增加字段,注意,不用增加id
语法是:
[<entity javadoc>]
[<entity annotation>*]
entity <entity name> [(<table name>)] {
[<field javadoc>]
[<field annotation>*]
<field name> <field type> [<validation>*]
}
例如:
entity A {
name String required
age Integer min(42) max(42)
}
可以增加required
、min
、max
等验证
字段的注释:
/**
* This is a comment
* about a class
* @author Someone
*/
entity A {
/** 名称 */
name String
age Integer // this is yet another comment
}
JHipster支持许多字段类型。这种支持取决于您的数据库后端,因此我们使用Java类型来描述它们:JavaString
将以不同的方式存储在Oracle或Cassandra中,这是JHipster的优势之一,可以为您生成正确的数据库访问代码。
String
: Java字符串。它的默认大小取决于基础后端(如果使用JPA,默认情况下为255),但是您可以使用校验规则进行更改(例如,修改max
大小为1024)。Integer
: Java整数。Long
: Java长整数。Float
: Java浮点数.Double
: Java双精度浮点数.BigDecimal
: java.math.BigDecimal对象, 当您需要精确的数学计算时使用(通常用于财务操作)。LocalDate
: java.time.LocalDate对象, 用于正确管理Java中的日期。Instant
: java.time.Instant对象, 用于表示时间戳,即时间线上的瞬时点。ZonedDateTime
: java.time.ZonedDateTime对象, 用于表示给定时区(通常是日历中会议、约定)中的本地日期时间。请注意,REST和持久层都不支持时区,因此您很可能应该使用Instant
。Duration
: java.time.Duration对象, 用于表示时间量。UUID
: java.util.UUID对象.Boolean
: Java布尔型.Enumeration
:Java枚举对象。选择此类型后,子生成器将询问您要在枚举中使用哪些值,并将创建一个特定的enum
类来存储它们。Blob
: Blob对象,用于存储一些二进制数据。选择此类型时,子生成器将询问您是否要存储通用二进制数据,图像对象或CLOB(长文本)。图像将专门在Angular侧进行优化处理,因此可以将其正常显示给最终用户。
字段的数据类型及数据库支持:
枚举
对于可枚举的状态,建议采用枚举值:
enum [<enum name>] {
<ENUM KEY> ([<enum value>])
}
例如:
/** 反馈类型 */
enum FeedbackType {
ADVICE,
COMPLAINTS
}
关系
SQL数据库支持表和表的关联:
OneToOne
OneToMany
ManyToOne
ManyToMany
如何定义关系呢?
relationship (OneToMany | ManyToOne | OneToOne | ManyToMany) {
<from entity>[{<relationship name>[(<display field>)]}] to <to entity>[{<relationship name>[(<display field>)]}]+
}
例如, 下面的例子里,我们定义两个对象,File
和Chunk
,1个Chunk
属于一个File
:
/**
* 文件
*/
entity File {
/** 文件名 */
name String,
/** 文件大小 */
size Long,
/** 文件路径 */
path String,
/** 分片数 */
chunks Integer,
/** 是否已完成 */
complete Integer
}
/**
* 文件分片
*/
entity Chunk {
/** md5值 */
md5 String,
/** 分片序号 */
number Integer,
/** 分片名称 */
name String
}
relationship ManyToOne {
/** 所属文件 */
Chunk{file} to File
}
对应的关系图:
生成代码配置
JHipster提供了丰富的配置,可以用来指定生成代码时的策略,例如是否要生成DTO对象
,是否需要支持分页,是否需要生成service类,如果生成service,是使用serviceClass
还是serviceImpl
。
示例如下:
entity A {
name String required
}
entity B
entity C
// 筛选实体
filter *
// 生成dto
dto A, B with mapstruct
// 分页
paginate A with infinite-scroll
paginate B with pagination
paginate C with pager // pager is only available in AngularJS
// 生成service
service A with serviceClass
service C with serviceImpl
生成代码
首先定义jdl
文件:
/**
* 反馈记录表
*/
entity FeedbackRecord {
/** 反馈类型*/
feedbackType FeedbackType,
/** 问题描述 */
title String,
/** 反馈状态 */
feedbackStatus FeedbackStatus,
/** 是否已完成 */
lastReplyTime Integer,
/** 关闭类型 */
closeType FeedbackCloseType,
/** 创建时间 */
createdDate Instant,
/** 创建者 */
createdBy String
}
/** 反馈类型 */
enum FeedbackType {
ADVICE,
COMPLAINTS
}
/** 反馈状态 */
enum FeedbackStatus {
TO_BE_SUBMIT, TO_BE_REPLY, TO_BE_CONFIRMED
}
/** 关闭类型 */
enum FeedbackCloseType {
NORMALLY, TIMEOUT
}
// 筛选实体
filter *
// 生成DTO
dto * with mapstruct
// 生成带接口和实现的service
service all with serviceImpl
// 支持分页
paginate all with pagination
然后生成代码:
jhipster jdl feedback.jh --force
可以看到类似下面的输出
D:Projectjhipster-7>jhipster jdl feedback.jh --force
INFO! Using JHipster version installed locally in current project's node_modules
INFO! Executing import-jdl feedback.jh
INFO! The JDL is being parsed.
info: The dto option is set for FeedbackRecord, the 'serviceClass' value for the 'service' is gonna be set for this entity if no other value has been set.
INFO! Found entities: FeedbackRecord.
INFO! The JDL has been successfully parsed
INFO! Generating 0 applications.
INFO! Generating 1 entity.
INFO! Generating entities for application undefined in a new parallel process
Found the D:Projectjhipster-7.jhipsterFile.json configuration file, entity can be automatically generated!
Found the D:Projectjhipster-7.jhipsterChunk.json configuration file, entity can be automatically generated!
Found the D:Projectjhipster-7.jhipsterFeedbackRecord.json configuration file, entity can be automatically generated!
info Creating changelog for entities File,Chunk,FeedbackRecord
force .yo-rc.json
force .jhipsterFeedbackRecord.json
force .jhipsterFile.json
force .jhipsterChunk.json
force srcmainjavacomcompanydatahubdomainFile.java
force srcmainjavacomcompanydatahubweb
estFileResource.java
force srcmainjavacomcompanydatahub
epositoryFileRepository.java
force srcmainjavacomcompanydatahubserviceFileService.java
force srcmainjavacomcompanydatahubserviceimplFileServiceImpl.java
force srcmainjavacomcompanydatahubservicedtoFileDTO.java
force srcmainjavacomcompanydatahubservicemapperEntityMapper.java
force srcmainjavacomcompanydatahubservicemapperFileMapper.java
force src estjavacomcompanydatahubweb
estFileResourceIT.java
force src estjavacomcompanydatahubdomainFileTest.java
force src estjavacomcompanydatahubservicedtoFileDTOTest.java
force src estjavacomcompanydatahubservicemapperFileMapperTest.java
force srcmainwebappappsharedmodelfile.model.ts
force srcmainwebappappentitiesfilefile-details.vue
force srcmainwebappappentitiesfilefile-details.component.ts
force srcmainwebappappentitiesfilefile.vue
force srcmainwebappappentitiesfilefile.component.ts
force srcmainwebappappentitiesfilefile.service.ts
force srcmainwebappappentitiesfilefile-update.vue
force srcmainwebappappentitiesfilefile-update.component.ts
force src estjavascriptspecappentitiesfilefile.component.spec.ts
force src estjavascriptspecappentitiesfilefile-details.component.spec.ts
force src estjavascriptspecappentitiesfilefile.service.spec.ts
force src estjavascriptspecappentitiesfilefile-update.component.spec.ts
force srcmainwebappapp
outerentities.ts
force srcmainwebappappmain.ts
force srcmainwebappappcorejhi-navbarjhi-navbar.vue
force srcmainwebappi18nzh-cnfile.json
force srcmainwebappi18nzh-cnglobal.json
force srcmainwebappi18nenfile.json
force srcmainwebappi18nenglobal.json
force srcmainjavacomcompanydatahubdomainChunk.java
force srcmainjavacomcompanydatahubweb
estChunkResource.java
force srcmainjavacomcompanydatahub
epositoryChunkRepository.java
force srcmainjavacomcompanydatahubserviceChunkService.java
force srcmainjavacomcompanydatahubserviceimplChunkServiceImpl.java
force srcmainjavacomcompanydatahubservicedtoChunkDTO.java
force srcmainjavacomcompanydatahubservicemapperChunkMapper.java
force src estjavacomcompanydatahubweb
estChunkResourceIT.java
force src estjavacomcompanydatahubdomainChunkTest.java
force src estjavacomcompanydatahubservicedtoChunkDTOTest.java
force src estjavacomcompanydatahubservicemapperChunkMapperTest.java
force srcmainwebappappsharedmodelchunk.model.ts
force srcmainwebappappentitieschunkchunk-details.vue
force srcmainwebappappentitieschunkchunk-details.component.ts
force srcmainwebappappentitieschunkchunk.vue
force srcmainwebappappentitieschunkchunk.component.ts
force srcmainwebappappentitieschunkchunk.service.ts
force srcmainwebappappentitieschunkchunk-update.vue
force srcmainwebappappentitieschunkchunk-update.component.ts
force src estjavascriptspecappentitieschunkchunk.component.spec.ts
force src estjavascriptspecappentitieschunkchunk-details.component.spec.ts
force src estjavascriptspecappentitieschunkchunk.service.spec.ts
force src estjavascriptspecappentitieschunkchunk-update.component.spec.ts
force srcmainwebappi18nzh-cnchunk.json
force srcmainwebappi18nenchunk.json
create srcmainjavacomcompanydatahubdomainFeedbackRecord.java
create srcmainjavacomcompanydatahubweb
estFeedbackRecordResource.java
create srcmainjavacomcompanydatahub
epositoryFeedbackRecordRepository.java
create srcmainjavacomcompanydatahubserviceFeedbackRecordService.java
create srcmainjavacomcompanydatahubserviceimplFeedbackRecordServiceImpl.java
create srcmainjavacomcompanydatahubservicedtoFeedbackRecordDTO.java
create srcmainjavacomcompanydatahubservicemapperFeedbackRecordMapper.java
create src estjavacomcompanydatahubweb
estFeedbackRecordResourceIT.java
create src estjavacomcompanydatahubdomainFeedbackRecordTest.java
create src estjavacomcompanydatahubservicedtoFeedbackRecordDTOTest.java
create src estjavacomcompanydatahubservicemapperFeedbackRecordMapperTest.java
create srcmainjavacomcompanydatahubdomainenumerationFeedbackType.java
create srcmainjavacomcompanydatahubdomainenumerationFeedbackStatus.java
create srcmainjavacomcompanydatahubdomainenumerationFeedbackCloseType.java
create srcmainwebappappsharedmodelfeedback-record.model.ts
create srcmainwebappappentitiesfeedback-recordfeedback-record-details.vue
create srcmainwebappappentitiesfeedback-recordfeedback-record-details.component.ts
create srcmainwebappappentitiesfeedback-recordfeedback-record.vue
create srcmainwebappappentitiesfeedback-recordfeedback-record.component.ts
create srcmainwebappappentitiesfeedback-recordfeedback-record.service.ts
force srcmain
esourcesconfigliquibasechangelog20210312045459_added_entity_File.xml
force srcmain
esourcesconfigliquibasefake-datafile.csv
create srcmainwebappappentitiesfeedback-recordfeedback-record-update.vue
force srcmain
esourcesconfigliquibasemaster.xml
force srcmain
esourcesconfigliquibasechangelog20210312045500_added_entity_Chunk.xml
force srcmain
esourcesconfigliquibasechangelog20210312045500_added_entity_constraints_Chunk.xml
force srcmain
esourcesconfigliquibasefake-datachunk.csv
create srcmain
esourcesconfigliquibasechangelog20210312072243_added_entity_FeedbackRecord.xml
create srcmain
esourcesconfigliquibasefake-datafeedback_record.csv
create srcmainwebappappentitiesfeedback-recordfeedback-record-update.component.ts
create src estjavascriptspecappentitiesfeedback-recordfeedback-record.component.spec.ts
create src estjavascriptspecappentitiesfeedback-recordfeedback-record-details.component.spec.ts
create src estjavascriptspecappentitiesfeedback-recordfeedback-record.service.spec.ts
create src estjavascriptspecappentitiesfeedback-recordfeedback-record-update.component.spec.ts
create srcmainwebappappsharedmodelenumerationsfeedback-type.model.ts
create srcmainwebappappsharedmodelenumerationsfeedback-status.model.ts
create srcmainwebappappsharedmodelenumerationsfeedback-close-type.model.ts
create srcmainwebappi18nzh-cnfeedbackType.json
create srcmainwebappi18nenfeedbackType.json
create srcmainwebappi18nzh-cnfeedbackStatus.json
create srcmainwebappi18nenfeedbackStatus.json
create srcmainwebappi18nzh-cnfeedbackCloseType.json
create srcmainwebappi18nenfeedbackCloseType.json
create srcmainwebappi18nzh-cnfeedbackRecord.json
create srcmainwebappi18nenfeedbackRecord.json
Entity File generated successfully.
Entity Chunk generated successfully.
Entity FeedbackRecord generated successfully.
Running `webapp:build` to update client app
包含domain、service、controller等都有生成:
测试生成程序
运行程序,
列表页面:
编辑页面:
生成代码介绍
Domain
package com.company.datahub.domain;
import com.company.datahub.domain.enumeration.FeedbackCloseType;
import com.company.datahub.domain.enumeration.FeedbackStatus;
import com.company.datahub.domain.enumeration.FeedbackType;
import java.io.Serializable;
import java.time.Instant;
import javax.persistence.*;
/**
* 反馈记录表
*/
@Entity
@Table(name = "feedback_record")
public class FeedbackRecord implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 反馈类型
*/
@Enumerated(EnumType.STRING)
@Column(name = "feedback_type")
private FeedbackType feedbackType;
/**
* 问题描述
*/
@Column(name = "title")
private String title;
/**
* 反馈状态
*/
@Enumerated(EnumType.STRING)
@Column(name = "feedback_status")
private FeedbackStatus feedbackStatus;
/**
* 是否已完成
*/
@Column(name = "last_reply_time")
private Integer lastReplyTime;
/**
* 关闭类型
*/
@Enumerated(EnumType.STRING)
@Column(name = "close_type")
private FeedbackCloseType closeType;
/**
* 创建时间
*/
@Column(name = "created_date")
private Instant createdDate;
/**
* 创建者
*/
@Column(name = "created_by")
private String createdBy;
// jhipster-needle-entity-add-field - JHipster will add fields here
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public FeedbackRecord id(Long id) {
this.id = id;
return this;
}
public FeedbackType getFeedbackType() {
return this.feedbackType;
}
public FeedbackRecord feedbackType(FeedbackType feedbackType) {
this.feedbackType = feedbackType;
return this;
}
public void setFeedbackType(FeedbackType feedbackType) {
this.feedbackType = feedbackType;
}
public String getTitle() {
return this.title;
}
public FeedbackRecord title(String title) {
this.title = title;
return this;
}
public void setTitle(String title) {
this.title = title;
}
public FeedbackStatus getFeedbackStatus() {
return this.feedbackStatus;
}
public FeedbackRecord feedbackStatus(FeedbackStatus feedbackStatus) {
this.feedbackStatus = feedbackStatus;
return this;
}
public void setFeedbackStatus(FeedbackStatus feedbackStatus) {
this.feedbackStatus = feedbackStatus;
}
public Integer getLastReplyTime() {
return this.lastReplyTime;
}
public FeedbackRecord lastReplyTime(Integer lastReplyTime) {
this.lastReplyTime = lastReplyTime;
return this;
}
public void setLastReplyTime(Integer lastReplyTime) {
this.lastReplyTime = lastReplyTime;
}
public FeedbackCloseType getCloseType() {
return this.closeType;
}
public FeedbackRecord closeType(FeedbackCloseType closeType) {
this.closeType = closeType;
return this;
}
public void setCloseType(FeedbackCloseType closeType) {
this.closeType = closeType;
}
public Instant getCreatedDate() {
return this.createdDate;
}
public FeedbackRecord createdDate(Instant createdDate) {
this.createdDate = createdDate;
return this;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public String getCreatedBy() {
return this.createdBy;
}
public FeedbackRecord createdBy(String createdBy) {
this.createdBy = createdBy;
return this;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof FeedbackRecord)) {
return false;
}
return id != null && id.equals(((FeedbackRecord) o).id);
}
@Override
public int hashCode() {
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
return getClass().hashCode();
}
// prettier-ignore
@Override
public String toString() {
return "FeedbackRecord{" +
"id=" + getId() +
", feedbackType='" + getFeedbackType() + "'" +