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:\Project\jhipster-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:\Project\jhipster-7\.jhipster\File.json configuration file, entity can be automatically generated!
Found the D:\Project\jhipster-7\.jhipster\Chunk.json configuration file, entity can be automatically generated!
Found the D:\Project\jhipster-7\.jhipster\FeedbackRecord.json configuration file, entity can be automatically generated!
info Creating changelog for entities File,Chunk,FeedbackRecord
force .yo-rc.json
force .jhipster\FeedbackRecord.json
force .jhipster\File.json
force .jhipster\Chunk.json
force src\main\java\com\company\datahub\domain\File.java
force src\main\java\com\company\datahub\web\rest\FileResource.java
force src\main\java\com\company\datahub\repository\FileRepository.java
force src\main\java\com\company\datahub\service\FileService.java
force src\main\java\com\company\datahub\service\impl\FileServiceImpl.java
force src\main\java\com\company\datahub\service\dto\FileDTO.java
force src\main\java\com\company\datahub\service\mapper\EntityMapper.java
force src\main\java\com\company\datahub\service\mapper\FileMapper.java
force src\test\java\com\company\datahub\web\rest\FileResourceIT.java
force src\test\java\com\company\datahub\domain\FileTest.java
force src\test\java\com\company\datahub\service\dto\FileDTOTest.java
force src\test\java\com\company\datahub\service\mapper\FileMapperTest.java
force src\main\webapp\app\shared\model\file.model.ts
force src\main\webapp\app\entities\file\file-details.vue
force src\main\webapp\app\entities\file\file-details.component.ts
force src\main\webapp\app\entities\file\file.vue
force src\main\webapp\app\entities\file\file.component.ts
force src\main\webapp\app\entities\file\file.service.ts
force src\main\webapp\app\entities\file\file-update.vue
force src\main\webapp\app\entities\file\file-update.component.ts
force src\test\javascript\spec\app\entities\file\file.component.spec.ts
force src\test\javascript\spec\app\entities\file\file-details.component.spec.ts
force src\test\javascript\spec\app\entities\file\file.service.spec.ts
force src\test\javascript\spec\app\entities\file\file-update.component.spec.ts
force src\main\webapp\app\router\entities.ts
force src\main\webapp\app\main.ts
force src\main\webapp\app\core\jhi-navbar\jhi-navbar.vue
force src\main\webapp\i18n\zh-cn\file.json
force src\main\webapp\i18n\zh-cn\global.json
force src\main\webapp\i18n\en\file.json
force src\main\webapp\i18n\en\global.json
force src\main\java\com\company\datahub\domain\Chunk.java
force src\main\java\com\company\datahub\web\rest\ChunkResource.java
force src\main\java\com\company\datahub\repository\ChunkRepository.java
force src\main\java\com\company\datahub\service\ChunkService.java
force src\main\java\com\company\datahub\service\impl\ChunkServiceImpl.java
force src\main\java\com\company\datahub\service\dto\ChunkDTO.java
force src\main\java\com\company\datahub\service\mapper\ChunkMapper.java
force src\test\java\com\company\datahub\web\rest\ChunkResourceIT.java
force src\test\java\com\company\datahub\domain\ChunkTest.java
force src\test\java\com\company\datahub\service\dto\ChunkDTOTest.java
force src\test\java\com\company\datahub\service\mapper\ChunkMapperTest.java
force src\main\webapp\app\shared\model\chunk.model.ts
force src\main\webapp\app\entities\chunk\chunk-details.vue
force src\main\webapp\app\entities\chunk\chunk-details.component.ts
force src\main\webapp\app\entities\chunk\chunk.vue
force src\main\webapp\app\entities\chunk\chunk.component.ts
force src\main\webapp\app\entities\chunk\chunk.service.ts
force src\main\webapp\app\entities\chunk\chunk-update.vue
force src\main\webapp\app\entities\chunk\chunk-update.component.ts
force src\test\javascript\spec\app\entities\chunk\chunk.component.spec.ts
force src\test\javascript\spec\app\entities\chunk\chunk-details.component.spec.ts
force src\test\javascript\spec\app\entities\chunk\chunk.service.spec.ts
force src\test\javascript\spec\app\entities\chunk\chunk-update.component.spec.ts
force src\main\webapp\i18n\zh-cn\chunk.json
force src\main\webapp\i18n\en\chunk.json
create src\main\java\com\company\datahub\domain\FeedbackRecord.java
create src\main\java\com\company\datahub\web\rest\FeedbackRecordResource.java
create src\main\java\com\company\datahub\repository\FeedbackRecordRepository.java
create src\main\java\com\company\datahub\service\FeedbackRecordService.java
create src\main\java\com\company\datahub\service\impl\FeedbackRecordServiceImpl.java
create src\main\java\com\company\datahub\service\dto\FeedbackRecordDTO.java
create src\main\java\com\company\datahub\service\mapper\FeedbackRecordMapper.java
create src\test\java\com\company\datahub\web\rest\FeedbackRecordResourceIT.java
create src\test\java\com\company\datahub\domain\FeedbackRecordTest.java
create src\test\java\com\company\datahub\service\dto\FeedbackRecordDTOTest.java
create src\test\java\com\company\datahub\service\mapper\FeedbackRecordMapperTest.java
create src\main\java\com\company\datahub\domain\enumeration\FeedbackType.java
create src\main\java\com\company\datahub\domain\enumeration\FeedbackStatus.java
create src\main\java\com\company\datahub\domain\enumeration\FeedbackCloseType.java
create src\main\webapp\app\shared\model\feedback-record.model.ts
create src\main\webapp\app\entities\feedback-record\feedback-record-details.vue
create src\main\webapp\app\entities\feedback-record\feedback-record-details.component.ts
create src\main\webapp\app\entities\feedback-record\feedback-record.vue
create src\main\webapp\app\entities\feedback-record\feedback-record.component.ts
create src\main\webapp\app\entities\feedback-record\feedback-record.service.ts
force src\main\resources\config\liquibase\changelog\20210312045459_added_entity_File.xml
force src\main\resources\config\liquibase\fake-data\file.csv
create src\main\webapp\app\entities\feedback-record\feedback-record-update.vue
force src\main\resources\config\liquibase\master.xml
force src\main\resources\config\liquibase\changelog\20210312045500_added_entity_Chunk.xml
force src\main\resources\config\liquibase\changelog\20210312045500_added_entity_constraints_Chunk.xml
force src\main\resources\config\liquibase\fake-data\chunk.csv
create src\main\resources\config\liquibase\changelog\20210312072243_added_entity_FeedbackRecord.xml
create src\main\resources\config\liquibase\fake-data\feedback_record.csv
create src\main\webapp\app\entities\feedback-record\feedback-record-update.component.ts
create src\test\javascript\spec\app\entities\feedback-record\feedback-record.component.spec.ts
create src\test\javascript\spec\app\entities\feedback-record\feedback-record-details.component.spec.ts
create src\test\javascript\spec\app\entities\feedback-record\feedback-record.service.spec.ts
create src\test\javascript\spec\app\entities\feedback-record\feedback-record-update.component.spec.ts
create src\main\webapp\app\shared\model\enumerations\feedback-type.model.ts
create src\main\webapp\app\shared\model\enumerations\feedback-status.model.ts
create src\main\webapp\app\shared\model\enumerations\feedback-close-type.model.ts
create src\main\webapp\i18n\zh-cn\feedbackType.json
create src\main\webapp\i18n\en\feedbackType.json
create src\main\webapp\i18n\zh-cn\feedbackStatus.json
create src\main\webapp\i18n\en\feedbackStatus.json
create src\main\webapp\i18n\zh-cn\feedbackCloseType.json
create src\main\webapp\i18n\en\feedbackCloseType.json
create src\main\webapp\i18n\zh-cn\feedbackRecord.json
create src\main\webapp\i18n\en\feedbackRecord.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() + "'" +