前回はSpring JDBCを使ったので、今回はSpring DATA JPAを使ってDBを操作します。
環境
クライアント側
OS: macOS Big Sur バージョン11.1
STS: Spring Tool Suite 4 Version: 4.9.0.RELEASE
DBサーバー側
OS: Amazon Linux
DB: mariaDB Ver 15.1
DB環境構築の参考サイト
・AWSのEC2でmariaDBを使う方法
・CentOS7にMariaDBをインストールして外部ホストから接続する方法
・Macのhomebrewでmysqlクライアントのみインストールする
参考ライブラリ
mvnrepository
前提
・STSでHelloWorldを出せる。
・DB環境が構築が完了してる(ローカルでも可)。
・lombokが使える状態。(lombokインストール)
Spring DATA JPAとは
JavaEE標準のORM(オブジェクト・リレーショナル・マッピング)によって、SQLを自動生成して実行してくれるライブラリです。
事前に作成したテーブル
事前にサンプル用ユーザーテーブルを作成しておく。
mysql> use sampledb;
Database changed
--テーブル作成時、user_idに自動連番の設定をしていない場合は以下を実行
mysql> alter table users change user_id user_id int(11) auto_increment;
mysql> show fields from users;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| user_id | int(11) | NO | PRI | NULL | auto_increment |
| password | varchar(10) | YES | | NULL | |
| user_name | varchar(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| role | varchar(10) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
5 rows in set (0.18 sec)
mysql> select * from users;
+---------+----------+-----------+------+---------+
| user_id | password | user_name | age | role |
+---------+----------+-----------+------+---------+
| 1 | 1pass | Benimaru | 24 | admin |
| 2 | 2pass | Senku | 17 | general |
| 3 | 3pass | Garp | 60 | general |
+---------+----------+-----------+------+---------+
3 rows in set (0.17 sec)
application.properties
application.propertiesにDBの設定を入れます。
spring.datasource.url=jdbc:mysql://(接続先IPアドレス):3306/sampledb
spring.datasource.username=testuser
spring.datasource.password=password
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
pom.xml
pom.xmlに使用するDBとjpaのライブラリを追加後、Mavenを更新する。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
プロジェクト構成
MyApp2プロジェクトソースはここ
下のような感じで、パッケージを作成する。
controller・・・ここにユーザーリクエストを受け付けるRESTコントローラークラスを作成。
entity・・ユーザーテーブルと対応したデータクラスを作成。
repository・・・DB操作をするインターフェースを作成。
エンティティ作成
usersテーブルと対応するデータクラスを作成する。
jpa関連のアノテーション
@Entity・・・テーブルとマッピングしたいオブジェクトにつける。
@Table・・・マッピングするテーブル名を指定。
@JsonIgnoreProperties・・・これが無いとjsonでレスポンスを返す際にエラーが発生する。(参考)
@Id・・・主キーにつける。
@GeneratedValue・・・DBで連番が設定されている時はこれを使う。
@Column・・・列であることを示す。
package com.r_saiki.springboot.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Entity
@Table(name = "users")
@Data
@JsonIgnoreProperties({"hibernateLazyInitializer"})
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int userId; // ユーザーID
@Column
private String password; // パスワード
@Column
private String userName; // ユーザー名
@Column
private int age; // 年齢
@Column
private String role; // ロール
}
リポジトリー作成
上記で作成したUserクラスと主キーのデータ型を、JpaRepositoryの型に指定し継承するだけで、基本的なDBアクセス機能が提供される。
package com.r_saiki.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.r_saiki.springboot.entity.User;
public interface UserRepository extends JpaRepository<User, Integer> {
}
コントローラー作成
@Autowiredにより、自動でUserRepositoryのオブジェクトが生成される。
jpa関連メソッド
findAll・・・全件取得。
getOne・・・引数で指定した主キーからデータを取得。
save・・・引数で渡したオブジェクトを保存する。存在する主キーを指定すると更新処理になる。
deleteById・・・引数で指定した主キーからデータを削除。
package com.r_saiki.springboot.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.r_saiki.springboot.entity.User;
import com.r_saiki.springboot.repository.UserRepository;
@RestController
public class UserController {
@Autowired
UserRepository repository;
// 全件取得用メソッド
@GetMapping("/user/showUserList")
@ResponseBody
public List<User> showUserList() {
return repository.findAll();
}
// 1件取得用メソッド
@GetMapping("/user/{id:[0-9]+}")
@ResponseBody
public User showUser(@PathVariable("id") int userId) {
return repository.getOne(userId);
}
// 1件追加用メソッド
@PostMapping("/user/insertOne")
public String insertOne(@RequestBody User user) {
repository.save(user);
return "一件追加しました!";
}
// 1件更新メソッド
@PostMapping("/user/updateOne")
public String updateOne(@RequestBody User user) {
repository.save(user);
return "一件更新しました!";
}
// 1件削除メソッド
@PostMapping("/user/deleteOne/{id:.+}")
public String deleteOne(@PathVariable("id") int userId) {
repository.deleteById(userId);
return "一件削除しました!";
}
}
実行結果
Spring Boot実行後、curlコマンドで実行結果を確認する。
全件取得
$ curl http://localhost:8080/user/showUserList
[{"userId":1,"password":"1pass","userName":"Benimaru","age":24,"role":"admin"},
{"userId":2,"password":"2pass","userName":"Senku","age":17,"role":"general"},
{"userId":3,"password":"3pass","userName":"Garp","age":60,"role":"general"}]
1件取得
userIdが2のデータが取得する。
$ curl http://localhost:8080/user/2
{"userId":2,"password":"2pass","userName":"Senku","age":17,"role":"general"}
1件追加
userIdは自動連番で取得されるため省略。
$ curl -X POST -H 'Content-Type: application/json' http://localhost:8080/user/insertOne -d '{"password":"InsertPass","userName":"Maki","age":17,"role":"general"}'
一件追加しました!
$ curl http://localhost:8080/user/showUserList
[{"userId":1,"password":"1pass","userName":"Benimaru","age":24,"role":"admin"},
{"userId":2,"password":"2pass","userName":"Senku","age":17,"role":"general"},
{"userId":3,"password":"3pass","userName":"Garp","age":60,"role":"general"},
{"userId":6,"password":"InsertPass","userName":"Maki","age":17,"role":"general"}]
1件更新
userIdが6のデータを更新。
$ curl -X POST -H 'Content-Type: application/json' ht0/user/updateOne -d '{"userId":6,"password":"UpdPass","userName":"Yuzuriha","age":88,"role":"general"}'
一件更新しました!
$ curl http://localhost:8080/user/showUserList
[{"userId":1,"password":"1pass","userName":"Benimaru","age":24,"role":"admin"},
{"userId":2,"password":"2pass","userName":"Senku","age":17,"role":"general"},
{"userId":3,"password":"3pass","userName":"Garp","age":60,"role":"general"},
{"userId":6,"password":"UpdPass","userName":"Yuzuriha","age":88,"role":"general"}]
1件削除
userIdが6のデータを削除。
$ curl -X POST http://localhost:8080/user/deleteOne/6
一件削除しました!
$ curl http://localhost:8080/user/showUserList
[{"userId":1,"password":"1pass","userName":"Benimaru","age":24,"role":"admin"},
{"userId":2,"password":"2pass","userName":"Senku","age":17,"role":"general"},
{"userId":3,"password":"3pass","userName":"Garp","age":60,"role":"general"}]
終わりに
Spring DATA JPAでのDB接続は桁違いに楽でした!
SQLをどうしても使わないといけない理由がない限り、JavaのDBアクセスはJPA一択ではと思うくらいです^^
参考
@GeneratedValueを使って主キーを生成する方法
SpringBoot + Spring JPAでデータベースに接続する
Spring Boot + JpaRepositoryを利用してRESTful のAPIを作成
Spring Data JPA で hibernateLazyInitializer を Jackson が JSON シリアライズできなくてエラーになる