Eclipseのバッチ処理でJPAを使ったDBアクセスを行う。

この記事は、Eclipseのバッチ処理でJPAとDBでPostgreSQLを扱ったプロジェクトの作成方法と簡単なDAOを使った処理について、記載したものです。

ポイント：

依存関係の注入を行う為、以下のアノテーションを追加しています。
(1) @EnableJpaRepositories(basePackages = {"com.example.demo.dao"})
(2) @EntityScan(basePackages = {"com.example.demo.entity"})
(3) @ComponentScan(basePackages = {"com.example.demo"})
※ @Autowired アノテーションによって、(1)で "com.example.demo.dao" のパッケージ内で作成した@Repositoryアノテーションクラス、(2)で "com.example.demo.entity" のパッケージ内で作成した@Entityアノテーションクラス、(3)で "com.example.demo" のパッケージ内で作成した@Componentアノテーションクラスの依存関係の注入を行えるようにします。

プロジェクトの作成手順：

1．Postgres側のDBにテスト用のテーブルを作成しています。
今回は、以下のような簡単なテーブルを作成します。

-- Table: public.mstr_info

-- DROP TABLE public.mstr_info;

CREATE TABLE public.mstr_info
(
  itemcode character varying(12) NOT NULL,
  itemname character varying(100) NOT NULL,
  CONSTRAINT mstr_info_pkey PRIMARY KEY (itemcode)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.mstr_info
  OWNER TO postgres;

テスト用にデータも入れておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/24d2e834-5d36-2bc0-dfbf-ba69bc1cc48c.png)

2．Eclipse側でプロジェクトの作成をします。
(1)パッケージエクスプローラより、右クリックしてプロジェクトを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/206311dd-17ae-3447-5dda-fc327c591f55.png)

(2)Springスターター・プロジェクトを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/d3fbc66c-fce0-b196-e156-56c248c0752d.png)

(3)名前を適当に入力して、次へをクリックします。ここでは demo-1 を設定しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/e7820833-69f6-d014-7168-1398dbf06aa0.png)

(4)バッチ、JPA、PostgresSQL を選択して完了をクリックします。チェックボックスの表示がない場合、左側のメニューから選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/8df79c25-9aa6-1889-ef2c-823948e8a31b.png)

3．JPAプロジェクトに変換します。
(1) 2.で作成した、demo-1 プロジェクトを右クリックして、構成、JPAプロジェクトへ変換... をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/70812ea1-06cd-fc8f-4e02-41dc62d2111d.png)

(2)そのまま、次へをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/48e7ef62-4ba4-4e3d-2f14-919a19583bc2.png)

(3)そのまま、次へをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/f5214399-d621-62ac-5f52-b77e7a7d781d.png)

(4)完了をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/6c35e706-f62d-7496-9410-405caeca75c4.png)

4．エンティティを作成します。
上記の 3.でJPAプロジェクトに変換すると、JPAツールが利用できます。
(1)demo-1プロジェクトを右クリック->JPAツール->テーブルからエンティティを生成をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/1b352474-748b-5b94-f1e0-31debf9916e4.png)

(2)新規PostgreSQLで接続の追加をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/6a8112c4-1d3a-9290-5b1d-1ebca40da25d.png)

(3)PostgreSQLを選択して、次へをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/95b6def8-1247-25bb-074e-69aea6bd3c84.png)

(4)PostgreSQLの接続情報を入力して、接続テストをクリックします。
接続テストで成功したら、完了をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/57da438e-2380-3cc6-ae42-7ea503011692.png)

(5)接続に新規PostgreSQL(1)、スキーマにpublicを選択すると、テーブル情報が表示されます。今回は 1.で作成したテーブルのエンティティを作成するので、mstr_info をチェックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/fadfb6a8-becb-5148-e4e2-ec6f12d566d6.png)

(6)そのまま、次へをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/16a7bb7c-d275-ba3e-66a1-31a7490d28ad.png)

(7)パッケージ名はentityクラス専用としたいので、デフォルトパッケージ名に .entity を追加して、次へをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/0ed8d55c-1c65-895d-e444-f2d81f3cb8eb.png)

(8)クラス名にEntityを追加して、完了をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/17116d1c-50fd-2fbe-9195-01aa5950c458.png)

(9)MstrInfoEntityクラスが自動生成されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/6b8afdfb-842d-e19b-f5f0-c71a7962fd65.png)

5．DAOを作成します。
(1)com.example.demo.dao パッケージを作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/88591aef-5b18-3ae2-f2d2-3c7323f66ba3.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/20d0e59a-9dae-75df-d65d-9ae0e2a7e808.png)

(2)MstrInfoDaoクラスを作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/b6a72ffc-7864-213c-7183-c435449d7f67.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/9b068ab6-ef5e-73b7-a1f7-216628c8da89.png)

(3)MstrInfoDao.java クラスに簡単な検索文を追加していきます。

以下のコードで上書きします。
package com.example.demo.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.entity.MstrInfoEntity;

@Repository
public interface MstrInfoDao extends JpaRepository<MstrInfoEntity, String> {

	public List<MstrInfoEntity> findByItemcode(String itemcode);
}

6．バッチ処理からテストデータを取得して表示してみます。
(1)Eclipseで簡単なバッチ処理の枠組みを作成する。の記事で使用したプロジェクトを参考にして、ジョブとタスクのクラスを作成していきます。
https://qiita.com/toolate32/items/4381bfd19c4c46733571
ここでは、Demo1Application.java、Demo1Job.java、Demo1Tasklet.java を作成します。

Demo1Application.java
==============================================================
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories(
		basePackages = {"com.example.demo.dao"}
)
@EntityScan(
		basePackages = {"com.example.demo.entity"}
)
@ComponentScan(
		basePackages = {"com.example.demo"}
)
@SpringBootApplication
public class Demo1Application {

	public static void main(String[] args) {
		System.out.println("main start");
		ApplicationContext context = SpringApplication.run(Demo1Application.class, args);
		int iRet = SpringApplication.exit(context);
		System.out.println("exit code = " + iRet);
		System.exit(iRet);
		System.out.println("main end");
	}
}

Demo1Job.java
==============================================================
package com.example.demo;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@EnableBatchProcessing
public class Demo1Job {

	@Autowired
	private JobBuilderFactory jobFactory;

	@Autowired
	private StepBuilderFactory stepFactory;

	@Autowired
	private Demo1Tasklet demo1Tasklet;

	@Bean
	public Step step1() {

		return stepFactory
				.get("step1")
				.tasklet(demo1Tasklet)
				.build();
	}

	@Bean
	public Job job(Step step1) {

		return jobFactory
				.get("job")
				.incrementer(new RunIdIncrementer())
				.start(step1)
				.build();
	}
}

Demo1Tasklet.java
==============================================================
package com.example.demo;

import java.util.List;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.stereotype.Component;

import com.example.dao.MstrInfoDao;
import com.example.entity.MstrInfoEntity;


@Component
public class Demo1Tasklet implements Tasklet, ExitCodeGenerator  {

	@Autowired
	private MstrInfoDao mstrInfoDao;

        @Override
	public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

		System.out.println("== BatchTestTasklet Start OK ==");
		List<MstrInfoEntity> lstMstrInfoEntity = mstrInfoDao.findByItemcode("1");
		MstrInfoEntity entity = lstMstrInfoEntity.get(0);
		System.out.println("ItemCode=" + entity.getItemcode());
		System.out.println("ItemName=" + entity.getItemname());
		System.out.println("== BatchTestTasklet Start END ==");
		return RepeatStatus.FINISHED;
	}

	@Override
	public int getExitCode() {
		return 0;
	}
}

7．Demo1Application.java を実行してみます。
(1) Demo1Application を右クリックして、実行->Javaアプリケーションをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157744/cbce8b2f-8766-15a6-6eaf-9fe8807b3ff0.png)

(2) ログ出力で以下のように出力されていれば、DBからの取得が出来ています。
== BatchTestTasklet Start OK ==
ItemCode=1
ItemName=name1
== BatchTestTasklet Start END ==