DBLINKを使用した Oracle Database で、DBLINK元と先のデータを取得して表示するJavaコードのサンプル

DBLINKを使用した Oracle Database で DBLINK元と先のデータを取得して表示するJavaコードのサンプルです。
某チャットの某質問で「ソース(情報源)はありますか？」と聞かれて「ぐぬぬ。」となったので、書いてみますた。彡(ﾟ)(ﾟ)

# 1. 環境と構成

下記の構成で検証してみました。

> Java → (JDBC) → User_A → (DBLINK) → User_B

環境は Virtualbox の下記環境を使ってます。初めから色々入ってて、セットアップもラクなんで。彡(ﾟ)(ﾟ)

> OTN の VirtualBoxイメージ で Oracle DB 19c環境 を 楽々構築
> https://qiita.com/ora_gonsuke777/items/b41f37637e59319796b4


# 2. User_A の作成とデータ挿入

まずは User_A を作成して、データを挿入します。

```sql
export ORACLE_HOME=/u01/app/oracle/product/version/db_1
export PATH=${PATH}:${ORACLE_HOME}/bin

sqlplus /nolog

CONNECT SYS/oracle@ORCL AS SYSDBA

CREATE USER USER_A IDENTIFIED BY USER_A
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;

GRANT CREATE SESSION TO USER_A;
GRANT CREATE TABLE TO USER_A;
ALTER USER USER_A QUOTA UNLIMITED ON USERS;

CONNECT USER_A/xxxxxxxx@orcl;

CREATE TABLE TBL_A(
  COL1 NUMBER
);
INSERT INTO TBL_A VALUES(100);
COMMIT;


Connected.

User created.

Grant succeeded.

Grant succeeded.

User altered.

Connected.

Table created.

1 row created.

Commit complete.
```

# 3. User_B の作成とデータ挿入

続いて User_B を作成して、データを挿入します。やる事は User_A と一緒彡(ﾟ)(ﾟ)

```sql
export ORACLE_HOME=/u01/app/oracle/product/version/db_1
export PATH=${PATH}:${ORACLE_HOME}/bin

sqlplus /nolog

CONNECT SYS/oracle@ORCL AS SYSDBA

CREATE USER USER_B IDENTIFIED BY USER_B
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;

GRANT CREATE SESSION TO USER_B;
GRANT CREATE TABLE TO USER_B;
ALTER USER USER_B QUOTA UNLIMITED ON USERS;

CONNECT USER_B/xxxxxxxx@orcl;

CREATE TABLE TBL_B(
  COL1 NUMBER
);
INSERT INTO TBL_B VALUES(200);
COMMIT;


Connected.

User created.

Grant succeeded.

Grant succeeded.

User altered.

Connected.

Table created.

1 row created.

Commit complete.
```

# 4. DBLINK作成と動作確認

User_A に DBLINK を作成して、動作確認をします。User_B に作成した TBL_B は、DBLINK経由でしか参照できないことが確認できます。

```sql

export ORACLE_HOME=/u01/app/oracle/product/version/db_1
export PATH=${PATH}:${ORACLE_HOME}/bin

sqlplus /nolog

CONNECT SYS/oracle@ORCL AS SYSDBA

GRANT CREATE DATABASE LINK TO USER_A;

CONNECT USER_A/xxxxxxxx@orcl;

CREATE DATABASE LINK DBL_USER_B
CONNECT TO USER_B IDENTIFIED BY xxxxxxxx
USING 'ORCL';

SELECT * FROM TBL_A;

SELECT * FROM TBL_B;

SELECT * FROM USER_B.TBL_B;

SELECT * FROM TBL_B@DBL_USER_B;

Connected.

Grant succeeded.

Connected.

Database link created.

      COL1
----------
       100

              *
ERROR at line 1:
ORA-00942: table or view does not exist

                     *
ERROR at line 1:
ORA-00942: table or view does not exist

      COL1
----------
       200
```


# 5. Javaコードのサンプル

User_A で接続して、TBL_A と TBL_B(DBLINK経由) をそれぞれ SELECT して表示するサンプルです。

```java
import java.sql.*;

public class GetDblinkData {
    public static void main(String[] args) {
        final String path = "jdbc:oracle:thin:@localhost:1521/orcl";
        final String id = "USER_A";  //ID
        final String pw = "xxxxxxxx";  //password

        try (
            Connection conn  = DriverManager.getConnection(path, id, pw);
            Statement  stmt  = conn.createStatement();
            ResultSet  rs    = stmt.executeQuery("SELECT COL1 FROM TBL_A");
            Statement  stmt2 = conn.createStatement();
            ResultSet  rs2   = stmt2.executeQuery("SELECT COL1 FROM TBL_B@DBL_USER_B");
        ) {
            while (rs.next()) {
                int i = rs.getInt("COL1");
                System.out.println("TBL_A COL1 => " + i);
            }
            while (rs2.next()) {
                int j = rs2.getInt("COL1");
                System.out.println("TBL_B COL1 => " + j);
            }
        } catch(SQLException ex) {
            ex.printStackTrace();  //Error
        }
    }
}
```


# 5. コンパイルと実行

さて、ようやくコンパイルと実行。下記コマンドを実行すると……彡(ﾟ)(ﾟ)

```java
javac GetDblinkData.java

java -classpath /u01/app/oracle/product/version/db_1/jdbc/lib/ojdbc8.jar:. GetDblinkData

TBL_A COL1 => 100
TBL_B COL1 => 200
```

DBLINK元のデータ(TBL_A) と DBLINK先のデータ(TBL_B) が取得＆表示できたで！彡(^)(^)

# 6. まとめ

一本のDB接続で DBLINK元 と DBLINK先 のデータを取得する事を確認できました。
ただ DBLINK は諸刃の剣。密結合な仕組みではあるので、乱用は控えるんやで。彡(ﾟ)(ﾟ)