Spring BootでJdbcTemplateを使ってデータベースに接続

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

はじめに

先日の記事ではSQLを書かずにSQLを実行できるJPAを紹介しましたが、今回はSQLを書いて接続してみます。
初心者にはこちらの方が分かりやすいと思います。

環境

Mac OSC 10.10.5 Yosemite
PostgreSQL 9.5.1
Java 8
Spring Boot 1.3.5

目標

これを作ります。

postgres=# select * from test;
 id | title | sub 
----+-------+-----
  1 | AAA   | aaa
  2 | BBB   | bbb
  3 | CCC   | ccc
(3 rows)

コード

build.gradle

今回の依存関係です。

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

application.yml

src/main/resources/configに配置してください。

spring:
  datasource:
    url:  jdbc:postgresql://localhost/データベース名
    username: ユーザー名
    password: パスワード
    driverClassName: org.postgresql.Driver

SpringBootJdbcApplication

SpringBootを起動するクラス。

package com.jdbc.spring;

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

@SpringBootApplication
public class SpringBootJdbcApplication {

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

SqlExecute

SQLを実行するクラス。

package com.jdbc.spring;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration
public class SqlExecute {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Bean
	public String create() {
		jdbc.execute("DROP TABLE IF EXISTS test");
		jdbc.execute("CREATE TABLE test (id SERIAL NOT NULL, title VARCHAR(20), sub VARCHAR(20), PRIMARY KEY(id))");

		return null;
	}
	
	@Bean
	public String insert() {
		String[][] data = {{"AAA","aaa"},{"BBB","bbb"},{"CCC","ccc"}};

		for (int i=0; i<data.length; i++) {
			jdbc.update("INSERT INTO test (title, sub) VALUES (?, ?)", data[i][0], data[i][1]);
		}

		return null;
	}

}

14-15行目:実行に必要なJdbcTemplateを@Autowiredeで接続。
これを使ってCRUDを実現します。
jdbc.executeで、CREATE・DROP
jdbc.updateで、INSERT・UPDATE・DELETE
を扱えます。

メソッド:create()
19行目:同名のテーブルが有れば削除。
20行目:テーブル作成。

メソッド:insert()
27行目:INSERTする値を作成。
29-31行目:forループでINSERT。
INSERT、UPDATE、DELETEはJdbcTemplate.update()を使用します。
Prepared Statementを介しているそうなので、「?」に値を適用できます。
第2引数以降は、「?」に適用する値を記述します。

11行目でクラスに@Configurationとアノテートしているので、
17行目と25行目の@Beanが読まれ、メソッドcreate()、insert()が順に自動的に実行されます。

実行すると目標のテーブルができるはずです。

SELECTする場合

こんな感じにします。

List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM test");
list.forEach(System.out::println);
{id=1, title=AAA, sub=aaa}
{id=2, title=BBB, sub=bbb}
{id=3, title=CCC, sub=ccc}

queryForLIstでSELECTの結果が返ってくるので、Listに入れます。
Java8ならforEachで簡単に全てのコレクションを書き出せます。

コレクションから個別に値を取得したいなら、

String str = list.get(2).get("title").toString();
System.out.println(str);
CCC

ListがMapになっているので、String(カラム名=Object Key)とObject(値)を使って取り出せます。

さいごに

JPAを使用する場合に比べてだいぶ簡単ですね。
ちなみに、@Beanでアノテートされたメソッドは戻り値を設定しないとエラーになるみたいです。
voidにしてもコンパイルできますが、

needs to have a non-void return type!

と表示されエラーになります。