データベースをプログラムで操作してみた

## はじめに
今回の内容は、データベースを操作するプログラムの作成方法についてです。
前提条件は以下の通りです。
|Windows10 64bit|
|---|
|Java 20.0.2|

## 作成の前に
プロジェクト作成の前に、用語説明をします。
理解できている方は、飛ばして先に進んでください。
また、以前に私が書いた記事で説明している用語に関しては、説明を省きます。
以下に記事を載せておきます。

https://qiita.com/ren_g/items/e34de896b8e15818f901

それでは、説明していきます。

* H2 Database
H2 Databaseは、Javaプラットフォーム上で動作するデータベースのことです。今回作成するようなデータベースを必要とするプログラムを作成する際は便利です。
* JPA
Java Persistence APIの略で、データの永続化を可能にしてくれる機能を提供してくれます。今回、プロジェクト作成の際に依存関係で設定するSpring Data JPAはフレームワークの一種で、JPAをSpring bootで使いやすくしたものです。
* エンティティ
JPA(Jakarta)を利用する場合、データベースのデータとなる部分は、エンティティクラスを定義することが必要なので、エンティティについても説明します。
データベースにおいて、エンティティは、実体を意味しており、エンティティの特徴としては、属性、識別子、関係性を持っています。
以下のコードだと、「User」というクラスが定義されており、名前、idという属性を持っています。
```
package com.example.demo;

public class User {
	private int id;
	private String name;
}
```
エンティティは、このようにそれぞれ固有の属性をもっているので、他のエンティティと関連付ければ、複雑なプログラムを作成することができます。

* getter
setterでセットしたフィールドの値をゲットし、returnで値を返すメソッドのことです。
* setter
フィールドに値をセットするためのメソッドのことです。
## プログラム作成
この記事のメインであるプログラム作成から実行までの説明をしていきます。
まず、新しくプロジェクトを作成するので、その手順です。
### プロジェクト作成
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/1da90b9a-b1e5-550f-f805-59bd0ce4d161.png">
「新規」から、「Springスタータープロジェクト」を選択します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/aa4103e2-012c-40a0-d905-a6db7ae390b8.png">

プロジェクト作成画面では、名前をdemo_databaseに設定して、依存関係を設定する画面に進みます。
ここでは、Spring Boot DevTools、Spring Data JPA、H2 Database、Thymeleaf、Spring Webを選択してください。
選択後、完了を押します。


### pom.xmlの編集
次に、データベースを使用するために、pom.xmlに以下のライブラリを追加します。
ここで注意なのですがSpringbootのバージョンよる影響でjavaxが使用できない可能性があります。（私がそうでした。）ですので、JPAの設定は追加せずに、以下のように、jakartaの設定を加えます。
```
        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
        <dependency>
			<groupId>jakarta.persistence</groupId>
			<artifactId>jakarta.persistence-api</artifactId>
			<version>3.1.0</version>
		</dependency>
        <dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
```
JPAがそのまま使用できる方は、以下のコードをjakartaの設定の代わりに入力するようにしてください。
```
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
```
### DemoApplicaition.javaの編集
以下のコードを入力するのみです。
```
package com.example.demo_database;

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

@SpringBootApplication
public class DemoDetabaseApplication {

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

}
```
### エンティティクラスの作成

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/260abbb2-2e87-6709-6e9a-073c4131ed1c.png">

作成したプロジェクトを右クリックして、「新規」から、「クラス」を選択します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/388e0f18-6fa8-37d1-ad50-d7445d9815e4.png">

この画面になるので、以下のように入力します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/2b999f78-baed-cf65-363e-48167f47f6f9.png">

赤枠に「User」と入力して、「完了」を押します。
そして、作成したUser.javaを以下のように編集します。

```
package com.example.demo_database;

public class User {
	private int id;
	private String name;
}
```
次に、User.javaを開いたまま、以下の操作を行います。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/7ac403b1-4f57-9041-b712-643b3288e091.png">

上のメニューから、ソースを選択し、getterおよび、setterの生成を押します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/5f3c0249-fcb0-3b18-ab6c-6bbbf0028ade.png">

そして、次に表示される画面で、「id」と「name」にチェックを入れ、挿入ポイントを「最後のメンバー」にします。そしたら「生成」を押してください。

```
package com.example.demo_database;

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


@Entity
@Table(name="\"user\"")


public class User {
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column
	private int id;
	@Column
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
```
setterとgetterが生成されたことを確認して、上記のコードと同じになるように、編集してください。
また、先ほどのpom.xmlをJPAで設定した方は、jakartaとコードに書いてあるところをjavaxに変更してください。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/7896aa4b-0bac-51bd-6a31-5a734d96f9cf.png">

### リポジトリの作成
プロジェクトの上で右クリックして「新規」から、「インターフェース」を選択します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/01c3a106-fb34-bfa0-55e2-1cd5a33a4de9.png">
名前にUserRepositoryと入力し、「完了」を押します。

```
package com.example.demo_database;


import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long>{

}
```
UserRepository.javaに上記のコードを入力します。

### コントローラの作成
プロジェクトの上で右クリックして、先ほどのように「新規」＞「クラス」と進み、名前をDemoControllerにします。
そして、DemoController.javaに下記のコードを入力します。
```
package com.example.demo_database;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.ModelAndView;

import jakarta.annotation.PostConstruct;

@Controller
public class DemoController {

    @Autowired
    UserRepository repos;
    
    @RequestMapping(value="/", method=RequestMethod.GET)
    public ModelAndView index(
            @ModelAttribute("formModel") User user,
            ModelAndView mav) {
        mav.setViewName("index");
        Iterable<User> list = repos.findAll();
        mav.addObject("data", list);
        return mav;
    }

    @RequestMapping(value="/", method=RequestMethod.POST)
    @Transactional(readOnly=false)
    public ModelAndView form(
            @ModelAttribute("formModel") User user,
            ModelAndView mav) {
        repos.saveAndFlush(user);
        return new ModelAndView("redirect:/");
    }
    
    @PostConstruct
    public void init() {
        User user1 = new User();
        user1.setName("島根　花子");
        repos.saveAndFlush(user1);

        user1 = new User();
        user1.setName("大阪　太郎");
        repos.saveAndFlush(user1);
    }
}
```
### ビューの作成
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/c9004721-c090-a51b-0b50-134085bec5e2.png">

プロジェクトの上で右クリック＞「新規」＞「ファイル」を選択、

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/13dd034b-4632-fc20-3893-aef8f552d2e3.png">

ファイル名にindex.htmlと入力し、「完了」と押す。
以下のコードを入力します。

```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo Page</title>
<style>
table {
  border-collapse: collapse;
}
</style>
</head>
<body>
<h1>Hello Page</h1>
<table border="1">
  <form method="post" action="/" th:object="${formModel}">
  <tr>
    <td><label for="name">名前</label></td>
    <td><input type="text" name="name" th:value="*{name}" /></td>
  </tr>
  <tr>
    <td></td>
    <td><input type="submit" /></td>
  </tr>
  </form>
</table>
<hr/>
<table border="1">
  <tr>
    <th>ID</th><th>名前</th>
  </tr>
  <tr th:each="obj : ${data}">
    <td th:text="${obj.id}"></td>
    <td th:text="${obj.name}"></td>
  </tr>
</table>
</body>
</html>
```

### 実行
プロジェクトを選択して、「実行」した後にhttp://localhost:8080と検索します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/e11b87c9-a181-2682-fe60-dc9322988e41.png">

上記のように表示されます。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/8fb918bb-1bf9-f79d-6ecd-eec83a47c527.png">

名前に入力して、送信を押し、更新されたWebページに入力した名前と、idが自動的に表に追加されていれば成功です。

お疲れさまでした。
## 参考記事

https://www.sys-link.jp/technical/SpringBoot/SpringBoot3-1.html