2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【VBA】Hibernate Toolsで生成したEntityクラスのプリミティブ型を対応する参照型に変換するツールを作ってみた

Last updated at Posted at 2020-06-14

テーブル定義やVIEW定義をもとに対応するEntityクラスを瞬時に作成できるHibernate Tools。
とても便利なのですが、デフォルトでは数値型はプリミティブ型で作成されてしまいます。
DBの値にnullが入りうる場合、これだとNG。
対応する参照型(プリミティブ型と違ってnullも許容)に変換できる設定がないか探してみるも出てこない、、
これなら作ってしまったほうが速い!というわけで、上を実現するツールを作ってみました。

環境

  • OS:Windows10
  • VBA:7.1
  • IDE:Eclipse2020-03
  • Java:8
  • MySQL:5.7
  • Hibernate ORM:5.4
  • Spring Boot:2.3.1

Entityクラスの作成

Hibernate ToolsでのEntityクラスの作成方法は

に詳しく記載されているため、本記事では割愛します。

データ型の対応表

MySQLのデータ型(以下、MySQL)、Hibernate Toolsで出力されるJavaのデータ型(以下、Hibernate Tools)、対応する参照型は以下の通りです。
(実際にHibernate Toolsを動かしてみての出力結果になります。)

MySQL HibernateTools(Java) 対応する参照型(Java)
INTEGER int Integer
INT int Integer
TINYINT byte Byte
SMALLINT short Short
MEDIUMINT int Integer
BIGINT BigInteger -
DECIMAL BigDecimal -
NUMERIC BigDecimal -
FLOAT float Float
DOUBLE double Double
BIT byte Byte

BigInteger, BigDecimalは参照型なので、変換不要ということで、対応する参照型は書いていません。
それにしても、INTEGERはInteger, BIGINTはlongで出力されるんじゃないんですね、、

コード

上記をもとに、VBAのコードを作成しました。
(数値型以外の変換も少し入ってます。)

Sub macro_for_entity_class_java()

    Dim filePath As String ' ファイルパス取得用
    Dim javaFile As String ' Javaファイル取得用
    
    Dim FSO As Object ' ファイル処理用
    
    Dim replaceContent As String  ' 文字列変換用
    
    Dim reg As Object '正規表現オブジェクト用(@JoinColumnの置換に使用)
    Set reg = CreateObject("VBScript.RegExp")  '正規表現オブジェクト用の設定
    
    ' Excelファイルのパスを取得
    filePath = ThisWorkbook.Path
    ' Excelファイルと同ファイル内にあるJavaファイルを取得
    javaFile = Dir(filePath & "\*.java")
    
    ' Javaファイルを順に開いて処理を実行
    Do While javaFile <> ""
    
        ' Javaファイルを開いて内容を読み込む
        Set FSO = CreateObject("Scripting.FileSystemObject")
        With FSO.GetFile(filePath & "\" & javaFile).OpenAsTextStream
            replaceContent = .ReadAll
            .Close
        End With
        
        ' boolean → Boolean
        replaceContent = replace(replaceContent, "private boolean", "private Boolean")
        replaceContent = replace(replaceContent, "public boolean get", "public Boolean get")
        replaceContent = replace(replaceContent, "(boolean", "(Boolean")
        
        ' byte → Byte
        replaceContent = replace(replaceContent, "private byte", "private Byte")
        replaceContent = replace(replaceContent, "public byte get", "public Byte get")
        replaceContent = replace(replaceContent, "(byte", "(Byte")
        
        ' short → Short
        replaceContent = replace(replaceContent, "private short", "private Short")
        replaceContent = replace(replaceContent, "public short get", "public Short get")
        replaceContent = replace(replaceContent, "(short", "(Short")
        
        ' int → Integer
        replaceContent = replace(replaceContent, "private int", "private Integer")
        replaceContent = replace(replaceContent, "public int get", "public Integer get")
        replaceContent = replace(replaceContent, "(int", "(Integer")
        
        ' long → Long
        replaceContent = replace(replaceContent, "private long", "private Long")
        replaceContent = replace(replaceContent, "public long get", "public Long get")
        replaceContent = replace(replaceContent, "(long", "(Long")
        
        ' float → Float
        replaceContent = replace(replaceContent, "private float", "private Float")
        replaceContent = replace(replaceContent, "public float get", "public Float get")
        replaceContent = replace(replaceContent, "(float", "(Float")
        
        ' double → Double
        replaceContent = replace(replaceContent, "private double", "private Double")
        replaceContent = replace(replaceContent, "public double get", "public Double get")
        replaceContent = replace(replaceContent, "(double", "(Double")
        
        ' Object → String(対JSON型;PK用のクラスは除く)
        If InStr(javaFile, "PK.java") = 0 Then
            replaceContent = replace(replaceContent, "private Object", "private String")
            replaceContent = replace(replaceContent, "public Object get", "public String get")
            replaceContent = replace(replaceContent, "(Object", "(String")
        End If
        
        ' @JoinColumnに「insertable = false, updatable = false」を追加
        reg.Pattern = "(.+?)@JoinColumn\((.+?)\)"
        reg.IgnoreCase = False
        reg.Global = True
        replaceContent = reg.replace(replaceContent, "$1@JoinColumn($2, insertable = false, updatable = false)")
        
        ' もとのファイルを削除して、置換後の内容を記述したファイルを出力する
        FSO.GetFile(filePath & "\" & javaFile).Delete
        FSO.CreateTextFile (filePath & "\" & javaFile)
        With FSO.GetFile(filePath & "\" & javaFile).OpenAsTextStream(8)
            .Write replaceContent
            .Close
        End With
        
        ' 次のJavaファイルを取得
        javaFile = Dir
        
    Loop
    
End Sub

補足事項

  • 変換するJavaファイルはマクロを記述したExcelファイルと同階層に置いてください。
  • 変換処理のところ、int → Integer, long → Longだけでいいのでは?と思われるかもしれませんが、introductionやlongitudeといった変数名が出てきた場合に変換されてしまうため、それを防ぐために上記のような書き方にしています。
  • JSON型はString型として取得後、Javaオブジェクトに変換してあげる必要があります。以下のいずれかのライブラリを使って変換すればOK!

    ①Jackson:【参考】Jackson使い方メモ | Qiita

    ②JSONIC:【参考】【Java】JSONの基本とJSONICを使用してJSONの変換をする方法 | TASK NOTES
  • 本ツールをGitHubに公開しました。よろしければご使用ください!

更新履歴

  • 2020/06/17:データ型の対応表を追加、一部内容を修正
  • 2020/06/19:JSON → Javaオブジェクトへの変換方法を追記、今後の課題を削除
  • 2020/07/05:JPAの「Repeated column in mapping for entity」エラーに対応する処理を追加, GitHubのリポジトリを追記

参考

■VBA

■MySQL

■Java

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?