【初心者〜現場で活躍まで】挫折しないPython勉強方法もっと知る

Springboot、Doma2、Gradle、Dockerで、SQLファイルベースのDBアクセスを実現する手順

Springboot、Doma2、Gradle、Dockerで、 SQLファイルベースのDBアクセスを実現する手順

Springbootでアプリケーションを開発する際、DBのライブラリは何を使っているのでしょうか?

自分の経験上、結構色んな種類のものがあって非常に悩みどころです。

この記事について

今回は、SQLファイルを使ってSQL文を発行出来るDoma2というDBアクセスフレームワークを使用して、簡単にDBアクセスを実現していきます。

一個、パターンを覚えておくと、DBアクセスを利用する色んな現場で使えますので、是非ともご確認頂きたいと思います。

目次

環境

環境は以下の通り。

今回の環境
  • Springboot : 2.2.6
  • Doma2 : 2.20.0
  • PostgreSQL : 11.7
  • Docker : 19.03.8

DBはDockerを使用して、PostgreSQLをインストールします。

フォルダ構成

今回、作成するファイルのフォルダ構成は以下となります。

demo2-sample
|--src
|  |--main
|  |  |--java
|  |  |  |--com
|  |  |  |  |--example
|  |  |  |  |  |--Demo2SampleApplication.java
|  |  |  |  |  |--controller
|  |  |  |  |  |  |--SampleController.java
|  |  |  |  |  |--dao
|  |  |  |  |  |  |--SampleDao.java
|  |  |  |  |  |--entity
|  |  |  |  |  |  |--Sample.java
|  |  |  |  |  |--service
|  |  |  |  |  |  |--SampleService.java
|  |  |  |  |  |  |--impl
|  |  |  |  |  |  |  |--SampleServiceImpl.java
|  |  |--resources
|  |  |  |--META-INF
|  |  |  |  |--com
|  |  |  |  |  |--example
|  |  |  |  |  |  |--dao
|  |  |  |  |  |  |  |--SampleDao
|  |  |  |  |  |  |  |  |--selectAll.sql
|  |  |  |--application.properties
|  |--test
|--build.gradle
|--Dockerfile
|--docker-compose.yml

ファイルの数が多く、フォルダ構成が結構ややこしいですね。

ポイントは、「resources/META-INF」以下のSQLファイルです。Doma2はSQLファイルベースで、DBアクセスします。

利点は以下となります。

SQLファイルベースである利点
  • Doma2はSQLをJavaのクラスやアノテーションを組み合わせて構成するのではなく、SQLファイルで構成されている。
  • SQLが書ければ、そのまま知識を使うことが出来る。
  • SQLがベースなので、複雑なSQLも簡単に実装が出来る

Springbootプロジェクトの作成

Spring Initializrで楽々プロジェクト作成

Springbootのプロジェクトを作成する際は、以下を使用するのが便利です。

Spring Initializr

あとで、build.gradleを修正するので、こんな感じで、適当に作っちゃって下さい。

build.gradleの修正

build.gradleの修正はとても難しいです。モジュール間の依存関係を考えたりとか、一番頭を悩ますポイントではないでしょうか?

エソラ

多分、ここが一番ハマる(自分もハマった)ので、注意深く作業して下さい。

Doma2を使う場合は、以下のようにbuild.gradleを修正する。

plugins {
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

// テンポラリディレクトリのパスを定義する
ext.domaResourcesDir = "${buildDir}/tmp/doma-resources"

// domaが注釈処理で参照するリソースをテンポラリディレクトリに抽出
task extractDomaResources(type: Copy, dependsOn: processResources)  {
    from processResources.destinationDir
    include 'doma.compile.config'
    include 'META-INF/**/*.sql'
    include 'META-INF/**/*.script'
    into domaResourcesDir
}

// テンポラリディレクトリ内のリソースをcompileJavaタスクの出力先ディレクトリにコピーする
task copyDomaResources(type: Copy, dependsOn: extractDomaResources)  {
    from domaResourcesDir
    into compileJava.destinationDir
}

repositories {
    mavenCentral()
}

compileJava {
    // 上述のタスクに依存させる
    dependsOn copyDomaResources
    // テンポラリディレクトリをcompileJavaタスクの入力ディレクトリに設定する
    inputs.dir domaResourcesDir
    options.encoding = 'UTF-8'
}

compileTestJava {
    options.encoding = 'UTF-8'
    // テストの実行時は注釈処理を無効にする
    options.compilerArgs = ['-proc:none']
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.projectlombok:lombok'
    implementation "org.seasar.doma.boot:doma-spring-boot-starter:1.1.1"
    // domaの注釈処理を実行することを示す
    annotationProcessor "org.seasar.doma:doma:2.20.0"
    // domaへの依存を示す
    implementation "org.seasar.doma:doma:2.20.0"
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}

上手く設定が出来ていないと、ビルドした際にDoma2のimplファイルが出力されないので、注意下さい。

application.propertiesの作成

application.propertiesはこんな感じで、DB接続に関するプロパティを設定します。

以下の設定はPostgreSQLですが、自分の環境に合わせて書き換えて下さい。

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://db:5432/sample_db
spring.datasource.username=postgres
spring.datasource.password=password

正しく書くことが出来れば、DB接続が出来ます。

Dockerを使った環境準備

Dockerを使って、環境準備をしていきます。

Dockerについて分からない場合は、以下から確認下さい。

Dockerfileの修正

Dockerfileは以下のような感じで定義。

FROM openjdk:8

RUN mkdir /api
WORKDIR /api
COPY ./gradlew /api
COPY ./build.gradle /api
COPY ./settings.gradle /api
COPY ./src /api/src
COPY ./gradle /api/gradle
ENTRYPOINT ["sh", "./gradlew", "bootRun"]

Dockerfileの使い方の基礎を学びたい方は以下から、ご確認下さい。

docker-compose.ymlの作成

docker-compose.ymlは以下のような感じで。

サービスとして、以下を定義する。

  • PostgreSQLを動かすdb
  • REST APIを動かすapi

コード例は以下です。

version: "3"

services:
  db:
    image: postgres:11-alpine
    container_name: db
    ports:
      - 5433:5432
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: sample_db
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
    volumes:
      - db_data:/var/lib/postgresql/data
  api:
    build: ./
    container_name: api
    ports:
      - "8080:8080"
    environment:
      spring.datasource.url: "jdbc:postgresql://db:5432/sample_db"
    depends_on:
      - db
volumes:
  db_data: {}

ここまで出来たら、以下のコマンドを流して、環境構築が完了します。

# Dockerイメージのビルド
$ docker-compose build

# Dockerイメージの起動
$ docker-compose up -d

環境ができたらPostgreSQL上に、以下のようにsampleテーブルを作成して、適当にデータを入れて下さい!

create table public.sample ( id serial not null,
name text not null,
age int not null,
constraint sample_pkey primary key (id) );

ここまででDockerの設定が完了しました。

SpringbootにDoma2処理の実装

では、ここまでで環境設定が出来ましたので、Springbootに実装をしていきましょう。

Daoの作成

Daoには実行するSQLのインターフェースを作成します。ビルドした際に、このインターフェースの実装クラスができます。

もし、上記で記載したbuild.gradleの設定が間違えていると、implクラスが正常に出力されませんので、ご注意下さい。

package com.example.dao;

import java.util.List;
import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;
import com.example.entity.Sample;

@ConfigAutowireable
@Dao
public interface SampleDao {

  @Select
  List<Sample> selectAll();

}

SQLファイルの作成

Doma2が発行するSQLファイルを作成する必要があるため、作成する。

ポイントは以下の2点!!

  1. SQLファイルの配置場所で「resources/META-INF」以下にソースコードのDaoと同じパッケージになるように配置する。
  2. ファイル名はDaoで定義したメソッド名と同じ名前になるようにする。

抜粋すると、こんな感じ。

demo2-sample
|--src
|  |--main
|  |  |--java
|  |  |  |--com
|  |  |  |  |--example
|  |  |  |  |  |--dao
|  |  |  |  |  |  |--SampleDao.java
|  |  |--resources
|  |  |  |--META-INF
|  |  |  |  |--com
|  |  |  |  |  |--example
|  |  |  |  |  |  |--dao
|  |  |  |  |  |  |  |--SampleDao
|  |  |  |  |  |  |  |  |--selectAll.sql

設定が間違っていると、コンパイルエラーになります。

エンティティの実装

エンティティを実装します。

例なので、すごく簡単な構造です。アノテーションの設定を忘れないようご注意下さい。

package com.example.entity;

import java.io.Serializable;
import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;
import org.seasar.doma.Table;
import lombok.Getter;
import lombok.Setter;

@Entity
@Table(name = "sample")
@Getter
@Setter
public class Sample implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private long id;

  @Column(name = "name")
  private String name;

  @Column(name = "age")
  private int age;

}

サービスの実装

こちらもすごく簡単な構造で。

package com.example.service;

import java.util.List;
import com.example.entity.Sample;

public interface SampleService {

  public abstract List<Sample> findAll();
}

こちらは実装クラスです。アノテーションの設定忘れにご注意ください。

package com.example.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.dao.SampleDao;
import com.example.entity.Sample;
import com.example.service.SampleService;

@Service
public class SampleServiceImpl implements SampleService {

  @Autowired
  private SampleDao sampleDao;

  @Override
  public List<Sample> findAll() {
    return sampleDao.selectAll();
  }
}

コントローラーの実装

REST APIを作成する。

package com.example.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.entity.Sample;
import com.example.service.SampleService;

@RestController
@RequestMapping("/api/sample")
public class SampleController {

  @Autowired
  private SampleService sampleService;

  @CrossOrigin
  @RequestMapping(value = "/", method = RequestMethod.GET)
  public List<Sample> index() {
    return sampleService.findAll();
  }
}

では、動かしてみよう!

お待たせしました!ここまでで、動かす準備が整いました。

Dockerコンテナを停止している場合は、再度起動コマンドをコマンドプロンプト、またはターミナルから打ち込んで下さい。すると、DBとSpringbootが起動しますので、「http://localhost:8080/api/sample/」にアクセスして下さい。

登録したデータがJSON形式で返ってきたら成功です!

返ってこない場合は、どこか設定が間違えている可能性がありますので、もう一度、記事を見直して見て下さい!

是非とも、このパターンを覚えて色んな現場やプロジェクトで使ってみて下さい!

ここまでお読みいただき、ありがとうございました。

役に立った、面白かったと思ったら、SNSでシェアしてくれると嬉しいです。

エソラ

もし分からないことがあれば、お問い合わせTwitterにご連絡をいただけると嬉しいです。(Twitterの方が返信早いかも…)

\ 更新の励みになるので、ポチッとしてね /

エソラ

他にもスキルアップやキャリアアップの役に立つ情報が満載です。他の記事も読んで、ゆっくりしていってね!

Springboot、Doma2、Gradle、Dockerで、 SQLファイルベースのDBアクセスを実現する手順

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次