Spring Frameworkでのデータベース処理

1.データベース接続

Spring JDBCを使用してPostgreSQLにデータベース接続するため、ライブラリの定義を pom.xml に追加します。

  <properties>
     :
    <!-- PostgreSQL version -->
    <postgresql.version>9.4-1206-jdbc42</postgresql.version>
  </properties>
  <dependencies>
     :
    <!-- Spring JDBC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>
    <!-- PostgreSQL -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>${postgresql.version}</version>
    </dependency>
     :
  </dependencies>
</project>

続いて、データベースの接続設定を spring-mvc.xml に定義します。
データベースの接続パラメータは環境依存する情報のため、外部ファイルに定義し、その変数値をDB接続設定として定義します。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     :
  <!-- DB設定(環境依存の外部化) -->
  <context:property-placeholder location="classpath:config/database.properties"/>

  <!-- DB接続設定 -->
  <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
  </bean>
</beans>

データベース構築時に設定した情報を外部ファイル(database.properties)へ定義します。

jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/studydb
jdbc.username=study
jdbc.password=xxxxxx

2.コネクションプーリング

コネクションプーリングを使用するには、Commons DBCP2などを使用して実装します。必要なライブラリを pom.xml に定義します。

  <properties>
     :
    <!-- Commons DBCP2 version -->
    <commons-dbcp2.version>2.1.1</commons-dbcp2.version>
  </properties>
  <dependencies>
     :
    <!-- Commons DBCP2 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>${commons-dbcp2.version}</version>
    </dependency>
  </dependencies>
</project>

spring-mvc.xml 定義したデータベース接続設定で使用するDataSourceをCommons DBCP2のクラスに変更します。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     :
  <!-- DB設定(環境依存の外部化) -->
  <context:property-placeholder location="classpath:config/database.properties"/>

  <!-- DB接続設定 -->
  <bean id="dataSource"
      class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="maxTotal" value="${jdbc.maxTotal}" />
  </bean>
</beans>

外部ファイルに最大コネクションプール数を設定します。

jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/studydb
jdbc.username=study
jdbc.password=xxxxxx
jdbc.maxTotal=10

3.O/Rマッピング

O/RマッパーとしてMyBatisを使用するため、pom.xmlに必要なライブラリの定義を行います。

  <properties>
     :
    <!-- MyBatis version -->
    <mybatis.version>3.5.6</mybatis.version>
    <!-- MyBatis Spring version -->
    <mybatis-spring.version>2.0.0</mybatis-spring.version>
  </properties>
  <dependencies>
     :
    <!-- MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis-spring.version}</version>
    </dependency>
</project>

MyBatisの設定を spring-mvc.xml に定義します。定義する内容は以下の通りです。

  • XMLのスキーマ情報
  • SQLを定義するXMLファイルのパス
  • アンダースコア区切りのテーブル定義からキャメル形式に変換するかどうかの設定
  • Mapperクラスをスキャンするパッケージの設定
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     :
    xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
     :
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
     :
  <!-- MyBatis マッピング設定 -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations" value="classpath*:config/mappers/**/*.xml" />
    <property name="configuration">
      <bean class="org.apache.ibatis.session.Configuration">
        <property name="mapUnderscoreToCamelCase" value="true" />
      </bean>
    </property>
  </bean>

  <!-- Mapperクラススキャン対象パッケージ -->
  <mybatis:scan base-package="org.miyadai.app.study.mapper" />
</beans>

エンティティ(テーブル)ごとのSQLをXMLに定義します。XMLはspring-mvc.xmlに定義したパス(例:src/main/resources/config/mappers/)配下にテーブル名.xmlで作成します(テーブル名ITEMの場合、item.xml)。

namespaceにはMapperクラス、resultTypeにはEntityクラスを指定します。
SELECT、INSERT、UPDATE、DELETEのSQLを必要に応じて定義します。
#{xxxxXxxx}の部分はEntityのプロパティ名を設定します。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.miyadai.app.study.mapper.ItemMapper">
  <select id="findAll" resultType="org.miyadai.app.study.entity.Item">
    select ITEM_CODE, ITEM_NAME, NOTE, ITEM_TYPE, LOT_MNG, VALID_FLG, INS_DATE, INS_USER, UPD_DATE, UPD_USER from ITEM
  </select>
  <select id="findOne" resultType="org.miyadai.app.study.entity.Item">
    select ITEM_CODE, ITEM_NAME, NOTE, ITEM_TYPE, LOT_MNG, VALID_FLG, INS_DATE, INS_USER, UPD_DATE, UPD_USER from ITEM where ITEM_CODE = #{itemCode}
  </select>
  <insert id="save">
    insert into ITEM (ITEM_CODE, ITEM_NAME, NOTE, ITEM_TYPE, LOT_MNG, VALID_FLG, INS_DATE, INS_USER, UPD_DATE, UPD_USER)
      values (#{itemCode}, #{itemName}, #{note}, #{itemType}, #{lotMng}, #{validFlg}, #{insDate}, #{insUser}, #{updDate}, #{updUser})
  </insert>
  <update id="update">
    update ITEM set ITEM_CODE = #{itemCode}, ITEM_NAME = #{itemName}, NOTE = #{note}, ITEM_TYPE = #{itemType}, LOT_MNG = #{lotMng}, VALID_FLG = #{validFlg}, INS_DATE = #{insDate}, INS_USER = #{insUser}, UPD_DATE = #{updDate}, UPD_USER = #{updUser} where ITEM_CODE = #{itemCode}
  </update>
  <delete id="delete">
    delete from ITEM where ITEM_CODE = #{itemCode}
  </delete>
</mapper>

Entityクラスを作成します。
Entityクラスはテーブル定義に沿ってフィールとおよびGetterメソッド、Setterメソッドを定義します。

public class Item {

	/* 品目コード. */
	String itemCode;

	/* 品目名. */
	String itemName;
     :
	/**
	 * 品目コードを取得します.
	 * @return 品目コード
	 */
	public String getItemCode() {
		return itemCode;
	}

	/**
	 * 品目コードを設定します.
	 * @param itemCode 品目コード
	 */
	public void setItemCode(String itemCode) {
		this.itemCode = itemCode;
	}
     :
}

Mapperインターフェースを作成します。
Mapperインタフェースには@Mapperアノテーションを付加します。
SQLを定義したXMLに沿ってメソッドを定義します。

@Mapper
public interface ItemMapper {

	List<Item> findAll();

	Item findOne(String itemCode);

	void save(Item item);

	void update(Item item);

	void delete(Item item);
}

Serviceクラス(ビジネスロジックを実装するクラス)を作成します。
Serviceクラスには@Serviceアノテーションを付加します。
MapperクラスをDIし、各業務処理内でMappertクラスの処理を実行します。

@Service
public class ItemService {

	@Autowired
	private ItemMapper itemMapper;

	public List<Item> findAll() {
		return itemMapper.findAll();
	}

	public Item findAll(String itemCode) {
		return itemMapper.findOne(itemCode);
	}

	public void save(Item item) {
		itemMapper.save(item);
	}

	public void update(Item item) {
		itemMapper.update(item);
	}

	public void delete(Item item) {
		itemMapper.delete(item);
	}
}

4.トランザクション制御

ビジネスロジックごとにトランザクション制御を自動で行うため、アノテーションおよびAOPでの制御を行います。Spring Aspectsを使用するため、pom.xmlにライブラリを定義します。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     :
  <dependencies>
     :
    <!-- Spring Aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>
  </dependencies>
</project>

アノテーションおよびAOPでのトランザクション制御を行う設定を spring-mvc.xmlに定義します。定義する内容は以下の通りです。

  • XMLのスキーマ情報にAOPとTX(Transaction)の定義を追加
  • アノテーションで制御する旨の宣言
  • AOPでServiceクラスのどのメソッドがトランザクション対象か定義
  • AOPでどのクラスがトランザクション制御対象かPointcutで定義
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     :
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
     :
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
     :
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     :
  <!-- アノテーションでトランザクションを制御 -->
  <tx:annotation-driven />
  <bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
  </bean>

  <!-- AOPでトランザクションを制御 -->
  <tx:advice id="txAdv" transaction-manager="transactionManager">
    <tx:attributes>
      <tx:method name="save*" />
      <tx:method name="update*" />
      <tx:method name="delete*" />
    </tx:attributes>
  </tx:advice>
  <aop:config>
    <aop:advisor advice-ref="txAdv" pointcut="execution(* org.miyadai.app.study.service.*Service.*(..))" />
  </aop:config>
     :
</beans>

Serviceクラスの対象メソッドに@Transactionalアノテーションを付加します。AOPと併用し、AOPの対象となっている場合はアノテーションは不要です。

@Service
public class ItemService {

	@Autowired
	private ItemMapper itemMapper;

	public List<Item> findAll() {
		return itemMapper.findAll();
	}

	public Item findAll(String itemCode) {
		return itemMapper.findOne(itemCode);
	}

	@Transactional
	public void save(Item item) {
		itemMapper.save(item);
	}

	public void update(Item item) {
		itemMapper.update(item);
	}

	public void delete(Item item) {
		itemMapper.delete(item);
	}
}

PosgreSQLのインストールとデータベース作成

1.PostgreSQLのインストール

EDB社のダウンロードページにアクセスし、インストーラをダウンロードします。
URL「https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

(1) サイトにアクセスしたらOSにあったバージョンのDownloadボタンをクリックします。

(2) ダウンロードが開始されるので、任意の場所に保存します。

(3) ダウンロードしたファイルをダブルクリックして、インストーラを起動し、以下画面が出たらNextをクリックします。

(4) インストール場所を選択し、Nextをクリックします。

(5) インストールするコンポーネントを選択し、Nextをクリックします。
※コンポーネントは初期状態(全てチェック)で構いません。

(6) データベースクラスタ(データベースを格納する領域)の作成先フォルダを指定し、Nextをクリックします。
※デフォルトのままでも構いません。

(7) スーパーユーザ(postgres)のパスワードを設定し、Nextをクリックします。

(8) クライアントから接続する際のパスワードを設定し、Nextをクリックします。
※デフォルトのままで構いません。

(9) ロケールを選択し、Nextをクリックします。
※ここではロケールを使わないことを示す C を選択します。

(10) インストールの情報が表示されますので、問題なければNextをクリックします。

(11) インストールの準備ができたので、Nextをクリックします。

(12) インストール完了後、 Stack Builder を起動するかを選択し、Finishをクリックします。
※ここでは起動しないため、チェックを外します。

2.ユーザの作成

インストールが完了したので、次はユーザを作成します。

(1) Windowsのスタートメニューから、SQL Shell (psql) を起動します。
(2) ユーザ postgres のパスワード以外は、すべて何も入力せずEnterキーを押します。
(3) postgres=# とコンソールに出たら、「create role (ユーザ名) with password ‘(パスワード)’ createdb;」と入力し、Enterキーを押します。
(4) CREATE ROLE と表示されたらユーザが作成されていますので、「\q」と入力し、Enterキーを押します。※コンソールを抜けます。

3.データベースの作成

ユーザを作成したら次はデータベースを作成します。

(1) Windowsのスタートメニューから、SQL Shell (psql) を起動します。
(2) ユーザ postgres のパスワード以外は、すべて何も入力せずEnterキーを押します。
(3) postgres=# とコンソールに出たら、「create database (データベース名) with owner (所有ユーザ名);」と入力し、Enterキーを押します。
(4) CREATE DATABASE と表示されたらデータが作成されていますので、「\l」と入力し、Enterキーを押します。
(5) データベースの一覧が表示されますので、作成したデータベースが存在することを確認します。
(6) 「\q」と入力し、Enterキーを押します。※コンソールを抜けます。

4.データベース接続確認

ユーザおよびデータベースの作成が完了したら、データベースへの接続確認を行います。
ここではフリーのSQLクライアント「A5:SQL Mk-2」を例にします。

(1) データベース追加画面での接続タイプで「PostgreSQL (直接接続)」を選択します。

(2) サーバ名、データベース名、ポート番号、ユーザーID、パスワードを入力し、OKボタンをクリックします。
※テスト接続ボタンをクリックして、接続できるか確認してください。
※入力内容は、作成したユーザ、データベースの情報を入力してください。

データベースへ接続できれば確認完了です。