LoginSignup
0
0

DataLoaderとDatabaseを連動する【V58】【HSQLDB編】

Posted at

SalesforceのバッチモードではCSVファイル以外にデータベースと連動する機能がある。

データベース接続およびSQL定義はdatabase-conf.xmlで定義する。
本記事ではHSQLDBを利用してSalesforceと連動を実施する。

前提条件

  • Java 11以上
  • DataLoder Version 58.0.4
  • HSQLDB 2.1.210

セキュリティトークンの取得

別の記事を参照

データローダバッチの構成

C:\DataLoaderProcess
  ├─config.properties              ⇒ データローダ環境設定ファイル
  ├─my.properties                  ⇒ 独自の環境設定ファイル
  │─extractAccountDbToSf.bat       ⇒ データベースからデータを取得してSalesforceへUpsertする
  │─extractAccountSfToDb.bat       ⇒ Salesforceからデータを取得してデータベースへInsertする
  │─extractAccountDbToSfMap.sdl    ⇒ DataLoaderマッピングファイル(Database⇒Salesforce)
  │─extractAccountSfToDbMap.sd     ⇒ DataLoaderマッピングファイル(Salesforce⇒Database)
  │─dataloader.key                 ⇒ 暗号鍵
  │─dataloader-58.0.4.jar          ⇒ データローダJAR
  │─spring-context-5.3.27.jar      ⇒ spring-context
  │─spring-core-5.3.27.jar         ⇒ spring-core
  │─h2-2.1.210.jar                 ⇒ HSQLDBライブラリ
  │─h2v2.mv.db                     ⇒ HSQLDBデータベースファイル
  │─h2v2.trace.db                  ⇒ HSQLDBデータベースファイル
  ├─process.bat                    ⇒ バッチ起動ファイル(ProcessId指定)
  ├─process-conf.xml               ⇒ データローダの実行設定ファイル
  └─log4j2.properties              ⇒ ログ出力用の設定ファイル

必要なJarファイルの取得する

DataLoader jarファイルの取得

本記事にはJava 11をサポートする最後のバージョンであるV58.0.4を利用する
取得先:https://github.com/forcedotcom/dataloader/releases/tag/v58.0.4

欲しいのは[dataloader-58.0.4.jar]ファイルのみなので任意のフォルダにコピーしておく
この記事では[C:\DataLoaderProcess]にコピーした。

Spring-Core,Spring-Context jarファイルの取得

mavenサイトからダウンロードする。
spring-core-5.3.27.jar
spring-context-5.3.27.jar

H2 Database Engine jarファイルの取得

h2-2.1.210.jar

※あなたが経験あるJavaプログラマーであれば、何で細かいマイナバージョンまで指定しているか理解してくれるはずです。

暗号化されたパスワードの生成

別の記事を参照

データベースを用意する

C:\DataLoaderProcess\h2v2.mv.dbファイルを作成し、以下のテーブルを作成する

CREATE TABLE PUBLIC.ACCOUNT_TABLE (
	ID CHARACTER(18),
	NAME CHARACTER(255),
	NUMBER_OF_EMPLOYEES INTEGER,
	INDUSTRY CHARACTER(40),
	ANNUAL_REVENUE DOUBLE PRECISION,
	CREATED_DATE CHARACTER(25)
);

設定ファイルを作成する

config.properties

# Data LodaerLoader Config
# https://help.salesforce.com/apex/HTViewHelpDoc?id=loader_params.htm

# 接続先情報
# sandboxの場合:https://test.salesforce.com
sfdc.endpoint=https://login.salesforce.com
sfdc.username=<ログインユーザ名>
sfdc.password=<コマンドで生成した暗号化パスワード>
process.encryptionKeyFile=./dataLoader.key

my.properties

# 独自の環境設定

outputdirectory=C:/DataLoaderProcess

log4j2.properties

name = Salesforce Data Loader
monitorInterval = 5
property.basePath = ${sys:java.io.tmpdir}
# RollingFileAppender name, pattern, path and rollover policy
appender.rolling.type = RollingFile
appender.rolling.name = fileAppender
appender.rolling.fileName= ./log/sdl.log
appender.rolling.filePattern= ./log/sdl-%d{yyyy-MM-dd}.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %-5p [%t] %C{2} %M (%F:%L) - %m%n
appender.rolling.policies.type = Policies

# CONSOLE Appender
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d %-5p [%t] %C{2} %M (%F:%L) - %m%n

# RollingFileAppender rotation policy
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 100KB

# Configure root logger
rootLogger.level = info
rootLogger.appenderRef.rolling.ref = fileAppender
rootLogger.appenderRef.stdout.ref = STDOUT

database-conf.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/util
           http://www.springframework.org/schema/util/spring-util.xsd
           http://www.springframework.org/schema/tool
           http://www.springframework.org/schema/tool/spring-tool.xsd">

    <!-- 独自の環境設定をロード -->
    <context:property-placeholder location="classpath:my.properties"/>

    <!-- データソースの設定(必ずdbcp2を使用する必要がある) -->
    <bean id="dbDataSource"
        class="org.apache.commons.dbcp2.BasicDataSource"
        destroy-method="close"
        scope="prototype">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:./h2v2"/>
        <property name="username" value=""/>
        <property name="password" value=""/>
    </bean>

    <!-- データベースから取得するBean定義 -->
    <bean id="queryAccountTable"
        class="com.salesforce.dataloader.dao.database.DatabaseConfig"
        scope="singleton">
        <property name="sqlConfig" ref="queryAccountTableSql"/>
        <property name="dataSource" ref="dbDataSource"/>
    </bean>

    <!-- データベースへ登録するBean定義 -->
    <bean id="insertAccountTable"
        class="com.salesforce.dataloader.dao.database.DatabaseConfig"
        scope="singleton">
        <property name="sqlConfig" ref="insertAccountTableSql"/>
        <property name="dataSource" ref="dbDataSource"/>
    </bean>

    <!-- SELECT SQL -->
    <bean id="queryAccountTableSql"
        class="com.salesforce.dataloader.dao.database.SqlConfig"
        scope="singleton">
        <property name="sqlString">
            <value>
                SELECT ID, NAME, NUMBER_OF_EMPLOYEES, INDUSTRY, ANNUAL_REVENUE
                FROM ACCOUNT_TABLE
                WHERE created_date > @process.lastRunDate@
            </value>
        </property>
        <property name="columnNames">
            <list>
                <value>id</value>
                <value>name</value>
                <value>number_of_employees</value>
                <value>industry</value>
                <value>annual_revenue</value>
            </list>
        </property>
        <property name="sqlParams">
            <map>
                <entry key="process.lastRunDate" value="java.sql.Timestamp"/>
            </map>
        </property>
    </bean>

    <!-- INSERT SQL -->
    <bean id="insertAccountTableSql"
        class="com.salesforce.dataloader.dao.database.SqlConfig"
        scope="singleton">
        <property name="sqlString">
            <value>
                INSERT INTO ACCOUNT_TABLE (
                ID, NAME, NUMBER_OF_EMPLOYEES, INDUSTRY, ANNUAL_REVENUE, CREATED_DATE)
                VALUES (@id@, @name@, @number_of_employees@, @industry@, @annual_revenue@, @created_date@)
            </value>
        </property>
        <property name="sqlParams">
            <map>
                <entry key="id"                  value="java.lang.String" />
                <entry key="name"                value="java.lang.String" />
                <entry key="number_of_employees" value="java.lang.Long" />
                <entry key="industry"            value="java.lang.Double" />
                <entry key="annual_revenue"      value="java.lang.String" />
                <entry key="created_date"        value="java.lang.String" />
            </map>
        </property>
    </bean>
</beans>

process-conf.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/util
           http://www.springframework.org/schema/util/spring-util.xsd
           http://www.springframework.org/schema/tool
           http://www.springframework.org/schema/tool/spring-tool.xsd">

    <!-- 独自の環境設定をロード -->
    <context:property-placeholder location="classpath:my.properties"/>

    <!-- Salesforce⇒Database出力ジョブを定義 -->
    <bean id="extractAccountSfToDb"
          class="com.salesforce.dataloader.process.ProcessRunner"
          scope="prototype">
        <description>extractAccountSfToDbジョブは、Salesforceから取引先情報を取得し、データベースへ保存します。</description>
        <property name="name" value="extractAccountSfToDb"/>
        <property name="configOverrideMap">
            <map>
                <entry key="sfdc.extractionSOQL" value="Select Id, Name, NumberOfEmployees, Industry, AnnualRevenue, CreatedDate FROM Account LIMIT 10" />
                <entry key="process.outputSuccess" value="${outputdirectory}/extractAccountDbSuccess.csv"/>
                <entry key="process.outputError" value="${outputdirectory}/extractAccountDbError.csv"/>
                <entry key="sfdc.debugMessagesFile" value="${outputdirectory}/extractAccountSfToDbSoapTrace.log"/>
                <entry key="sfdc.extractionRequestSize" value="1000"/>
                <entry key="sfdc.entity" value="Account"/>
                <entry key="process.operation" value="extract"/>
                <entry key="process.mappingFile" value="${outputdirectory}/extractAccountSfToDbMap.sdl"/>
                <entry key="dataAccess.type" value="databaseWrite"/>
                <entry key="dataAccess.name" value="insertAccountTable"/>
                <entry key="dataAccess.writeBatchSize" value="750"/>
            </map>
        </property>
    </bean>

    <!-- Database⇒Salesforce入力ジョブを定義 -->
    <bean id="extractAccountDbToSf"
          class="com.salesforce.dataloader.process.ProcessRunner"
          scope="prototype">
        <description>extractAccountDbToSfジョブは、データベースから取引先情報を取得し、SalesforceへUpsertします。</description>
        <property name="name" value="extractAccountDbToSf"/>
        <property name="configOverrideMap">
            <map>
                <entry key="sfdc.debugMessages" value="false"/>
                <entry key="sfdc.debugMessagesFile" value="${outputdirectory}/extractAccountSfToDbSoapTrace.log"/>
                <entry key="sfdc.externalIdField" value="Id"/>
                <entry key="sfdc.entity" value="Account"/>
                <entry key="process.operation" value="upsert"/>
                <entry key="process.mappingFile" value="${outputdirectory}/extractAccountDbToSfMap.sdl"/>
                <entry key="dataAccess.name" value="queryAccountTable"/>
                <entry key="dataAccess.type" value="databaseRead"/>
                <entry key="process.initialLastRunDate" value="2005-12-01T00:00:00.000-0800"/>
            </map>
        </property>
    </bean>

</beans>

process.bat

@echo off

SET MIN_JAVA_VERSION=11
echo Data Loader requires Java JRE %MIN_JAVA_VERSION% or later. Checking if it is installed...
java -version 1>nul 2>nul || (
echo Did not find java command.
EXIT -1
)

java -cp ".\dataloader-58.0.4.jar;.\spring-core-5.3.27.jar;.\spring-context-5.3.27.jar;.\h2-2.1.210.jar;." com.salesforce.dataloader.process.DataLoaderRunner .\ %1 run.mode=batch
EXIT /b %ERRORLEVEL%

extractAccountDbToSf.bat


CALL process.bat extractAccountDbToSf

extractAccountSfToDb.bat


CALL process.bat extractAccountSfToDb

バッチファイルの実行

データベースにはデータが何もないのでまず、Salesforceからデータを取得してデータベースへ登録してみる。

extractAccountSfToDb.batファイルを実行して起動

image.png

次はデータベースへ登録された取引先情報をSalesforceへUpsertする。
データは同じなので最終更新日が更新されたことは確認できる

extractAccountDbToSf.batファイルを実行して起動

image.png

0
0
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
0