0
2

More than 3 years have passed since last update.

DynamoDBの情報を読み込んでJavaFXで表示してみる

Last updated at Posted at 2021-01-16

この記事について

将来的に書く予定の「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 ファイル作成

.gitignore
target

dependency追加

公式サイト に従い、以下をpom.xml

pom.xmlのprojectブロック配下に追加
  <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>
pom.xmlのdependenciesブロック配下に追加
    <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名、リージョン指定部分だけ変える(元に戻す)。

App.java
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 にそれぞれtableColTgtDatetableColTargetCdtableColValueを指定

src/main/resources/com/silverboxsoft/controller/javafx/DynaboDbToolController.fxml に保存

pom.xml に起動クラス指定

ついでにエンコーディングやjavaバージョン指定

pom.xml
  <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への接続テスト部分は削除

App.java
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側コントローラークラス作成

DynamoDbToolController.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」の「禁止された参照(アクセス・ルール)」を「エラー」から「無視」に変更

現在の画面

image.png

今後のステップ

今はテーブルは固定カラム。今回作成するのは汎用DBツールなのでそこを動的に判断して処理する必要がある。
テーブルリスト表示や、接続先の指定なども可能にしたい。細かい読み込み指定もしたい。

参考にさせて頂いたページ

※2021-01-21 追記
Java11でJavaFXを動かす

0
2
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
0
2