この記事について
将来的に書く予定の「JavaFX で DynamoDB Viewer作ってみた」記事の1ステップ。
結構大きな話になると思うので、少しずつ技術ポイント毎に記事を書いて、ある一定程度の要件を満たせた段階で前述まとめ記事書く予定。今回は、基本技術確認まで。
背景
業務や趣味でDynamoDBを使用している。少しのデータならAWS管理コンソールや NoSQL Workbench for DynamoDB が存在するものの、どうもしっくりこない。表示可能なデータ量少ないし、カラム幅の変更などの操作も微妙に遅い。大体痒いところに手が届かない。
調べると結構Viewer作っている人はいるものの、大体サービス起動してブラウザで見る形式。
GoogleSpreadSheetレベルに完成度が高いブラウザツールがあったらそれを使いたいが、今のところ見当たらない。なので作ってしまおうという事。
開発環境
Eclipse Neon
JavaFX Scene Builder 2.0
※著者は結構前にインストールしたのを使ってるので古いです。
要件
- スタンドアロンのツールにする。
- LinuxでもWindowsでも動くようにする
- GUIでもCUI(ファイル出力とか)でも使えるようにする
- 1つのフィールドにJSON形式などで保存されてるデータも参照したい
技術選定
GUI
要件からほぼ JavaFX 一択。ブラウザで見る形式は取りたくない。
JavaFXはJDK11からは標準装備ではなくなったけど、OpenJFX として続いている模様。何となくJava8用とJava11用ビルドの2種類が必要になりそうな気配。
何にせよ、先が無い技術というわけでもない。実際今回の様な案件にはピッタリなので需要が無くなるという気がしない。
※2021-01-21 追記
java11でも別ビルドにする必要なく動きました。こちらがその際に参考にさせて頂いたページです。
Java11でJavaFXを動かす
基本ライブラリ
JDBCがあれば使いたいが、CData社製 の様に有料のものしかなさそう。
趣味のものなのでお金使いたくない。aws-sdk-java-v2 を使う。
準備
mavenプロジェクト(pom.xml)作成
mvn archetype:generate -DgroupId=com.silverboxsoft -DartifactId=dynamodbtool -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
dynamodbtool フォルダ及び、基本フォルダが作成される。
EclipseにImport
cd dynamodbtool
mvn eclipse:eclipse
Eclipseを起動し、File => Import。Existing Project into Workspace を選び、dynamodbtool フォルダを選択。
.gitignoreファイル作成
dynamodbtool 直下に以下内容でフ.gitignore ファイル作成
target
dependency追加
公式サイト に従い、以下をpom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.15.64</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId>
</dependency>
再度コンソールで mvn eclipse:eclipse 実行して、EclipseのプロジェクトをRefresh
mvn eclipse:eclipse
※以後 pom.xml変更後は同じことする。
Queryしてみる
コードコピー
サンプルコード を真似る。
サンプルの Query.java の中身をまるっとApp.java(自動生成されたソース)にコピーし、package名、class名、リージョン指定部分だけ変える(元に戻す)。
package com.silverboxsoft;
// 中略
public class App {
// 中略
Region region = Region.AP_NORTHEAST_1;
// 後略
認証情報
AWS SDKのセットアップを終わらせておく。
もしくは Eclipse の Run => RunConfigurationで、Environmentタブにて、以下の変数と値を追加
- AWS_ACCESS_KEY_ID=your_access_key_id
- AWS_SECRET_ACCESS_KEY=your_secret_access_key
テスト実行
EclipseのRunConfigurationで、ProgramArgumentに「テーブル名 主キー名 主キー値」の形式で指定。今回は自分用の家計簿ツール で使用しているテーブルを使用。「account_balance tgt_date 20200208」を指定。
Querying account_balance
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
There were 3record(s) returned
単純な処理だが、DynamoDBへのアクセスに成功。次のステップに移る。
JavaFX準備始
Scene Builderのインストール
すいませんが、ここは検索すると良記事がたくさん出てくるのでそちらを参考にお願いします。
画面デザイン作成
Scnene Builderで、File => New From Template => Basic Application
- 左ペインのDocument => Controller の Controller classに、「com.silverboxsoft.controller.DynamoDbToolController」を指定(後でjavaクラスで作成する)。
- ButtonとTableView配置
- Button の Inspector => Code の On Action に
actLoad
を指定(後で関数で作成する) - TableView の Inspector => Code => fx:id に
tableResultList
を指定 - TableViewに TableColumn を追加して3つにする。
- TableColumn の fx:id にそれぞれ
tableColTgtDate
、tableColTargetCd
、tableColValue
を指定
src/main/resources/com/silverboxsoft/controller/javafx/DynaboDbToolController.fxml
に保存
pom.xml に起動クラス指定
ついでにエンコーディングやjavaバージョン指定
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<start-class>com.silverboxsoft.App</start-class>
</properties>
※修正後はお約束のmvn eclipse:eclipse
とEclipseのプロジェクトRefresh
メインクラス変更
コピーして作っていたDynamoDBへの接続テスト部分は削除
package com.silverboxsoft;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
// Application クラスを継承する
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
prepareControl(stage);
stage.show();
}
private void prepareControl(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("controlloer/javafx/DynamoDbToolController.fxml"));
// Templateで作成されるデザインのルートコンテナが VBoxの為
VBox newPane = (VBox) fxmlLoader.load();
Scene scene = new Scene(newPane);
stage.setTitle("DynamoDB Tool");
stage.setScene(scene);
}
}
java側コントローラークラス作成
package com.silverboxsoft.controller;
import java.net.URL;
import java.util.ResourceBundle;
import com.silverboxsoft.dao.AccountBalanceDao;
import com.silverboxsoft.model.AccountBalance;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
// Initializable を継承
public class DynamoDbToolController implements Initializable {
// 画面デザイン上のコンポーネントと結びつける
@FXML
TableView<AccountBalance> tableResultList;
@FXML
TableColumn<AccountBalance, String> tableColTgtDate;
@FXML
TableColumn<AccountBalance, String> tableColTargetCd;
@FXML
TableColumn<AccountBalance, Long> tableColValue;
@Override
public void initialize(URL location, ResourceBundle resources) {
setTableColumns();
}
// ボタンに指定したアクションと結びつける
@FXML
protected void actLoad(ActionEvent ev) {
AccountBalanceDao dao = new AccountBalanceDao();
// 今回はテストなのでベタ打ち
tableResultList.getItems().clear();
tableResultList.getItems().addAll(dao.getBalanceListAtOneDay("20200208"));
}
// カラムとデータクラスメンバの結び付け
private void setTableColumns() {
tableColTgtDate.setCellValueFactory(new PropertyValueFactory<AccountBalance, String>("tgtDate"));
tableColTargetCd.setCellValueFactory(new PropertyValueFactory<AccountBalance, String>("methodCd"));
tableColValue.setCellValueFactory(new PropertyValueFactory<AccountBalance, Long>("value"));
}
}
その他Daoやmodelクラス
今回の主目的とは違う部分なのでgithubで。
Dao
Model
各ソースの関係まとめ
- pom.xml で Application クラスを継承した起動クラス指定
- 起動クラス内で、fxmlファイルを読み込む。
- fxmlファイルで、結びつくControllerクラスを指定
- fxmlファイルで、Controllerで使用するコンポーネントのfx:idを指定して@FXMLアノテーションで結び付ける
- fxmlファイルで、ボタンのアクション関数名を指定して、Controllerの関数と@FXMLアノテーションで結びつける
変なエラーが出たら
restriction on required library 'C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar'
というエラーが出たら、EclipseでJavaFXを使おうとするとアクセス制限とでる問題の解決方法 を参考に、環境設定>Java>コンパイラー>エラー警告>「使用すべきでない制限されたAPI」の「禁止された参照(アクセス・ルール)」を「エラー」から「無視」に変更
現在の画面
今後のステップ
今はテーブルは固定カラム。今回作成するのは汎用DBツールなのでそこを動的に判断して処理する必要がある。
テーブルリスト表示や、接続先の指定なども可能にしたい。細かい読み込み指定もしたい。
参考にさせて頂いたページ
※2021-01-21 追記
Java11でJavaFXを動かす