Javaやさんに優しいローコードフレームワーク、OpenXavaを試す

OpenXavaという、JPAエンティティだけ定義すればCRUDな画面を作ってくれるローコードフレームワークがあるので、試してみました。
Javaわかる人には手軽に使えてよさそう。
https://www.openxava.org/

OpenXavaプロジェクトの作成

Maven Archetypeが用意されているので、こんな感じのMavenコマンドで始めれます。

mvn archetype:generate -DarchetypeGroupId=org.openxava -DarchetypeArtifactId=openxava-archetype -DarchetypeVersion=RELEASE -DgroupId=com.yourcompany -DartifactId=invoicing -DinteractiveMode=false

しかし、Mavenコマンドを入力するのはめんどいので、IDEを使いましょう。
NetBeansだとProject from Archetypeを選ぶとArchetype指定でプロジェクトが作成できます。

そしたらSearchにxavaといれればopenxava-archetypeが出てきます。

IntelliJ IDEAの場合はCatalogにMaven Centralを指定すると、Archetypeにxavaを入力すれば候補が出てきます。

プロジェクトのファイル構成はこんな感じ

modelのYourFirstEntity.javaはこんな感じです。

@Entity @Getter @Setter
public class YourFirstEntity extends Identifiable {
    
    @Column(length=50) @Required
    String description;
    
    LocalDate date;
    
    BigDecimal amount;

}

そしてrunのxavaSample.javaはこんな感じ。

public class xavaSample {

    public static void main(String[] args) throws Exception {
        DBServer.start("xavaSample-db"); 
        AppServer.run("xavaSample"); 
    }

}

起動

プロジェクトをビルドしてこのxavaSample.javaを実行するとTomcatが起動します。
ログの最後にアクセスURLが表示されます。

アクセスするとこんな画面が。

サインインに行くとログイン画面がでます。admin / adminでログイン。ただし、enterキーではログインできないので、「サインイン」ボタンをクリックする必要があります。めんどい。

「左がわのモジュールを選べ」とでかい矢印が出てます。ウィンドウ幅が狭いと左のバーが出てないので、ウィンドウを広げましょう。

「Your first entity」を選ぶと、データ入力フォームが出るので、適当に入力して「保存」

「リスト」を選ぶとデータが入ってます。

右上のグラフボタンを選ぶとグラフが。横軸に日付を選んでいます。

カレンダーも。

詳細付データを登録してみる

注文-注文詳細なデータを登録してみます。
こんな感じ。

エンティティはこんな感じを。

まずカテゴリ。

package naoki.xavasample.xavaSample.model;

import javax.persistence.*;
import org.openxava.annotations.Required;
import lombok.*;

@Entity @Setter @Getter
public class Category {
    @Id
    long id;
    
    @Required
    String name;
}

それから注文詳細。注文に埋め込むので@Embeddableにしています。
@DescriptionsListをつけるとドロップダウンにしてくれるらしい。

package naoki.xavasample.xavaSample.model;

import javax.persistence.*;
import org.openxava.annotations.DescriptionsList;
import lombok.*;

@Embeddable @Setter @Getter
public class OrderDetail {
    
    String name;

    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @DescriptionsList
    Category category;

    long price;
}

そして注文。ここでOrderにしてしばらくハマっていた。SQLのキーワードは避けましょう。
主キーをUUIDにするためにいろいろついています。
あと、@DefaultValueCalculatorで初期値を設定してくれる。
それから、詳細部分は@ElementCollectionにして、表示項目を@ListPropertiesで指定しています。

package naoki.xavasample.xavaSample.model;

import java.time.LocalDate;
import java.util.Collection;
import javax.persistence.*;

import org.hibernate.annotations.GenericGenerator;
import org.openxava.annotations.DefaultValueCalculator;
import org.openxava.annotations.Hidden;
import org.openxava.annotations.ListProperties;
import org.openxava.annotations.Required;
import org.openxava.calculators.CurrentLocalDateCalculator;

import lombok.*;

@Entity @Setter @Getter
public class Orders {
    @Id
    @GeneratedValue(generator="system-uuid")
    @Hidden
    @GenericGenerator(name="system-uuid", strategy="uuid")
    @Column(length=32)
    String oid;
   
    @Required
    @DefaultValueCalculator(CurrentLocalDateCalculator.class)
    LocalDate orderDate;
    
    String customerName;
    
    @ElementCollection
    @ListProperties("name, price, category")
    Collection<OrderDetail> details;
}

そうすると、こういう登録画面が。

一覧からはみ出た[+]ボタンを押すとカテゴリが追加できます。
これ、category - priceの順にすると、ボタンがpriceのところにかぶってダメな感じでした。

ということでカテゴリーも選べるようになっています。

テーブルはこんな感じになっています。

ついでに、下部のテーマからBlueを選んでみます。

いい感じ。これデフォルトにすればいいのに。

データベースを変更する

MySQLPostgreSQLなど外部DBを使うときはsrc/main/webapp/META-INF/context.xmlを編集します。
こんな感じで設定がコメントで書いてあるので、必要なものを有効にします。

 <!-- HSQLDB -->       
    <Resource name="jdbc/myXavaDS" auth="Container" type="javax.sql.DataSource"
          maxTotal="20" maxIdle="5" maxWaitMillis="10000"
          username="sa" password="" 
          driverClassName="org.hsqldb.jdbc.JDBCDriver"
          url="jdbc:hsqldb:hsql://localhost:1666"/>
          
    <!-- MySQL       
    <Resource name="jdbc/myXavaDS" auth="Container" type="javax.sql.DataSource"
         maxTotal="20" maxIdle="5" maxWaitMillis="10000"
         username="root" password="" 
         driverClassName="com.mysql.cj.jdbc.Driver"
         url="jdbc:mysql://localhost:3306/myXavadb"/>       
   -->      
    
    <!-- PostgreSQL 
   <Resource name="jdbc/myXavaDS" auth="Container" type="javax.sql.DataSource"
         maxTotal="20" maxIdle="5" maxWaitMillis="10000"
         username="postgres" password=""
         driverClassName="org.postgresql.Driver" 
         url="jdbc:postgresql://localhost/myXavadb"/>
   -->

JDBCドライバはdependencyに含める必要があります。
それもpom.xmlにコメントで書いてあるので、必要なものを有効にします。

<!-- 
To access to your database uncomment the corresponding entry 
from the below dependencies. If you don't find yours, look in
internet for the maven depencency for your database and add it 
here yourself.
-->

<!-- MySQL 
<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>      
<version>8.0.32</version>
</dependency>
-->

<!-- PostgreSQL 
<dependency>
        <groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.4</version>
</dependency>
-->

あと、mainメソッドのDB起動部分はコメントアウトします。

// DBServer.start("xavaSample-db"); 
AppServer.run("xavaSample"); 

まとめ

なんかデータ管理するだけであれば結構便利。
権限管理が必要になると有償版を使うことになるけど、手元のデータを管理するくらいだと十分じゃなかろうか。