Spring Bootでデータベースに接続

2016.06.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

前回はSpring Bootの導入を行い、簡単に実行してみました。
今回はもっと進めて、ローカルのデータベースに接続してみます。

環境

OS : Mac OSX 10.10.5
DB : Postgres 9.5.1

プロジェクト作成

db_jpa_start

JPAとPostgreSQLにチェックを入れます。
JPAはSQLを書かずにCRUDができるので便利です。

準備

データベース、テーブルの用意

まず、PostgreSQLでデータベースとテーブルを作成しておきます。

CREATE DATABASE sbdb;

CREATE TABLE counter1 (
id SERIAL PRIMARY KEY
, title VARCHAR(16)
, count INT);

INSERT INTO counter1 VALUES
 (0,'all',0)
 , (1,'select',0)
 , (2,'update',0)
 , (3,'delete',0);
sbdb=# select * from counter1 ;
 id | title  | count 
----+--------+-------
  0 | all    |     0
  1 | select |     0
  2 | update |     0
  3 | delete |     0
(4 rows)

設定ファイル

build.gradle

buildscript {
	ext {
		springBootVersion = '1.3.5.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot' 

jar {
	baseName = 'demo'
	version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
	mavenCentral()
}


dependencies {
	compile('org.springframework.boot:spring-boot-starter-web')
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	runtime('org.postgresql:postgresql')
	testCompile('org.springframework.boot:spring-boot-starter-test') 
}


eclipse {
	classpath {
		 containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
		 containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
	}
}

依存関係にJPAとPostgreSQLが追加されています。

application.xml

spring:
  datasource:
    url:  jdbc:postgresql://localhost/sbdb
    username: XXXX
    password: XXXX
    driverClassName: org.postgresql.Driver

src/main/resourcesの下に、Folder「config」を作成してFile「application.yml」を作成します。
ここにデータベースの接続情報を書き込みます。

コード

DBApplication

ここから始まります。

package com.pstgrs.jpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DBApplication {

	public static void main(String[] args) {
		SpringApplication.run(DBApplication.class, args);
	}
	
}

6行目、@SpringBootApplicationで、SpringBoot設定の自動化します。楽です。
10行目で起動です。

Counter

Entityクラスです。
データベースのカラムを設定します。

package com.pstgrs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="counter1")
public class Counter {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="title")
	private String title;

	@Column(name="count")
	private int count;
	
	// getter, setter
	public Integer getID() {return id;}
	public void setId(Integer no) {this.id = no;}
	public String getTitle() {return title;}
	public void setTitle(String title) {this.title = title;}
	public int getCount() {return count;}
	public void setCount(int count) {this.count = count;}
	
}

10行目、@EntityでJPAに管理してもらいます。
11行目、@Tableで接続するテーブルを指定。
14行目、@Idで変数idをプライマリーキーに指定。
15行目、@GeneratedValueで値を指定しなくても自動生成する様に設定。
18〜22行目、その他カラムの設定。

getterとsetterはlombokでも良いですね。

CounterRepository

package com.pstgrs.jpa;

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

public interface CounterRepository extends JpaRepository<Counter, Integer> {
}

このリポジトリでJPAを継承すれば、SQLを書かずに済みます。

CounterService

package com.pstgrs.jpa;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class CounterService {

	@Autowired
	CounterRepository repository;
	
	public List<Counter> selectAll() {
		return repository.findAll(new Sort(Sort.Direction.ASC, "id"));
	}
	
}

10行目、サービスに設定。
11行目、トランザクション設定。
14〜15行目、@Autowiredでリポジトリを繋げ、後述のCounterクラスで使用する実行内容を作っていきます。

18行目、repository.findAll()で、
SELECT * FROM counter1;
と同じ意味になりますが、Sort.Direction.ASCで、"id"を昇順と指定しているので、
SELECT * FROM counter1 ORDER BY id;
と同じ意味になります。

Controller

package com.pstgrs.jpa;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/counter")
public class Controller {
	
	@Autowired
	CounterService service;
	
	// 一覧表示
	@RequestMapping(value="/selectall", method=RequestMethod.GET)
	public List<Counter> counterSelectAll() {
		return service.selectAll();	
	}

}

14行目、@RequestMapping("/counter")とすると、http://localhost:8080/counter で繋がります。

17〜18行目、サービスに繋げます。

21行目、counterSelectAll()の@RequestMappingでは、
value="/selectall", method=RequestMethod.GETと設定しているので、
http://localhost:8080/counter/selectall で繋がります。

コマンドラインから実行

作ったアプリを起動してからコマンド実行で確認します。

$ curl http://localhost:8080/counter/selectall
[{"id":0,"title":"all","count":0},{"id":1,"title":"select","count":0},{"id":2,"title":"update","count":0},{"id":3,"title":"delete","count":0}]ip-172-18-0-147:~ cm$

JSONで帰って来ました。

さいごに

アノテーションが多いので最初は戸惑いますが、段々と見慣れてくると思います。
サービスについては、リポジトリからコントローラーに直接接続できるようですが、使用した方がより本格的の様です。