ローカルにPostgreSQLをインストールしてMyBatisで操作する手順

## はじめに
Windows 11にPostgreSQLをインストールし、MyBatisを使ってデータベース操作を行います。
MyBatisを導入してデータ取得することをゴールとして手順をまとめてみました。

## 環境
windows11
Java 21
Spring Boot 3.4.1
Maven 3.9.9
Thymeleaf 3.1.3
下記記事を参考にしていただければ同じ環境を構築できると思います。

https://qiita.com/uniuni108/items/1362a9bf21faf6b0bbd3


## インストール
まずはここからインストールします。
バージョンは現時点で最新の17.2とします。
https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

![postgresqlインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/d7714831-6323-2a57-c4f8-3b4578fdbbd2.png)

インストーラーを実行します。
基本的に何も変更しないためキャプチャは一部だけ載せておきます。
LocaleのみCに変更しています。
![setup2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/263b3ed7-da79-532b-dfd2-add474a1974f.png)

![setup4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/1db86750-0ec0-5295-24c8-399a0f1189d1.png)

![setup5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/80c4318b-dc34-fc50-b319-07b3da1f0820.png)

インストールはここまでで完了です。

## DB
PostgreSQLのインストールが完了したので、ここから新規DB、テーブル、ユーザーを作っていきます。
今回はPostgreSQL用のGUIツールであるpgAdmin4を使います。
pgAdmin4がインストールされていない場合はこちらから

https://www.pgadmin.org/download/pgadmin-4-windows/

最初に動作確認用のユーザーとデータベースを作成します。
ユーザー名：test
(権限は下記画像のように設定しましたが、Create databasesは無しで問題ないはずです)
![user1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/525b522a-9cd6-be85-2d13-0c6812ba6b9c.png)

![user2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/b4b7271a-4eda-7e07-baa7-2fc5b4782259.png)

DBのOwnerは作成したユーザーに変更しておきます。
デフォルト設定値のままだと後続の処理で権限エラーが発生します。
![db1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/344db2c8-91bf-9ee8-3ac5-07bac6eb31fa.png)


ここまでpostgresユーザーでログインしていましたが、作成したユーザーに切り替えてテーブルを作成し適当なデータを入れておきます。

```sql
CREATE TABLE test_table (
    id SERIAL PRIMARY KEY,
    comment VARCHAR(255)
);
```

```sql
INSERT INTO test_table (comment) 
VALUES ('データ1です'), 
       ('データ2です'), 
       ('データ3です');
```
![db1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/65a3b186-cbd8-feaf-4caa-85fe108dd72f.png)

これでデータ投入まで完了しました。
続いてMyBatisを導入していきます。

## MyBatis
データベース接続とMyBatisの設定です。
* pom.xml
```xml
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.7.4</version>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.4</version>
</dependency>
```
* application.properties
「org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
動作確認した際にこのようなエラーが発生する場合は、mybatis.mapper-locationsの設定値が正しいか確認しましょう。
```properties
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
mybatis.mapper-locations=classpath:/mapper/*.xml
```
ここから実際にデータを取ってくる処理を記述していきます。
* TestMapper.xml
idにgetAllDataを指定し、先ほど作成したテーブルからデータを全件取得する処理を記述します。
xmlファイルはsrc/main/resources配下にmapperフォルダを作成しその下に配置しました。
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//MyBatis//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo.mapper.TestMapper">
    <select id="getAllData" resultType="com.example.demo.model.Test">
        SELECT *
        FROM test_table
    </select>
</mapper>
```
* TestMapper.java
Mapperはsrc/main/java/com/example/demo/mapperに配置しています。
```java
package com.example.demo.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.example.demo.model.Test;

@Mapper
public interface TestMapper {
	List<Test> getAllData();
}
```
* Test.java
```java
package com.example.demo.model;

public class Test {
	
	private int id;
    private String comment;

    public int getId() {
        return id;
    }

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

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }
}
```

Mapperを呼び出すserviceクラスを作ります。
* TestService.java
```java
package com.example.demo.service;

import java.util.List;
import com.example.demo.model.Test;

public interface TestService {	
	public List<Test> getAllData();
}
```
* TestServiceImpl.java
```java
package com.example.demo.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.mapper.TestMapper;
import com.example.demo.model.Test;
import com.example.demo.service.TestService;

@Service
public class TestServiceImpl implements TestService {

	@Autowired
    TestMapper testMapper;

    @Override
    public List<Test> getAllData() {

        return testMapper.getAllData();
    }

}
```

* DemoController.java
TestServiceを呼び出し、データを取得します。
```java
package com.example.demo.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.demo.model.Test;
import com.example.demo.service.TestService;

@Controller
public class DemoController {
	
	@Autowired
	private TestService testService;
	
	@GetMapping("/demo")
    public String demo(Model model) {
		List<Test> result = testService.getAllData();
		model.addAttribute("result", result);
        return "demo/demo";
    }
}
```

* demo.html
動作確認用に取得結果を表示します。
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>確認</h1>
	<table border="1">
	    <thead>
	        <tr>
	            <th>ID</th>
	            <th>コメント</th>
	        </tr>
	    </thead>
	    <tbody>
	        <tr th:each="data : ${result}">
	            <td th:text="${data.id}"></td>
	            <td th:text="${data.comment}"></td>
	        </tr>
	    </tbody>
	</table>
</body>
</html>
```
実行してみます。
    →事前に投入していたデータが確認できました
![画面1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967914/961aeef7-a9d4-1a5c-6976-5065eef7f5eb.png)

## あとがき
最後まで読んでいただきありがとうございます。
少しでも参考になれば幸いです。
次回はMyBatisでMapperを自動生成する方法をまとめてみます。