そこに仁義はあるのか(仮)

略してそこ仁!

SIerといえばソースコードの自動生成だ!テーブルとEntityクラスを自動生成するサムシン(PostgreSQL版)

これはPostgreSQL Advent Calendar 2015 - Qiitaの記事です。
昨日はsawada_masahikoさんのPostgreSQL開発の基本動作まとめ - Qiitaでした!

SIerといえば、ソースコードの自動生成ですね!
開発を進めていくうえで、コロコロと変わっていくテーブル構成。。。
そんな中で、まったくソースコードを触らずに(sqljavaも触らない!つまり誰でも!どんな人でも!!作業できる!!!
テーブル構築からデータ投入、さらにはEntityクラスを生成することが出来るツール(mavenプラグイン)を、今のプロジェクトで使っているので、それの紹介と使いかたを説明します。
いろんなDBに対応しているけど、今のプロジェクトではPostgreSQLを使っているので、今回はPostgreSQL版の使いかた説明です!*1

なお、今回使っているPostgreSQLのバージョンは9.1.15です!

★必要なもの

  • PostgreSQL (インストールとユーザ作成が完了しているもの)
  • maven
  • ObjectBrowserER(テーブルの自動生成で必要。ライセンスいる。)
  • プロジェクト用のmaven リポジトリ(もしプロジェクトの人にダンプファイルをお手軽に配布したいなら。)(うちのプロジェクトではArtifactoryを使ってます)

★そもそもみんな自動生成ってどうしてるの?

Googleさんで調べてみると、こんな感じでS2JDBC-Genを使っている人が多そう。

f:id:syobochim:20151212203219p:plain

でも、S2JDBC-Genの説明を見ると、こんな感じでDBにテーブルがあること前提で記載されている。
かつ、生成した後は、Entityファイルを修正しろ的なことが描かれている。
(みんながみんな、テーブルを作れるわけじゃない!Javaを修正できるわけじゃない!)

f:id:syobochim:20151212204534p:plain

キャプチャ取得元:Seasar2 - S2JDBC-Gen - S2JDBC-Genとは

できれば、sqlがわからなくても、Javaがわからなくても、なんかツールが勝手によしなにやっといてほしい!!

★そんな悩みを解消してくれるツールがこちら

コンセプトは@さんがシステムエンジニア Advent Calendar 2015 - Qiitaで話してくれました!
qiita.com

今私がいるプロジェクトの隣の隣くらいのチームの人達が作ってる(・_・)

github.com

これはS2JDBC-Genをラップしているので、基本的にはS2JDBC-Genと同じようにしようできる!
ざっくりな説明になりますが、下の図のように、ER図とデータさえあれば実行できるので、sqlJavaを書かなくてもいいという!

f:id:syobochim:20151212210712p:plain

★やってみよう

☆まずはER図を用意する

ObjectBrowserERを使用してER図を描いていく。
ここでは、特にsqlを書いたりする必要はなくて、すべてGUIでの操作になる。
こんな感じでER図を描く。

f:id:syobochim:20151212231002p:plain

csvファイルにデータを書く

テーブルに格納するデータをcsvファイルで書いていく。
ちなみに、csvファイル名は[テーブル名].csvにする。

f:id:syobochim:20151212231018p:plain

☆gsp-dba-pluginをローカルでビルドする

ただし、これはセントラルにはまだないので、ローカルでbuildしておく必要がある。
(かつ、Artifactoryなどのプロジェクト用のmavenリポジトリにjarを格納しておく必要がある。)

以下コマンドを叩くと、ビルドが実行されてローカルの~/.m2/repositoryフォルダにjarができる!
お手軽〜

// gsp-dba-pluginをビルド!
> git clone https://github.com/coastland/gsp-dba-maven-plugin.git
> cd gsp-dba-maven-plugin
> mvn install

☆pomを書く

やっとPostgreSQLが出てきた!

pomにこんな感じでプラグインを設定していく

  <build>
    <plugins>
      <plugin>
        <groupId>jp.co.tis.gsp</groupId>
        <artifactId>gsp-dba-maven-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <!-- DBの情報を書いていく -->
          <driver>org.postgresql.Driver</driver>
          <url>jdbc:postgresql://localhost:5432/postgres</url>
          <!-- ユーザは事前に作っておく -->
          <adminUser>postgres</adminUser>
          <adminPassword>postgres</adminPassword>
          <user>postgres</user>
          <password>postgres</password>
          <!-- ここで指定したスキーマ名になる -->
          <schema>sample</schema>

          <!-- csvファイルの格納先パス。データを読み込むよ -->
          <dataDirectory>src/test/resources/data</dataDirectory>
          <!-- ER図の格納先 -->
          <erdFile>src/main/resources/entity/data-model.edm</erdFile>
          <lengthSemantics>CHAR</lengthSemantics>

          <!-- Entityクラスはcom.syobochim.entityパッケージに出来る -->
          <rootPackage>com.syobochim</rootPackage>
          <entityPackageName>entity</entityPackageName>

          <!-- Entityクラスにアクセサつけるかどうか -->
          <useAccessor>true</useAccessor>

          <!-- jarも出来るけど、javaファイルをどこに生成するか -->
          <javaFileDestDir>target/generated-sources/entity</javaFileDestDir>
        </configuration>
        <dependencies>
          <!-- プロジェクトで使用するDB製品にあわせたJDBCドライバに修正してください。 -->
          <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4-1201-jdbc41</version>
          </dependency>
        </dependencies>

このコードはこちら
sandbox/gsp-dba-plugin-sample at master · syobochim/sandbox · GitHub

☆実行する!

こんな感じでコマンドを実行する。

> mvn install

と、こんな感じでtarget配下にjarやEntityが生成される!

├─src
│  ├─main
│  │  ├─java
│  │  └─resources
│  │      └─entity
│  │              data-model.edm
│  │              
│  └─test
│      ├─java
│      └─resources
│          └─data
│                  DEPARTMENT.csv
│                  EMPLOYEE.csv
│                  
└─target
    │  sample-1.0-SNAPSHOT.jar
    │  
    ├─classes
    │  │  convention.dicon
    │  │  jdbc.dicon
    │  │  s2jdbc.dicon
    │  │  
    │  └─entity
    │          data-model.edm
    │          
    ├─ddl
    │      10_CREATE_DEPARTMENT.sql
    │      10_CREATE_EMPLOYEE.sql
    │      20_CREATE_PK_DEPARTMENT.sql
    │      20_CREATE_PK_EMPLOYEE.sql
    │      30_CREATE_FK_EMPLOYEE01.sql
    │      
    ├─dump
    │      sample-testdata-1.0-SNAPSHOT.jar
    │      sample.dmp
    │      
    ├─generated-sources
    │  └─entity
    │      └─com
    │          └─syobochim
    │              └─entity
    │                      Department.java
    │                      Employee.java
    │                      
    ├─maven-archiver
    │      pom.properties
    │      
    ├─maven-status
    │  └─maven-compiler-plugin
    │      ├─compile
    │      │  └─default-compile
    │      │          inputFiles.lst
    │      │          
    │      └─testCompile
    │          └─default-testCompile
    │                  inputFiles.lst
    │                  
    └─test-classes
        └─data
                DEPARTMENT.csv
                EMPLOYEE.csv

生成できたJavaはこんな感じ

package com.syobochim.entity;

import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * DEPARTMENT
 *
 */
@Generated("GSP")
@Entity
@Table(name = "department")
public class Department implements Serializable {

    private static final long serialVersionUID = 1L;

    /** DEPARTMENT_ID */
    private Integer departmentId;

    /** DEPARTMENT_NAME */
    private String departmentName;

    /** employeeList関連プロパティ */
    private List<Employee> employeeList;
    /**
     * DEPARTMENT_IDを返します。
     *
     * @return DEPARTMENT_ID
     */
    @Id
    @GeneratedValue(generator = "generator", strategy = GenerationType.AUTO)
    @Column(name = "department_id", precision = 10, nullable = false, unique = true)
    public Integer getDepartmentId() {
        return departmentId;
    }

    /**
     * DEPARTMENT_IDを設定します。
     *
     * @param departmentId DEPARTMENT_ID
     */
    public void setDepartmentId(Integer departmentId) {
        this.departmentId = departmentId;
    }
    /**
     * DEPARTMENT_NAMEを返します。
     *
     * @return DEPARTMENT_NAME
     */
    @Column(name = "department_name", length = 20, nullable = true, unique = false)
    public String getDepartmentName() {
        return departmentName;
    }

    /**
     * DEPARTMENT_NAMEを設定します。
     *
     * @param departmentName DEPARTMENT_NAME
     */
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    /**
     * employeeListを返します。
     *
     * @param employeeList
     */
    @OneToMany(mappedBy = "department")
    public List<Employee> getEmployeeList() {
        return employeeList;
    }

    /**
     * employeeListを設定します。
     *
     * @param employeeList
     */
    public void setEmployeeList(List<Employee> employeeList) {
        this.employeeList = employeeList;
    }
}

できてるーっ!
Javaの型とDBの型はS2JDBC-Genと同じになるので、ここに対応表があるよ。
http://s2container.seasar.org/2.4/ja/s2jdbc_gen/tasks/gen_entity.html#データベースのデータ型とJavaの型の対応表

ちなみにJSON型を指定するとStringになった。

あと、テーブルはこんな感じでできてるよ。

f:id:syobochim:20151212231040p:plain

★ちなみに

gsp-dba-pluginのREADME.mdの一番下にかいてある制約を見ると、

f:id:syobochim:20151212231120p:plain

つまりPostgreSQLには制約ついてない!やったー!


PostgreSQLのこと、あまり書いてない気がするけど、大丈夫かな。。。
ああううう!ガチ勢の中、お邪魔しました!!!

お次はtksy - Qiitaさん!

★本日のコードはこちら!

github.com

*1:PostgreSQL要素少ないですごめんなさい