Red Hat Data Virtualization 複数 DB の結合

Kenta Kosugi
14 min readJan 28, 2020

--

Data Virtualization を実現するには以下 3 種類の方法があります。

  1. Data Virtualization Operator を使用
  2. Fuse Online からデザイン
  3. SpringBoot で実装

今回のお話は SpringBoot を使って実装する方法をもっと具体的にしたものです。

0. 仮想化対象のデータベース

customer テーブル(Postgresql)

customer

address テーブル(MySQL)

address

customer テーブルに address テーブルを左結合します。その際 CUSTOMER_ID を使用します。このようなとき、Teiid SpringBoot ではどのように実装するのかまとめます。

上記にデータベースのイメージをあげているので以下のコマンドで起動すれば仮想化対象のデータベースは準備完了です。

$ docker run -d --name customerdb --rm -p 5432:5432 kkosugi/customerdb:v1
$ docker run -d --name addressdb --rm -p 3306:3306 kkosugi/addressdb:v1

1. Spring Initializr でプロジェクトの雛形を生成

2.1.12 (2020/1月時点で 2.1 台の最後のリリース) を選択して Maven プロジェクトを作成します。

プロジェクトが作成されたらダウンロードして IDE が使用するワークスペースの下にコピーします。

Spring Initializr を使用することのメリットは Maven がインストールされていない環境でも Maven が動作できるよう mvnw を作ってくれるところにあります。

2. pom.xml の編集

IDE にプロジェクトをインポートして、pom.xml に幾つかの変更を加えます。

  1. properties
  2. dependencyManagement
  3. dependency

properties

version.teiid.spring-boot で teiid のバージョンを追加します。今回は 2020/1 時点で最新の 1.3.0 を指定。

<properties>
<java.version>11</java.version>
<version.teiid.spring-boot>1.3.0</version.teiid.spring-boot>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

dependencyMangement

pom.xml の後方にまるっとコピー。Maven の settings.xml にコピーする方法もありますが、全プロジェクトが参照できてしまうため Teiid SpringBoot の pom.xml に記載すれば問題ないと思います。

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-spring-boot-starter-parent</artifactId>
<version>${version.teiid.spring-boot}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

dependency

データベース仮想化対象への接続に使用する JDBC(例は Postgresql と MySQL)と、teiid-spring-boot-starter を指定します。spring-odata は OData を使用しない場合は不要です。ライブラリは Maven Central Repository のもので問題ありません。

<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.teiid</groupId>
<artifactId>spring-odata</artifactId>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

3. ソースコードの追加

まず、main 文は SpringBoot Initializr が作ってくれるので省略。Red Hat のドキュメントを参照すると mvn archetype generate で作っちゃうので main 文も自分で書かなきゃいけないです。そしてこの資料はタイポがあって単純にコピー&ペーストではうまく機能しないので気を付けてください。

おまじないのように以下のコードを追加。

DataSources.java

これは何しているかというと SpringBoot のコンフィグファイルから値を読み取って、JDBC の DataSource を作っているだけです。prefix = “spring.datasource.customerds” の部分とメソッド名 customerds() の太字は合わせてください。

spring.datasource.xxxx は application.yml / application.properties で登場します。

4. SpringBoot コンフィグファイル

今回は application.yml でご紹介。

prefix に出てきた spring.datasoruce.customerds で Postgresql への接続を定義、addressds で MySQL への接続を定義しています。

teiid.jdbc-enabling を true にしないと Teiid SpringBoot に JDBC 接続できなくなるので注意です。SpringBoot 内でしか Postgresql や MySQL へのデータソースを使えなくなる Embedded モードになるので、この場合更なるコーディングが必要となります。

5. VDB ファイル

VDB ファイルは必須ではないのですが、今回のように異なる RDBMS にあるテーブル同士を結合したいなんて時は必要になります。

-- This is simple VDB that connects to a single PostgreSQL database and exposes it
-- as a Virtual Database.

-- create database
CREATE DATABASE sampledb OPTIONS (ANNOTATION 'Customer VDB');
USE DATABASE sampledb;

-- create translators and connections to source
CREATE FOREIGN DATA WRAPPER postgresql;
CREATE FOREIGN DATA WRAPPER mysql;

CREATE SERVER customerds TYPE 'NONE' FOREIGN DATA WRAPPER postgresql OPTIONS ("jndi-name" 'customerds');
CREATE SERVER addressds TYPE 'NONE' FOREIGN DATA WRAPPER mysql OPTIONS ("jndi-name" 'addressds');

-- create schema, then import the metadata from the PostgreSQL database
CREATE SCHEMA a SERVER customerds;
CREATE SCHEMA b SERVER addressds;
CREATE VIRTUAL SCHEMA portfolio;

SET SCHEMA a;
IMPORT FOREIGN SCHEMA public FROM SERVER customerds INTO a OPTIONS("importer.useFullSchemaName" 'true');

SET SCHEMA b;
IMPORT FOREIGN SCHEMA address FROM SERVER addressds INTO b OPTIONS("importer.useFullSchemaName" 'true');

SET SCHEMA portfolio;

CREATE VIEW CustomerZip(id long PRIMARY KEY, name string, ssn string, zip string) AS
SELECT b.ID as id, b.NAME as name, b.SSN as ssn, c.ZIP as zip
FROM a.public.customer b LEFT OUTER JOIN b.address.ADDRESS c
ON b.ID = c.CUSTOMER_ID;

Teiid SpringBoot の起動

$ ./mvnw clean package spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< com.redhat.integration:multi-rdbms >-----------------
[INFO] Building multi-rdbms 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ multi-rdbms ---
[INFO] Deleting /Users/kkosugi/IdeaProjects/data-virtualization/multi-rdbms/target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ multi-rdbms ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ multi-rdbms ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/kkosugi/IdeaProjects/data-virtualization/multi-rdbms/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ multi-rdbms ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/kkosugi/IdeaProjects/data-virtualization/multi-rdbms/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ multi-rdbms ---
[INFO] Changes detected - recompiling the module!
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ multi-rdbms ---
〜略〜
起動画面

今回 VDB として sampledb を作成し portfolio というスキーマを定義していますが、その通りにログが出力されていることがわかります。

TEIID50029 VDB sampledb.1 model "portfolio" metadata is currently being loaded. Start Time: 2020/01/28 12:25

JDBC クライアントから接続

DataGrip などの JDBC クライアントを使用して Teiid SpringBoot に JDBC アクセスしてみましょう。JDBC の接続文字列は以下のとおりです。

jdbc:teiid:sampledb@mm://localhost:31000
DataGrip から接続

OData へ接続

ブラウザから以下の URL を実行して動作を確認します。

  1. http://localhost:8080/odata
  2. http://localhost:8080/odata/portfolio/CustomerZip
  3. http://localhost:8080/odata/portfolio/CustomerZip?$format=json
  4. http://localhost:8080/odata/portfolio/CustomerZip(12)?$format=json

参考までに 4 は以下のような表示になります。

クリーンアップ

Teiid SpringBoot の停止

control + c で停止

仮想化対象のデータベースの停止

$ docker stop customerdb
$ docker stop addressdb

--

--

Kenta Kosugi
Kenta Kosugi

Written by Kenta Kosugi

Javaアプリケーションサーバーの開発からCORBA製品のサポート、QA、証券外務員(第一種免許)、ストレージ屋、アーキテクト、SaaS屋と一貫性のない道を歩んでいます。Red Hatに復帰しました。

No responses yet