使用jhipster 加速java web開發

jhipster,中文釋義: Java 熱愛者!

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.

JHipster 可以通過代碼生成,讓你快速開發web應用和微服務。

安裝

  1. 安裝Java,Git Node.js
  2. 安裝 JHipster npm install -g generator-jhipster
  3. 創建應用目錄 mkdir myApp && cd myApp
  4. 運行jhipster命令,根據提示設置應用
  5. 可以通過JDL Studio 來生成jhipster-jdl.jh文件
  6. 然後通過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)
}

可以增加requiredminmax等驗證

字段的註釋:

/**
 * 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雙精度浮點數.
  • BigDecimaljava.math.BigDecimal對象, 當您需要精確的數學計算時使用(通常用於財務操作)。
  • LocalDatejava.time.LocalDate對象, 用於正確管理Java中的日期。
  • Instantjava.time.Instant對象, 用於表示時間戳,即時間線上的瞬時點。
  • ZonedDateTimejava.time.ZonedDateTime對象, 用於表示給定時區(通常是日曆中會議、約定)中的本地日期時間。請注意,REST和持久層都不支持時區,因此您很可能應該使用Instant
  • Durationjava.time.Duration對象, 用於表示時間量。
  • UUIDjava.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>)]}]+
}

例如, 下面的例子裏,我們定義兩個對象,FileChunk,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() + "'" +
            
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章