これは InterSystems FAQ サイトの記事です。
Java のプログラムで $List 構造のデータを扱うには、InterSystems 製品が提供する IRISList クラスを使用することが可能です。
こちらは、IRIS Native と同様に JDBCドライバの拡張機能の一部として提供しております。
Native API for Java Quick Reference(英語のみ)
こちらでは、InterSystems 製品上に $List 構造を扱うクラスメソッドを作成し、それをストアドプロシージャとして公開し Java から呼び出すサンプルをご紹介します。
【使用可能バージョン】
IRIS 2020.1 以降に同梱されている JDBC ドライババージョン 3.1.0 以降。
ただし、JDBCで使用する場合は 3.2.0以降(IRIS2021.1以降)。
<IRISインストールディレクトリ>\dev\java\lib\JDK(Ver.)\intersystems-jdbc-3.1.0.jar
【手順】
1. IRISサーバの任意のネームスペースに以下のようなクラスを用意します。
SqlProc キーワード を指定し、メソッドを SQL ストアドプロシージャとして呼び出せるようにします。
こちらのサンプルでは、^scoreDetails グローバルに Java から渡されたリスト形式の gamesList をセットしています。
※後程おまけのサンプルで使用するリスト型のプロパティ FavoriteColors も追加しています。
Class User.ListTest Extends %Persistent
{
Property Name As %String
Property FavoriteColors As list Of %String;
ClassMethod writeTest(name As %String, gamesList As %List) [ SqlProc ]
{
set ^scoreDetails(name,"gamesList") = gamesList
quit
}
}
ObjectScriptObjectScript
2. Java のコードを用意します。今回は、JDBCを使用する方法と、Native API for Java を使用する方法をご紹介します。
★JDBCでストアドプロシージャを実行するサンプル
import java.sql.*;
import java.util.*;
import com.intersystems.jdbc.*;
public class SListTestIRIS1 {
public static void main(String[] args) throws Exception {
String url = "jdbc:IRIS://127.0.0.1:1972/USER";
IRISDataSource dataSource = new IRISDataSource();
dataSource.setURL(url);
dataSource.setUser("username");
dataSource.setPassword("password");
IRISConnection connection = (IRISConnection) dataSource.getConnection();
IRISList list = new IRISList();
list.add("basketball");
list.add("tennis");
//list.set(1,"basketball"); // add, set どちらの方法でもOK
//list.set(2,"tennis");
PreparedStatement cstmt = connection.prepareStatement("{ call SQLUser.ListTest_writeTest(?, ?) }");
cstmt.setString(1, "David");
cstmt.setBytes(2,Arrays.copyOf(list.getBuffer(),list.size())); // 現時点ではIRISListをそのまま渡せないためArraysにコピー
//cstmt.setBinaryStream(2, new java.io.ByteArrayInputStream(list.getBuffer()),list.size()); // 4.3MB以上のbyte[] を取り扱うときはこちら
cstmt.execute();
cstmt.close();
return;
}
}
JavaJava
実行結果:
USER>zw ^scoreDetails ^scoreDetails("David","gamesList")=$lb("basketball","tennis")
★Native APIでクラスメソッドを呼び出すサンプル
import com.intersystems.jdbc.*;
public class SListTestIRIS2 {
public static void main(String[] args) throws Exception {
String url = "jdbc:IRIS://127.0.0.1:1972/USER";
IRISDataSource dataSource = new IRISDataSource();
dataSource.setURL(url);
dataSource.setUser("username");
dataSource.setPassword("password");
IRISConnection connection = (IRISConnection) dataSource.getConnection();
// create IRIS Native object
IRIS iris = IRIS.createIRIS(connection);
IRISList list = new IRISList();
list.add("basketball");
list.add("cricket");
//list.set(1,"basketball"); // add, set どちらの方法でもOK
//list.set(2,"tennis");
iris.classMethodVoid("User.ListTest", "writeTest", "Nicole", list);
return;
}
}
実行結果:
USER>zw ^scoreDetails ^scoreDetails("Nicole","gamesList")=$lb("basketball","cricket")
※おまけ
INSERT で文字列のリストを設定する場合、以下のような単純な方法で行うことができます。
List Of %String のプロパティは、値をカンマで区切り、二重引用符で囲んだ単純な文字列として渡すことができます。
import java.sql.*;
import com.intersystems.jdbc.*;
public class SListTestIRIS3 {
public static void main(String[] args) throws Exception {
String url = "jdbc:IRIS://127.0.0.1:1972/USER";
IRISDataSource dataSource = new IRISDataSource();
dataSource.setURL(url);
dataSource.setUser("username");
dataSource.setPassword("password");
IRISConnection connection = (IRISConnection) dataSource.getConnection();
PreparedStatement insert = connection.prepareStatement("INSERT INTO SQLUser.ListTest (name, favoritecolors) " + "VALUES (?,?)");
insert.setString(1, "InterSystems, Japan");
insert.setString(2, "\"red\",\"orange\",\"yellow\",\"green\",\"blue\",\"purple\"");
int rowsAffected = insert.executeUpdate();
return;
}
}
実行結果:
USER>d $SYSTEM.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
The command prefix is currently set to: <<nothing>>.
Enter <command>, 'q' to quit, '?' for help.
[SQL]USER>>select * from SQLUser.ListTest
1. select * from SQLUser.ListTest
ID FavoriteColors Name
1 $lb("red","orange","yellow","green","blue","purple") InterSystems, Japan
1 Rows(s) Affected
statement prepare time(s)/globals/cmds/disk: 0.0629s/40013/185744/15ms
execute time(s)/globals/cmds/disk: 0.0014s/2/816/0ms
cached query class: %sqlcq.USER.cls9
---------------------------------------------------------------------------
[SQL]USER>>