記事
· 2021年6月3日 5m read

Javaから配列のような複数項目のデータを渡す方法

これは 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
}

}


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;
    }
}

実行結果:

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>>
ディスカッション (0)0
続けるにはログインするか新規登録を行ってください