[팁] intellij database schema 기반으로 일괄 엔티티 클래스 생성하기

Posted by 자렌
2019. 1. 24. 10:20 개발

  1. JPA 기반으로 IntelliJ 기능 사용
  • resources 에 persistence.xml 을 생성하면 활성화됨 - 좌측 하단에 [persistence] 버튼을 눌러 탭을 연뒤 우측버튼


위 메뉴를 통해 Entity class를 생성할 경우 아래처럼 생성됨
lombok이 적용된 깔끔한 entity class로 만들고 싶지만 위 방법으로는 불가능

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Table(name = "Copy", schema = "runawaysuccess", catalog = "")
public class CopyEntity {
    private int id;
    private String name;
    private Integer createUserId;
    private Integer updateUserId;
    private Timestamp createAt;
    private Timestamp updateAt;

    @Id
    @Column(name = "id", nullable = false)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "name", nullable = true, length = 50)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Basic
    @Column(name = "create_user_id", nullable = true)
    public Integer getCreateUserId() {
        return createUserId;
    }

    public void setCreateUserId(Integer createUserId) {
        this.createUserId = createUserId;
    }

    @Basic
    @Column(name = "update_user_id", nullable = true)
    public Integer getUpdateUserId() {
        return updateUserId;
    }

    public void setUpdateUserId(Integer updateUserId) {
        this.updateUserId = updateUserId;
    }

    @Basic
    @Column(name = "create_at", nullable = true)
    public Timestamp getCreateAt() {
        return createAt;
    }

    public void setCreateAt(Timestamp createAt) {
        this.createAt = createAt;
    }

    @Basic
    @Column(name = "update_at", nullable = true)
    public Timestamp getUpdateAt() {
        return updateAt;
    }

    public void setUpdateAt(Timestamp updateAt) {
        this.updateAt = updateAt;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CopyEntity that = (CopyEntity) o;
        return id == that.id &&
                Objects.equals(name, that.name) &&
                Objects.equals(createUserId, that.createUserId) &&
                Objects.equals(updateUserId, that.updateUserId) &&
                Objects.equals(createAt, that.createAt) &&
                Objects.equals(updateAt, that.updateAt);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, createUserId, updateUserId, createAt, updateAt);
    }
}



  1. Database 의 script 기반으로 생성
  • intellij에서 database 메뉴를 통해 pojo 클래스를 생성하는 script가 있으며 자유롭게 스크립트를 추가할 수 있다는 것을 발견
  • 원래는 Generate POJOs.groovy script밖에 없지만 [Go to Scripts Directory] 로 script 폴더에 가서 script 생성이 가능


  • POJOs 스크립트를 복사 밑 수정하여 Generate Entity.groovy 생성
import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

/*
* Available context bindings:
*   SELECTION   Iterable<DasObject>
*   PROJECT     project
*   FILES       files helper
*/

packageName = "com.sample;"
typeMapping = [
        (~/(?i)int/)                      : "long",
        (~/(?i)float|double|decimal|real/): "double",
        (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
        (~/(?i)date/)                     : "java.sql.Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)/)                         : "String"
]

FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
}

def generate(table, dir) {
    def tableName = table.getName()
    def className = javaName(tableName, true)
    def fields = calcFields(table)
    new File(dir, className + "Entity.java").withPrintWriter { out -> generate(out, tableName, className, fields) }
}

def generate(out, tableName, className, fields) {
    out.println "package $packageName"
    out.println ""
    out.println "import lombok.Data;"
    out.println "import lombok.NoArgsConstructor;"
    out.println ""
    out.println "import javax.persistence.*;"
    out.println "import java.sql.Date;"
    out.println "import java.sql.Timestamp;"
    out.println ""
    out.println "@NoArgsConstructor"
    out.println "@Data"
    out.println "@Entity"
    out.println "@Table(name = \"$tableName\", schema = \"\", catalog = \"\")"
    out.println "public class $className" + "Entity {"
    out.println ""
    fields.each() {
        if (it.annos != "") out.println ${it.annos}"
        out.println "    @Basic"
        out.println "    @Column(name = \"${it.oriName}\", nullable = false)"
        out.println "    private ${it.type} ${it.name};"
    }
    out.println ""
    out.println "}"
}

def calcFields(table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        def spec = Case.LOWER.apply(col.getDataType().getSpecification())
        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        fields += [[
                           name : javaName(col.getName(), false),
                           oriName : col.getName(),
                           type : typeStr,
                           annos: ""]]
    }
}

def javaName(str, capitalize) {
    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
            .collect { Case.LOWER.apply(it).capitalize() }
            .join("")
            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
    capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

  • 이 방법으로 생성한 결과 - 깔끔하게 class가 생성됨
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Date;
import java.sql.Timestamp;

@NoArgsConstructor
@Data
@Entity
@Table(name = "Copy", schema = "", catalog = "")
public class CopyEntity {

    @Basic
    @Column(name = "id", nullable = false)
    private long id;
    @Basic
    @Column(name = "name", nullable = false)
    private String name;
    @Basic
    @Column(name = "create_user_id", nullable = false)
    private long createUserId;
    @Basic
    @Column(name = "update_user_id", nullable = false)
    private long updateUserId;
    @Basic
    @Column(name = "create_at", nullable = false)
    private java.sql.Timestamp createAt;
    @Basic
    @Column(name = "update_at", nullable = false)
    private java.sql.Timestamp updateAt;

}