Java 同期論理は Mobile Link や共通 Java クラスと連動し、Mobile Link サーバを使用したアプリケーションの配備に柔軟性を提供します。次の項では、単純な例を使用して、この広範囲な機能について説明します。
この項では、Java 同期論理の実例を挙げて説明します。このクラスを使用したり独自のクラスを作成したりする前に、次のチェックリストを使用してすべてを満たしているかどうかを確認してから、クラスをコンパイルしてください。
擬似コードなどを使用する機能の計画。
データベース・テーブルとカラムのマッピングの作成。
Mobile Link システム・テーブルで、Java 同期メソッドの言語タイプとロケーションを指定していることを確認して、Java 同期用の統合データベースを設定。
Java 同期論理の設定を参照してください。
Java クラスの実行中に呼び出される関連 Java クラスのリストの作成。
Mobile Link サーバのクラスパスに含まれるロケーションに Java クラスを格納。
この例の Java 同期論理は、例の処理に必要な機能を指定する関連 Java ファイルとクラスを指しています。この例は、クラス CustEmpScripts の作成方法を示します。また、接続用同期コンテキストの設定方法も示します。最後に、次の用途を持つ Java メソッドを提供します。
Mobile Link ユーザを認証する。
各データベース・テーブル用のカーソルを使用して、ダウンロード操作とアップロード操作を実行する。
同期対象となるテーブルは emp と cust です。emp テーブルには、3 つのカラム emp_id、emp_name、manager があります。cust テーブルには、cust_id、cust_name、emp_id という 3 つのカラムがあります。各テーブルのすべてのカラムが同期されます。統合データベースからリモート・データベースへのマッピングにより、テーブル名とカラム名はどちらのデータベースでも同じです。さらに、監査テーブルが統合データベースに追加されます。
この例で使用するファイルは Samples\MobiLink\JavaAuthentication ディレクトリにあります。
次のコードは Java 同期論理を設定します。import 文は、Java 仮想マシンに対して、必要なファイルのロケーションを指定します。public class 文はクラスを宣言します。
// Use a package when you create your own script. import ianywhere.ml.script.InOutInteger; import ianywhere.ml.script.DBConnectionContext; import ianywhere.ml.script.ServerContext; import java.sql.*; public class CustEmpScripts { // Context for this synchronization connection. DBConnectionContext _conn_context; // Same connection MobiLink uses for sync. // Do not commit or close this. Connection _sync_connection; Connection _audit_connection; //Get a user id given the user name. On audit connection. PreparedStatement _get_user_id_pstmt; // Add record of user logins added. On audit connection. PreparedStatement _insert_login_pstmt; // Prepared statement to add a record to the audit table. // On audit connection. PreparedStatement _insert_audit_pstmt; // ... } |
CustEmpScripts コンストラクタは、authenticateUser メソッドの準備文をすべて設定します。また、メンバ・データも設定します。
public CustEmpScripts(DBConnectionContext cc) throws SQLException { try { _conn_context = cc; _sync_connection = _conn_context.getConnection(); ServerContext serv_context = _conn_context.getServerContext(); _audit_connection = serv_context.makeConnection(); // Get the prepared statements ready. _get_user_id_pstmt = _audit_connection.prepareStatement( "select user_id from ml_user where name = ?" ); _insert_login_pstmt = _audit_connection.prepareStatement( "INSERT INTO login_added(ml_user, add_time) " + "VALUES (?, { fn CONVERT({ fn NOW() }, SQL_VARCHAR) })" ); _insert_audit_pstmt = _audit_connection.prepareStatement( "INSERT INTO login_audit(ml_user_id, audit_time, audit_action) " + "VALUES (?, { fn CONVERT({ fn NOW() }, SQL_VARCHAR) }, ?)" ); } catch(SQLException e) { freeJDBCResources(); throw e; } catch(Error e) { freeJDBCResources(); throw e; } } |
finalize メソッドは、end_connection が呼び出されなければ JDBC リソースをクリーンアップします。freeJDBCResources メソッドを呼び出し、割り付けられたメモリを解放して、監査接続を終了します。
protected void finalize() throws SQLException, Throwable { super.finalize(); freeJDBCResources(); } private void freeJDBCResources() throws SQLException { if (_get_user_id_pstmt != null) { _get_user_id_pstmt.close(); } if (_insert_login_pstmt != null) { _insert_login_pstmt.close(); } if (_insert_audit_pstmt != null) { _insert_audit_pstmt.close(); } if (_audit_connection != null) { _audit_connection.close(); } _conn_context = null; _sync_connection = null; _audit_connection = null; _get_user_id_pstmt = null; _insert_login_pstmt = null; _insert_audit_pstmt = null; } |
endConnection メソッドは、不要になった時点でリソースをクリーンアップします。
public void endConnection() throws SQLException { freeJDBCResources(); } |
次の authenticateUser メソッドは、すべてのユーザ・ログインを承認し、データベース・テーブルにユーザ情報のログを取ります。ユーザが ml_user テーブルにない場合は、そのログが login_added に書き込まれます。ユーザ ID が ml_user 内で見つかると、そのログが login_audit に書き込まれます。実際のシステムでは user_password を無視することはありませんが、この例では単純にするためにすべてのユーザを承認しています。データベース操作のいずれかが失敗して例外が発生すると、endConnection メソッドは SQLException を発行します。
public void authenticateUser( InOutInteger authentication_status, String user_name) throws SQLException { boolean new_user; int user_id; // Get ml_user id. _get_user_id_pstmt.setString(1, user_name); ResultSet user_id_rs = _get_user_id_pstmt.executeQuery(); new_user = !user_id_rs.next(); if (!new_user) { user_id = user_id_rs.getInt(1); } else { user_id = 0; } user_id_rs.close(); user_id_rs = null; // In this tutorial always allow the login. authentication_status.setValue(1000); if (new_user) { _insert_login_pstmt.setString(1, user_name); _insert_login_pstmt.executeUpdate(); java.lang.System.out.println("user: " + user_name + " added. "); } else { _insert_audit_pstmt.setInt(1, user_id); _insert_audit_pstmt.setString(2, "LOGIN ALLOWED"); _insert_audit_pstmt.executeUpdate(); } _audit_connection.commit(); return; } |
次のメソッドは、SQL コードを使用して、データベース・テーブル上でカーソルとして動作します。これらはカーソル・スクリプトであるため、SQL 文字列を返します。
public static String empUploadInsertStmt() { return("INSERT INTO emp(emp_id, emp_name) VALUES(?, ?)"); } public static String empUploadDeleteStmt() { return("DELETE FROM emp WHERE emp_id = ?"); } public static String empUploadUpdateStmt() { return("UPDATE emp SET emp_name = ? WHERE emp_id = ?"); } public static String empDownloadCursor() { return("SELECT emp_id, emp_name FROM emp"); } public static String custUploadInsertStmt() { return("INSERT INTO cust(cust_id, emp_id, cust_name) VALUES (?, ?, ?)"); } public static String custUploadDeleteStmt() { return("DELETE FROM cust WHERE cust_id = ?"); } public static String custUploadUpdateStmt() { return("UPDATE cust SET emp_id = ?, cust_name = ? WHERE cust_id = ?"); } public static String custDownloadCursor() { return("SELECT cust_id, emp_id, cust_name FROM cust"); } |
次のコマンドを使用して、コードをコンパイルします。
javac -cp %sqlany11%\java\mlscript.jar CustEmpScripts.java |
クラスパスの CustEmpScripts.class のロケーションを使用して Mobile Link サーバを実行します。次に、コマンド・ラインの一部を示します。
mlsrv11 ... -sl java (-cp <class_location>) |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |