0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Salesforce と kintone 間で顧客データを同期する方法 (Java - シンプルなJDBC)

Last updated at Posted at 2017-05-19

Salesforce と kintone 間で顧客データを同期する方法として、CDataドライバーを利用したWindowsフォームアプリケーション(C#/ADO.NET)によるものを別記事でご紹介しました。
CDataドライバーは、ADO.NETのみならず様々なテクノロジーで提供されています。今回は、Salesforce と kintone 間で顧客データを同期するアプリケーションの Java による例をご紹介したいと思います。

000_構成図.png

このアプリケーションの概要は次の通りです。

  • JDK 8
  • JavaFX によるデスクトップアプリケーション
  • Eclipse 4.6
  • Salesforce および kintone からデータを読み込む
  • インポートしたい行を選択して、Salesforce から kintone へデータをインポートする

それでは、このサンプルアプリケーションの開発手順を見ていきます。

ソースコード

このサンプルアプリケーションのソースコードはこちらからどうぞ。

CData製品のインストール

CData Software をインストールします。今回必要になるのは、次の2つです。

開発環境の準備

Eclipse 4.6 を使用します。以下の機能を Eclipse にインストールしておいてください。

  • e(fx)clipse - IDE

※ サイトのロケーションは http://download.eclipse.org/efxclipse/updates-released/2.4.0/site を使用

プロジェクト作成

新規プロジェクトを作成します。JavaFX Project を選択します。

001_プロジェクト作成.png

デフォルトのまま順次「次へ」ボタンをクリックしていきます。最後のダイアログでは、「言語」に"FXML"、「Root-Type」に"javax.scene.layout.AnchorPane"、「ファイル名」に"MainPane"、「Controller Name」に"MainPaneController"を指定し、完了ボタンをクリックします。

002_プロジェクト作成2.png

処理の実装

データモデルクラス

Salesforce側はContact、kintone側は顧客リスト に対応するクラスを実装します。これは単純なDTOです。

package application;


public class Contact {
	
	private String id;

	private String accountId;

	private String department;

	private String email;

	private String fax;

	private String name;

	private String phone;
	
	private String accountName;
	
	private String accountAddress;
	
	private String accountBillingPostalCode;

	// 以下略 それぞれのsetter/getter
}
package application;


public class 顧客リスト  {

	private int recordId;

	private String fax_数字のみ_;

	private String tel_数字のみ_;

	private String メールアドレス;
	
	private String レコード番号;

	private String 会社名;

	private String 住所;

	private String 担当者名;

	private String 部署名;

	private String 郵便番号_数字のみ_;

	// 以下略 それぞれのsetter/getter
}

MainPaneController

今回のアプリケーションの主たるクラスです。javafx.fxml.Initializableを実装して初期化できるようにします。さらに、Salesforce/kintoneに接続するためのJDBCURL、そしてそれらのデータを表示するためのTableViewのフィールドを追加します。
※JDBCURLの形式はマニュアルに記載されています。

public class MainPaneController implements Initializable {

	private String salesforceJdbcUrl = "<SalesforceのJDBCURL>";
	
	private String kintoneJdbcUrl = "<kintoneのJDBCURL>";
	
	@FXML
	private TableView<Contact> salesforceTable;
	
	@FXML
	private TableView<顧客リスト> kintoneTable;

データの読み込み

MainPaneControllerに、Salesforce/kintoneのデータをTableViewに読み込む処理を実装します。JDBCを使ったシンプルなものです。

	private void loadSalesforceTableView() {
		
		salesforceTable.getItems().clear();
		
		try (
			Connection conn = DriverManager.getConnection(salesforceJdbcUrl);
			PreparedStatement pstmt = conn.prepareStatement(
				"SELECT c.*, " +
				"a.Name AccountName, a.BillingPostalCode AccountBillingPostalCode, CONCAT(a.BillingState, a.BillingCity, a.BillingStreet) AccountAddress " +
				"FROM Contact c INNER JOIN Account a ON a.Id=c.AccountId");
			ResultSet rs = pstmt.executeQuery();
			) {

			while (rs.next()) {
				Contact c = new Contact();
				c.setId(rs.getString("Id"));
				c.setAccountId(rs.getString("AccountId"));
				c.setDepartment(rs.getString("Department"));
				c.setEmail(rs.getString("Email"));
				c.setFax(rs.getString("Fax"));
				c.setName(rs.getString("Name"));
				c.setPhone(rs.getString("Phone"));
				c.setAccountName(rs.getString("AccountName"));
				c.setAccountAddress(rs.getString("AccountAddress"));
				c.setAccountBillingPostalCode(rs.getString("AccountBillingPostalCode"));
				salesforceTable.getItems().add(c);
			}
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	private void loadKintoneTableView() {
	
		kintoneTable.getItems().clear();
		
		try (
			Connection conn = DriverManager.getConnection(kintoneJdbcUrl);
			PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM 顧客リスト");
			ResultSet rs = pstmt.executeQuery();
			) {

			while (rs.next()) {
				顧客リスト c = new 顧客リスト();
				c.setRecordId(rs.getInt("RecordId"));
				c.setFax_数字のみ_(rs.getString("Fax(数字のみ)"));
				c.setTel_数字のみ_(rs.getString("Tel(数字のみ)"));
				c.setメールアドレス(rs.getString("メールアドレス"));
				c.setレコード番号(rs.getString("レコード番号"));
				c.set会社名(rs.getString("会社名"));
				c.set住所(rs.getString("住所"));
				c.set担当者名(rs.getString("担当者名"));
				c.set部署名(rs.getString("部署名"));
				c.set郵便番号_数字のみ_(rs.getString("郵便番号(数字のみ)"));
				kintoneTable.getItems().add(c);
			}
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

アプリケーションの初期化

MainPaneControllerのinitializeを実装します。主な処理はデータ読み込みのメソッドを呼び出すだけです。

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		
		salesforceTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
		
		loadSalesforceTableView();
		loadKintoneTableView();
	}

インポート処理

インポート処理を実装します。やっていることは、Salesforce側のTableViewで選択された行のデータで、JDBCでシンプルにkintone側にINSERT/UPDATE文を実行しているだけです。

	@FXML
	private void importOnClick(MouseEvent event) {
		
		try (Connection conn = DriverManager.getConnection(kintoneJdbcUrl)) {
			
			conn.setAutoCommit(false);
			
			for (Contact contact : salesforceTable.getSelectionModel().getSelectedItems()) {
				
				顧客リスト kintoneItem = kintoneTable.getItems().stream()
					.filter(o -> o.getメールアドレス().equals(contact.getEmail()))
					.findFirst()
					.orElse(new 顧客リスト());
				
				PreparedStatement pstmt;
				
				if (kintoneItem.getRecordId() == 0) {
					pstmt = conn.prepareStatement("INSERT INTO 顧客リスト(メールアドレス, 会社名, 住所, 担当者名, 部署名, [郵便番号(数字のみ)], [Tel(数字のみ)], [Fax(数字のみ)]) VALUES(?, ? ,? ,? ,? ,? ,? ,?)");
				} else {
					pstmt = conn.prepareStatement("UPDATE 顧客リスト SET メールアドレス=?, 会社名=?, 住所=?, 担当者名=?, 部署名=?, [郵便番号(数字のみ)]=?, [Tel(数字のみ)]=?, [Fax(数字のみ)]=? WHERE RecordId=?");
					pstmt.setInt(9, kintoneItem.getRecordId());
				}
				
				pstmt.setString(1, contact.getEmail());
				pstmt.setString(2, contact.getAccountName());
				pstmt.setString(3, contact.getAccountAddress());
				pstmt.setString(4, contact.getName());
				pstmt.setString(5, Optional.ofNullable(contact.getDepartment()).orElse(""));
				pstmt.setString(6, Optional.ofNullable(contact.getAccountBillingPostalCode()).orElse("").replace("-", ""));
				pstmt.setString(7, contact.getPhone());
				pstmt.setString(8, contact.getFax());
				
				pstmt.execute();
				pstmt.close();
			}
			
			conn.commit();
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		loadKintoneTableView();
	}

画面の作成

最後に画面を作成します。application/MainPane.fxmlを開き、以下のコードを実装します。データモデルクラスの各プロパティとテーブルの列をマッピングしています。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="660.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainPaneController">
   <children>
      <TableView fx:id="salesforceTable" layoutX="14.0" layoutY="53.0" prefHeight="600.0" prefWidth="485.0">
        <columns>
          <TableColumn prefWidth="150.0" text="担当者名">
            <cellValueFactory><PropertyValueFactory property="name" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="メールアドレス">
            <cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" resizable="false" sortable="false" text="会社名">
          	<cellValueFactory><PropertyValueFactory property="accountName" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="部署名">
            <cellValueFactory><PropertyValueFactory property="department" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="住所">
            <cellValueFactory><PropertyValueFactory property="accountAddress" /></cellValueFactory>
          </TableColumn>
        </columns>
      </TableView>
      <Button layoutX="542.0" layoutY="263.0" mnemonicParsing="false" onMouseClicked="#importOnClick" prefHeight="35.0" prefWidth="116.0" text="インポート" />
      <TableView fx:id="kintoneTable" layoutX="696.0" layoutY="53.0" prefHeight="600.0" prefWidth="485.0">
        <columns>
          <TableColumn editable="false" prefWidth="75.0" sortable="false" text="レコード番号">
            <cellValueFactory><PropertyValueFactory property="レコード番号" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="担当者名">
            <cellValueFactory><PropertyValueFactory property="担当者名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="メールアドレス">
            <cellValueFactory><PropertyValueFactory property="メールアドレス" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="会社名">
            <cellValueFactory><PropertyValueFactory property="会社名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="100.0" sortable="false" text="部署名">
            <cellValueFactory><PropertyValueFactory property="部署名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="住所">
            <cellValueFactory><PropertyValueFactory property="住所" /></cellValueFactory>
          </TableColumn>
        </columns>
      </TableView>
   </children>
</AnchorPane>

ウィンドウのサイズを設定します。application/Main.java を開き、Sceneのサイズを変更します。

Scene scene = new Scene(root, 1200, 660);

実装は以上です。

実行

実行構成を作成します。[実行]->[実行構成]を開き、「Javaアプリケーション」を右クリックして「新規」を選択します。
クラスパスタブを開き、CDataのJDBCドライバーを2つ指定し、実行ボタンをクリックします。

018_実行構成.png

実行すると、テーブルビューにSalesforceとkintoneのデータが表示されたウィンドウが立ち上がります。

019_実行直後.png

データ移行したい行を選択して「インポート」ボタンをクリックすると、選択したデータが kintone に登録されます。

020_移行後.png

021_移行後kintone.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?