发布新帖

查找

文章
· 六月 3, 2021 阅读大约需 5 分钟

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
登录或注册以继续
问题
· 六月 2, 2021

Query SearchTable Definitions?

I've poked through the class documentation and globals and I can't seem to find what I'm looking for, namely a mechanism that will give me the PropName key and value for each of the Items in an EnsLib.HL7.SearchTable definition. Is there some sort of query that will turn the list of Items in the XData SearchSpec section into a key/value pair of some sort?

For example:

<Items>
<Item DocType=""  PropName="MSHTypeName" Unselective="true">{1:9.1}_"_"_{1:9.2}</Item>
<Item DocType=""  PropName="MSHControlID" PropType='String:CaseSensitive' >{1:10}</Item>
<Item DocType=""  PropName="PatientID"   >[PID:2.1]</Item>
<Item DocType=""  PropName="PatientID"   >[PID:3().1]</Item>
<Item DocType=""  PropName="PatientID"   >[PID:4().1]</Item>
<Item DocType=""  PropName="PatientName" >[PID:5()]</Item>
<Item DocType=""  PropName="PatientAcct" >[PID:18.1]</Item>
</Items>

Becomes:

tSearch.MSHTypeName = ""{1:9.1}_"_"_{1:9.2}""

and, say,

 tSearch.PatientID = $LB("[PID:2.1],[PID:3().1],[PID:4().1]")

etc. ...

JSON would be fine, too laugh

1 Comment
讨论 (1)1
登录或注册以继续
问题
· 六月 1, 2021

Storing a %DynamicObject

I've been tasked with an interface that needs to supply some additional metadata for the indexing of HL7v2 messages. After toying with a couple of ideas, I thought that it would be useful to subclass EnsLib.HL7.Message, add a %DynamicObject property, and store the metadata in it (it ends up getting sent to the target in JSON form anyway).

And, well, it seems to work just fine ... so far.

I seem to remember that %DynamicObjects are not persistent, and for that reason not something you would normally stuff into a database. I was a little surprised when things worked as I had hoped. With ZWRITE, the literal name of the property doesn't show up in the list of attributes, but it does show with an i% prefix under swizzled references. It also shows up, along with assigned contents, in an SQL query of the projected table. I can modify it in a DTL and the values seem to persist.

I just have this odd feeling that what I'm doing is NOT OK. Can someone confirm one way or another?

4 Comments
讨论 (4)2
登录或注册以继续
问题
· 六月 1, 2021

Mirroring Ensemble service information

I have some system with heavy production. There are about 500GB of journals daily. And I'm looking at the ways, how to decrease the amount of data that appeared there.

I found no way, on how to split have the journal separately for mirroring databases and for others. So, I'm thinking about moving some of the globals to CACHETEMP. So, they will disappear from journals. So, thinking about Ens.* globals, I have about 30% of data in journals just for such data. Which production data can be safely moved to CACHETEMP, with no issues for mirroring?

Or, maybe you have some other suggestions, how to focus journaling more on important data.

6 Comments
讨论 (6)1
登录或注册以继续
问题
· 五月 27, 2021

Can OAuth client configurations be exported/copied from one instance to another?

Hi all,

I'm performing a migration of some services from one instance to another, and I noticed that the technique defined within the InterSystems Server Migration Guide does not include OAuth client configurations. The recommended technique is to use the ##class(Security.System).ExportAll() and ##class(Security.System).ImportAll() methods.

Is there a way to migrate OAuth client configurations, or do those have to be re-created manually?

5 Comments
讨论 (5)2
登录或注册以继续