はじめに
前回の記事では、Oracle Database で JSON データを管理する方法を確認しました。JSON のアクセス方法は、SQL ・ SODA(Simple Oracle Document Access) の2種類あります。
SODA はプログラム開発者向けに用意されている API です。SQLの知識が無くても、JSON ドキュメントを格納・取り出しが出来る特徴があります。
SODA のなかで利用する言語などによって、6種類の方法が提供されています。
- Java
- C
- Rest
- PL/SQL
- Node.js
- Python
今回は、SODA を Java のプログラムから利用するまでの手順を紹介していきます。
SODA Driver for Java と Table の関係性
と、実際の作業に入る前に、SODA で扱う抽象的な概念と、Oracle Database の Table との関係性を見て行きます。
SODA Driver for Java では、Collection と Document という2つの抽象的な概念を扱い、Oracle Database 上で JSON データをストアできます。Java のコードで見ると、次のような感じです。
// Create a collection with the name "MyJSONCollection".
// This creates a database table, also named "MyJSONCollection", to store the
// collection.
OracleCollection col = db.admin().createCollection("MyJSONCollection");
// Create a JSON document.
OracleDocument doc = db.createDocumentFromString("{ \"name\" : \"Alexander\" }");
// Insert the document into a collection.
col.insert(doc);
MyJSONCollection
という名前の Collection を作成し、{"name" , "Alexander"}
という Document を格納している Java のサンプルコードです。SQL が、ドキュメントとコレクションという概念に隠蔽されていることが分かります。
上記を実行すると、Oracle Database 上では、MyJSONCollection
という名前のTableが作成されます。実際のデータはこんな感じです。1個のDocumentが、1個のRow として、Insert されています。
Table は5個のカラムで構成されています。
- ID : コレクションで自動的に採番される ID。Primary Key となる。
- CREATED_ON : Document の作成日時
- LAST_MODIFIED : Document の更新日時
- VERSION : Document のバージョン
- JSON_DOCUMENT : JSON のデータが格納される。BLOB 型に保管される
Table に設定されている Constraint を見ると、JSON_DOCUMENT
列に JSON 用の制約が入っています。
なお、自分の環境では、SODA Driver for Java から作成した Table は、SQL 文で直接参照しようとしても、table 名が見つからないエラーが出ました。SQL Developer を使うことで、Table のデータや構造が確認できました。SQL で直接見えない場合は、他のツールを使うと参照出来るように見えます。
環境構築手順
それでは、実際に SODA Driver for Java を使って、開発用の環境を構築していきます。SODA for Java Developer's Guide に、必要な前提条件が書かれており、これを参考に作業を進めます。
https://docs.oracle.com/en/database/oracle/simple-oracle-document-access/java/adsda/soda-java-prerequisites.html#GUID-470DC8EE-087E-4196-B3FE-6A24C24C615A
この記事の開発環境は、Visual Studio Code + Maven + Remote Development です。環境に合わせて適宜読み替えてください。
実施する手順
- Remote Development 用の CentOS 7 を構築して、OpenJDK 11 と Maven を Install
- Visual Studio Code の Remote Development で接続
- SODA Driver for Java のダウンロード
- Maven プロジェクトに SODA Driver for Java 追加 (本質的には、クラスパスへ追加)
- Oracle Database のユーザに、SODA 用の権限付与
- Sample プログラム実行
CentOS 7 構築
CentOS7 上に、OpenJDK・Maven の環境を構築します。既に環境がある場合は、それを使って大丈夫です。
環境が無い場合は、次のURLを参考に適当に構築します。なお、この記事では、Open JDK 11 を インストールしています。
https://qiita.com/sugimount/items/a635473079d837b8944d
Remote Development + Java Extension Pack
構築した CentOS に遠隔から接続して開発するために、2個の拡張機能を使っています。
- Remote Development で接続
- Java Extension Pack Install
Download SODA Driver for Java
Oracle が管理している GitHub で、SODA Driver for Java が公開されています。
https://github.com/oracle/soda-for-java/releases?xd_co_f=262969594c72535bdd71591657038936
CentOS へ wget するために、URLをコピーしておきます。
Install SODA Driver in Maven Project
まずは、Maven で Project を作ります。適当な名前で mkdir します。
mkdir -p ~/java
cd ~/java
Maven Project 作成 です。oraclesoda
という名前で作成します。
mvn archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-simple \
-DarchetypeVersion=1.4 \
-DgroupId=com.example \
-DartifactId=oraclesoda \
-Dversion=1.0-SNAPSHOT \
-Dpackage=com.example
作成した Project のなかで、SODA Driver for Java を格納するためにディレクトリを作ります。
cd ~/java/oraclesoda
mkdir -p lib/repo/oraclesodadriver/jars
SODA Driver for Java を作成したディレクトリに wget でダウンロードします。
cd ~/java/oraclesoda/lib/repo/oraclesodadriver/jars
wget https://github.com/oracle/soda-for-java/releases/download/v1.1.4/orajsoda-1.1.4.jar
ダウンロードされているか確認です。
[opc@soda jars]$ pwd
/home/opc/java/oraclesoda/lib/repo/oraclesodadriver/jars
[opc@soda jars]$
[opc@soda jars]$ ls -la
total 452
drwxrwxr-x. 2 opc opc 32 Aug 23 08:07 .
drwxrwxr-x. 3 opc opc 18 Aug 23 08:00 ..
-rw-rw-r--. 1 opc opc 459867 Apr 22 10:59 orajsoda-1.1.4.jar
[opc@soda jars]$
Maven Project を作成したときに自動生成された、pom.xml の依存関係 (dependencies) の指定で、次の指定をします。
- SODA Driver for Java
- JDBC8
- javax.json
pom.xml の全文を載せます。この中で必要なのは、<dependencies>
で囲まれている部分です。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>oraclesoda</artifactId>
<version>1.0-SNAPSHOT</version>
<name>oraclesoda</name>
<description>A simple oraclesoda.</description>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>oracle.soda</groupId>
<artifactId>sodadriver</artifactId>
<version>1.4</version>
<scope>system</scope>
<systemPath>${basedir}/lib/repo/oraclesodadriver/jars/orajsoda-1.1.4.jar</systemPath>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8-production</artifactId>
<version>19.7.0.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>
dependencies で指定した、ライブラリ群を download します。Maven Project 用の Directory のなかで、target/dependency にダウンロードされます。
(余談ですが、Oracle の JDBS が Maven として公開されており、楽にダウンロードが出来るようになっています。)
https://www.oracle.com/database/technologies/maven-central-guide.html
cd ~/java/oraclesoda
mvn dependency:copy-dependencies
ダウンロードされた jar ファイル群の確認です。
[opc@soda2 oraclesoda]$ ls -la target/dependency/
total 11280
drwxrwxr-x. 2 opc opc 4096 Aug 23 12:25 .
drwxrwxr-x. 3 opc opc 24 Aug 23 12:25 ..
-rw-rw-r--. 1 opc opc 85147 Aug 23 12:25 javax.json-1.0.4.jar
-rw-rw-r--. 1 opc opc 4398602 Aug 23 12:25 ojdbc8-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 5140 Aug 23 12:25 ojdbc8-production-19.7.0.0.pom
-rw-rw-r--. 1 opc opc 156242 Aug 23 12:25 ons-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 311000 Aug 23 12:25 oraclepki-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 1663954 Aug 23 12:25 orai18n-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 210337 Aug 23 12:25 osdt_cert-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 312200 Aug 23 12:25 osdt_core-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 32168 Aug 23 12:25 simplefan-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 459867 Aug 23 12:25 sodadriver-1.4.jar
-rw-rw-r--. 1 opc opc 1684253 Aug 23 12:25 ucp-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 265130 Aug 23 12:25 xdb-19.7.0.0.jar
-rw-rw-r--. 1 opc opc 1933746 Aug 23 12:25 xmlparserv2-19.7.0.0.jar
[opc@soda2 oraclesoda]$
Oracle Database のユーザーに権限付与
Oracle Database で使うユーザーに、SODA_APP という権限を付与します。
GRANT SODA_APP TO sugi;
実行例
SQL> GRANT SODA_APP TO sugi;
Grant succeeded.
SQL>
Sample Code
ここまでの手順で、SODA Driver for Java を使えるようになりました。今回は、SODA を動かしたいだけなので、一旦テストコードは全て削除します。
rm -rf ~/java/oraclesoda/src/test/
VS Code で、SodaApp.java を言う名前でファイルを新規作成します。
Quick Start なコードを全て載せます。url
, user
, password
などは、環境に合わせて適宜変更してください。
-
MyJSONCollection
名のコレクションを作成 - 作成したコレクションに、Document を Insert
- Insert する時には、ヒント句で MONITOR を入れており、リアルタイムに実行計画などを参照可能
package com.example;
// import java.sql.Connection;
import java.sql.DriverManager;
import oracle.jdbc.OracleConnection;
import oracle.soda.rdbms.OracleRDBMSClient;
import oracle.soda.OracleDatabase;
import oracle.soda.OracleCursor;
import oracle.soda.OracleCollection;
import oracle.soda.OracleDocument;
import oracle.soda.OracleException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class SodaApp {
public static void main(String[] arg) {
// Set the JDBC connection string, using information appropriate for your Oracle
// Database instance.
// (Be sure to replace placeholders host_name, port_number, and service_name in
// the string.)
String url = "jdbc:oracle:thin:@//10.0.0.71:1521/pdb01.pubsubnet01.vcn.oraclevcn.com";
// Set properties user and password.
// (Be sure to replace placeholders user and password with appropriate string
// values.)
Properties props = new Properties();
props.setProperty("user", "sugi");
props.setProperty("password", "Sug1_Passw0rd_dayo");
OracleConnection conn = null;
try {
// Get a JDBC connection to an Oracle instance.
conn = (OracleConnection) DriverManager.getConnection(url, props);
// Enable JDBC implicit statement caching
conn.setImplicitCachingEnabled(true);
conn.setStatementCacheSize(50);
// Get an OracleRDBMSClient - starting point of SODA for Java application.
OracleRDBMSClient cl = new OracleRDBMSClient();
// Get a database.
OracleDatabase db = cl.getDatabase(conn);
// Create a collection with the name "MyJSONCollection".
// This creates a database table, also named "MyJSONCollection", to store the
// collection.
OracleCollection col = db.admin().createCollection("MyJSONCollection");
// Create a JSON document.
OracleDocument doc = db.createDocumentFromString("{ \"name\" : \"Alexander\" }");
// Insert the document into a collection.
// col.insert(doc);
Map<String, String> hint = new HashMap<String, String>();
hint.put("hint", "MONITOR");
col.insertAndGet(doc, hint);
// Find all documents in the collection.
OracleCursor c = null;
try {
c = col.find().getCursor();
OracleDocument resultDoc;
while (c.hasNext()) {
// Get the next document.
resultDoc = c.next();
// Print document components
System.out.println("Key: " + resultDoc.getKey());
System.out.println("Content: " + resultDoc.getContentAsString());
System.out.println("Version: " + resultDoc.getVersion());
System.out.println("Last modified: " + resultDoc.getLastModified());
System.out.println("Created on: " + resultDoc.getCreatedOn());
System.out.println("Media: " + resultDoc.getMediaType());
System.out.println("\n");
}
} finally {
// IMPORTANT: YOU MUST CLOSE THE CURSOR TO RELEASE RESOURCES.
if (c != null)
c.close();
}
// Drop the collection, deleting the table underlying it and the collection
// metadata.
if (arg.length > 0 && arg[0].equals("drop")) {
col.admin().drop();
System.out.println("\nCollection dropped");
}
}
// SODA for Java throws a checked OracleException
catch (OracleException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
}
}
VS Code 上で、Run を押してプログラムを実行します。
実行例
[opc@soda2 java]$ cd /home/opc/java ; /usr/lib/jvm/java-11-openjdk-11.0.8.10-0.el7_8.x86_64/bin/java -Dfile.encoding=UTF-8 @/tmp/cp_axz1vz6oaf2zjr4qikomut4ns.argfile com.example.SodaApp
Key: B4B652D1424A43BCAEEBA112B2CB80FF
Content: { "name" : "Alexander" }
Version: 75611B2924EB4168510D33D13DA7D441E65DCB3DEA5F1629A8407161040D7E75
Last modified: 2020-08-23T09:54:42.360941000Z
Created on: 2020-08-23T09:54:42.360941000Z
Media: application/json
Monitor ヒント句を Java で指定しているので、Enterprise Manager で SODA Driver が実行する SQL テキストをそのまま確認できます。
SODA の裏側では、Insert 文が投げられていて、MyJSONCollection
テーブルにデータが格納されています。
insert /*+ MONITOR */ into "SUGI"."MyJSONCollection" ("ID","JSON_DOCUMENT","LAST_MODIFIED","CREATED_ON","VERSION") values (:1 ,:2 ,sys_extract_utc(SYSTIMESTAMP),sys_extract_utc(SYSTIMESTAMP),:3 ) returning "LAST_MODIFIED" into :4
API Refference
SODA Driver for Java の他のAPIが気になるときは、このURLを確認するとよいでしょう。
JavaDoc
http://oracle.github.io/soda-for-java/
Using SODA for Java
https://docs.oracle.com/en/database/oracle/simple-oracle-document-access/java/adsda/using-soda-java.html#GUID-4A87EFC6-C090-47C3-B025-035DC9F1BFE0
参考URL
JSON開発者ガイド
https://docs.oracle.com/cd/F19136_01/adjsn/index.html
SODA Document
https://docs.oracle.com/en/database/oracle/simple-oracle-document-access/index.html
SODAについて
https://www.oracle.com/database/technologies/appdev/json.html
SODAについて
https://orablogs-jp.blogspot.com/2018/10/node-oracledb-30-introduces-soda.html
SODA GitHub
https://github.com/oracle/soda-for-java/
SODA Release Note
https://github.com/oracle/soda-for-java/releases
SODA Java Doc
http://oracle.github.io/soda-for-java/
Oracle JDBC drivers on Maven Central
https://medium.com/oracledevs/all-in-and-new-groupids-oracle-jdbc-drivers-on-maven-central-a76d545954c6
Developers Guide For Oracle JDBC 19.7.0.0 on Maven Central
https://www.oracle.com/database/technologies/maven-central-guide.html