あるSEのつぶやき・改

ITやシステム開発などの技術に関する話題を、取り上げたりしています。

Spring Boot入門:MySQLにSpring Boot アプリケーションからアクセスする

はじめに

この記事は「Getting Started:Accessing data with MySQL」から、実際に動作させてみたことを記録したものになります。

Getting Start 通りだと、一部でエラーが発生するのでその点も記載します。

Spring Boot アプリケーションを作成することから始めます。

作業環境は、以下の通りです。

  • Java 1.8 以降
  • MySQL 5.6 以降
  • Docker
  • IntelliJ IDEA Community Edition

IntelliJ IDEA Community Edition のダウンロードとインストールは、下記記事を参考にしてください。

www.aruse.net

Docker は下記サイトからダウンロードできます(アカウントの作成が必要)。

hub.docker.com

Spring Boot のプロジェクト作成

IntelliJ IDEA Community Edition は無償で商用利用も可能な IDE ですが、Spring Boot のプロジェクトを作成できません。

ですので、以下の Spring Initializr というサイトで Spring Boot のプロジェクトを作成します。

基本的にデフォルトなのですが、Dependencies に いくつか追加しています。

項目 設定値 備考
Project Maven Project デフォルト
Language Java デフォルト
Spring Boot 2.1.6 デフォルト
Project Meta (Group) com.example デフォルト
(Artifact) demo デフォルト
options デフォルト
Dependencies Spring Web Starter 追加
Spring Data JPA 追加
MySQL Driver 追加

設定ができたら、[Generate the project] をクリックして、自動生成される demo.zip をダウンロードします。

解凍して作成された demo フォルダを IntelliJ IDEA Community Edition で開いたら、Spring Boot のプロジェクト作成は完了です。

MySQL の Docker コンテナ作成

MySQL の Docker コンテナは以下のコマンドで作成します。

$ docker pull mysql   #MySQLのDockerイメージの取得
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql #コンテナの起動

データベースの作成

Docker コンテナのログインし、MySQL コマンドでデータベースを作成します。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
81072f8433c0        mysql               "docker-entrypoint.s…"   3 hours ago         Up 3 hours          0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

$ docker exec -it 81072f8433c0 bash  # Docker コンテナ内部にログイン
root@81072f8433c0:/# mysql -u root -p  #パスワードは mysql

mysql> create database db_example; -- Create the new database
mysql> create user 'springuser'@'%' identified by 'ThePassword'; -- Creates the user
mysql> grant all on db_example.* to 'springuser'@'%'; -- Gives all the privileges to the new user on the newly created database
mysql> quit

root@81072f8433c0:/# exit

MySQL への接続設定を行う

src/main/resources/application.propertiesファイルに、MySQL の接続設定設定を行います。

ここで注意して欲しいのですが、以下の Getting Start の通りに指定すると Spring Boot 起動エラーが発生して悩みまくります。

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword

Spring Boot の起動エラーは以下のようになります。

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
    If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
    If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).


Process finished with exit code 1

application.propertiesファイルの正しい設定は以下のようになります。最後の1行が足りませんでした。

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

なお、spring.jpa.hibernate.ddl-autoupdateとなっていますが、テーブルの作成が済んだらnoneに変更します。

@Entity モデルクラスの作成

@Entity モデルクラスは、テーブルを自動作成するクラスになります。

package com.example.demo;

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

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

リポジトリの作成

package com.example.demo;

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Integer> {

}

コントローラーの作成

@AutoWired アノテーションの部分に、UserRepository のインスタンスがインジェクションされます。

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(path="/demo")
public class MainController {

    @Autowired
    private UserRepository userRepository;

    @PostMapping(path="/add")
    public @ResponseBody String addNewUser(@RequestParam String name, @RequestParam String email) {
        User n = new User();
        n.setName(name);
        n.setEmail(email);
        userRepository.save(n);
        return "Saved";
    }

    @GetMapping(path = "/all")
    public @ResponseBody Iterable<User> getAllUsers() {
        return userRepository.findAll();
    }
}

動作確認

curl コマンドを使用して動作確認を行います。

$ curl localhost:8080/demo/add -d name=First -d email=someemail@someemailpr
Saved

想定通りのレスポンスが返ってきました。

$ curl 'localhost:8080/demo/all'
[{"id":1,"name":"First","email":"someemail@someemailpr"}]

こちらも想定通りです。

ここで、MySQL にログインして内容を確認してみます。

mysql> use db_example
Database changed
mysql> show tables;
+----------------------+
| Tables_in_db_example |
+----------------------+
| hibernate_sequence   |
| user                 |
+----------------------+
2 rows in set (0.01 sec)

mysql> select * from user;
+----+-----------------------+-------+
| id | email                 | name  |
+----+-----------------------+-------+
|  1 | someemail@someemailpr | First |
+----+-----------------------+-------+
1 row in set (0.01 sec)

テーブルとデータが正しく作成されていますね。

なお、Getting Start では、現在の設定はセキュリティ的に問題があるので、権限の上限を下げる設定を行っています。詳しくは原文にあたってください。

おわりに

思いの外手こずってしまいましたが、なんとか MySQL の Getting Start のこなすことができました。

前の記事と合わせて、少しずつですが Spring Boot の理解が進みました。

www.aruse.net