Heroku の Spring Boot アプリでテーブル接続を行う

プログラミング
この記事は約10分で読めます。
スポンサーリンク

環境

macOS Mojave 10.14.1
Eclipse (Pleiades) Oxygen.3a Release (4.7.3a)

使用するもの

  • Heroku
  • Spring Boot
  • PostgreSQL
  • Gradle
  • Lombok

事前準備

あらかじめ Java 8 をインストールしておいてください。

Heroku 登録および設定

登録

Heroku | Sign up
Sign up for a Heroku developer account and get started building your apps on Heroku.

こちらのサイトから登録をします。

CLI インストール

$ brew install heroku/brew/heroku
Getting Started on Heroku with Java | Heroku Dev Center
A step-by-step guide for deploying your first Java app and mastering the basics of Heroku

Homebrew がない場合はこちらのサイトからダウンロードしてインストールします。

PostgreSQL インストール

Postgres.app – the easiest way to get started with PostgreSQL on the Mac
Postgres.app is a full featured PostgreSQL installation packaged as a standard Mac app.

こちらのサイトを参照し、①〜③ を実施します。

データ作成

上記 ① で起動した PostgreSQL アプリから使用するデータベースをダブルクリックし、ターミナルを立ち上げます。

あらかじめ以下のようにテーブルを作成しておきます。

# select * from sample;
id | name
----+------
1 | hoge
2 | fuga
3 | piyo
(3 rows)

Spring Boot アプリケーション作成

作成方法は下記記事を参考にして頂ければ。

依存追加

build.gradle の dependencies に追加します。

dependencies {
  compile('org.springframework.boot:spring-boot-starter-data-jpa')
  compile('org.springframework.boot:spring-boot-devtools')
  compileOnly('org.projectlombok:lombok')
  runtime('org.postgresql:postgresql')
  implementation('org.springframework.boot:spring-boot-starter-web')
  testImplementation('org.springframework.boot:spring-boot-starter-test')
}

org.springframework.boot:spring-boot-devtools はホットデプロイするために使用。

データベース接続設定

src/main/resources/application.properties を作成します。

spring.datasource.url=${DATABASE_URL}
spring.datasource.driverClassName=org.postgresql.Driver

${DATABASE_URL} については環境変数から取得するようにしています。

こうすることで、Heroku にデプロイした時は Heroku 上のデータベースに接続することができるようになります。

Mac での環境変数の設定

Macでの環境変数(environment variables)の設定方法 - Qiita
対象 システムレベルでグローバルに有効にしたい環境変数の話。GUIアプリケーション上で有効にしたい、などが対象ユースケース。 ターミナルコンソール上で有効になる .bashrc や .bash_profile に export ...

こちらのサイトを参考にさせていただきました。

setenv.DATABASE_URL.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>setenv.DATABASE_URL</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/launchctl</string>
      <string>setenv</string>
      <string>DATABASE_URL</string>
      <string>jdbc:postgresql://localhost:5432/{データベース名}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceIPC</key>
    <false/>
  </dict>
</plist>

ソースファイル作成

Entity

Sample.java

package com.example.sample.domain;

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

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Entity
@Getter
@Setter
@ToString
public class Sample {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;

  private String name;
}

Lombok を使用して Getter, Setter を省略しています。

DAO

SampleRepository.java

package com.example.sample.domain;

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

public interface SampleRepository extends JpaRepository<Sample, Integer>{
}

Service

SampleService.java

package com.example.sample.service;

import java.util.List;

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

import com.example.sample.domain.Sample;
import com.example.sample.domain.SampleRepository;

@Service
@Transactional
public class SampleService {

  @Autowired
  SampleRepository sampleRepository;

  public List<Sample> selectAll() {
    return sampleRepository.findAll();
  }
}

Controller

SampleController.java

package com.example.sample.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.sample.domain.Sample;
import com.example.sample.service.SampleService;

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

  @Autowired
  SampleService sampleService;

  @RequestMapping(value = "", method = RequestMethod.GET)
  public String hello() {
    return "Hello world.";
  }

  @RequestMapping(value = "select-all", method = RequestMethod.GET)
  public List<Sample> selectAll() {
    return sampleService.selectAll();
  }
}

注意点

注意点として、パッケージ構成を上記の通りにしないと @Autowired でインジェクションができません。
(アノテーションを別途定義すればできないことはない)

Spring Bootを使って簡単なMVCのサンプルシステムを作ってみました - Qiita
はじめてのSpring Boot ものすごく出遅れ感がありますがSpring Bootを勉強し始めました。 会社では独自フレームワークやStruts2を使ったシステムがほとんどでしたが昨今騒がれている脆弱性についてやマイクロサー...

こちらのサイトを参考にさせて頂きました。

lombok インストール方法

少しハマったので書いておきます。

build.gradle に依存を入れただけだと適切に動かないので、以下の手順を実行します。

  1. Eclipse のアプリのパッケージ内を表示します。
  2. Contents/MacOS に lombok.jar を入れます。※ ファイル名注意
  3. Contents/Eclipse/eclipse.ini に下記2行を追記
-Xbootclasspath/a:lombok.jar
-javaagent:lombok.jar

ローカルで起動確認

Eclipse でプロジェクト名のコンテキストメニューを開き、Spring Boot アプリケーションで実行します。

この時、以下のようなエラーが出る場合があると思います。

Caused by: java.sql.SQLFeatureNotSupportedException: org.postgresql.jdbc.PgConnection.createClob() メソッドはまだ実装されていません。

この場合、src/main/resources/hibernate.properties を作成し、以下を記載します。

hibernate.jdbc.lob.non_contextual_creation=true

画面確認

404 Not Found

上記 URL にアクセスし、 sample テーブルにインサートした内容が JSON で表示されていれば OK です。

Heroku 側の起動確認

以下、ターミナルでの作業です。

Git コミット

git init
git add .
git commit -m "commit message"

Heroku にデプロイ

heroku login
heroku create
git push heroku master
heroku open

この状態で、【ドメイン】/sample にアクセスすると Hello world. が表示されます。

Heroku の DB 設定

PostgreSQL のアドオンを追加

heroku addons:create heroku-postgresql

Heroku の PostgreSQL に接続

heroku pg:psql

ローカルのテーブルと同様に作成します。

この状態で、【ドメイン】/sample/select-all にアクセスするとテーブルの内容が JSON で表示されます。

2回目以降のデプロイ

git add .
git commit -m "commit message"
git push heroku master
heroku open

コメント

タイトルとURLをコピーしました