【Spring Boot + Angular + MySQLでWebアプリ作成】 SpringBoot編②

前回はプロジェクトの作成、実行まで行いました。
ここではSpring Bootの各機能を使ってデータベースからデータを取得し表示まで行います。

## Dao、Entity、Service、Controllerの役割
###Dao
DBアクセスを担当します。

###Entity
Daoから取得したデータを格納します。
データベースのテーブルと紐づきます。

###Service
Daoを呼び出します。


###Controller
リクエストが来るところ。
Serviceを呼びだします。



##アプリケーションフォルダ構成

最終的に以下のフォルダ構成となります。


```
main
  ├─java
  │  └─com
  │      └─example
  │          └─demo
  │              │  DemoApplication.java
  │              │
  │              ├─controller
  │              │      HomeController.java
  │              │
  │              ├─dao
  │              │      EmployeeDao.java
  │              │
  │              ├─dto
  │              │      HomeInitResultDto.java
  │              │
  │              ├─entity
  │              │      Employee.java
  │              │      Department.java
  │              │
  │              └─service
  │                      EmployeeService.java
  │
  └─resources
      │  application.properties
      │
      ├─META-INF
      │  └─com
      │      └─example
      │          └─demo
      │              └─dao
      │                  └─EmployeeDao
      │                          selectAll.sql
      │
      ├─static
      └─templates
```




##Entity作成

Entityを作成します。

```java:Employee.java
package com.example.demo.entity;

import org.seasar.doma.Entity;

@Entity
public class Employee {

	public Integer id;
	public String name;
	public Integer department_id;
	public Date birthday;
}
```

```java:Department.java
package com.example.demo.entity;

import org.seasar.doma.Entity;

@Entity
public class Department {

	public Integer id;
	public String name;
}
```

##DAOインタフェース作成
interfaceであることに注意します。

はじめに部署テーブルに対してアクセスを行うDepartmentDaoから作成します。

```java:DerartmentDao.java
package com.example.demo.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

import com.example.demo.entity.Department;

@ConfigAutowireable
@Dao
public interface DepartmentDao {

	@Select
	List<Department> selectAll();

}
```

次に、selectAll()メソッドで右クリック→Doma→Jump to SqlFileを選択します。



```sql:selectAll.sql
SELECT 
	*
FROM
	DEPARTMENT;
```

これでselectAll()メソッドが呼ばれた際に、対応するselectAll.sqlが実行され、結果はDepartmentのEntityとして帰ってきます。



次は社員テーブルに対するアクセスを行う、EmployeeDaoを作成します。
今回は単純に社員テーブルの一覧を取得するのではなく、社員テーブルと部署テーブルを結合し、部署名も取り出してみます。
となると、上記の部署テーブルの一覧取得のように戻り値にDepartmentのEntityを指定することはできません。

Doma2の公式には

>エンティティクラスを利用する場合、エンティティクラスは 検索結果に応じて 作成する必要があります。
>たとえば、EMPLOYEEテーブルに対応するEmployeeエンティティクラスが定義されている場合、 EMPLOYEEテーブルのカラムを含む結果セットはEmployeeエンティティクラスで受けられますが、 EMPLOYEEテーブルとDEPARTMENTテーブルを結合して得られる結果セットに対しては、 Employeeエンティティクラスとは別のクラス（たとえばEmployeeDepartmentクラス）が必要です。

というわけで検索結果格納用Entityを作成します。
また、これまではEntityに対しid、nameなどと対象のEntity内だけで一意に決まる名前付けをしていましたが、
結合した結果に対しidやnameだけではわかりづらくなるため
この時点で明示的な名前を付けます。employeeIdやemployeeNameのように


###Entity追加
```java:EmployeeDepartment.java
package com.example.demo.entity;

import org.seasar.doma.Entity;

@Entity
public class EmployeeDepartment {

	public Integer employeeId;
	public String employeeName;
	public String departmentName;
	public String birthday;
}
```

Daoを作成します。

```java:EmployeeDao.java
package com.example.demo.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

import com.example.demo.entity.Employee;

@ConfigAutowireable
@Dao
public interface EmployeeDao {
	
	@Select
	List<EmployeeDepartment> selectAll();

}
```

DepartmentDaoと同様の手順でSQLファイルを作成します。

```sql:selectAll.sql
SELECT
	T1.ID, T1.NAME AS employeeName, T2.NAME AS departmentName, DATE_FORMAT(BIRTHDAY,'%Y-%m-%d') AS birthday
FROM
	EMPLOYEE T1
JOIN
	DEPARTMENT T2
ON
	T1.DEPARTMENT_ID = T2.ID
ORDER BY T1.ID
```

##Service作成

ServiceからはDaoを呼び出します。

```java:EmployeeService.java
package com.example.demo.service;

import java.util.List;

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

import com.example.demo.dao.EmployeeDao;
import com.example.demo.entity.Employee;

@Service
public class EmployeeService {
	
	@Autowired
	EmployeeDao employeeDao;

	public List<Employee> selectAll() {
		return employeeDao.selectAll();
	}
}
```





##Dto作成

処理結果を返すDtoを作成します。
今回は社員情報一覧と部署一覧をDtoに記述します。

```java:HomeInitResultDto
package com.example.demo.dto;

import java.util.List;

import com.example.demo.entity.Department;
import com.example.demo.entity.Employee;
import com.example.demo.entity.EmployeeDepartment;

public class HomeInitResultDto {

	public List<EmployeeDepartment> employeeList;
	public List<Department> departmentList;
}

```


##Controller作成

ControllerからはServiceを呼び出します。

```java:HomeController.java
package com.example.demo.controller;

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.demo.dto.HomeInitResultDto;
import com.example.demo.service.EmployeeService;

@RestController
@RequestMapping(value = "/Home")
public class HomeController {

	@Autowired
	EmployeeService employeeService;

	@Autowired
	DepartmentService departmentService;

	/**
	 * 初期化
	 * @return
	 */
	@RequestMapping(path="/init", method = RequestMethod.GET)
	public HomeInitResultDto init() {

		HomeInitResultDto resultDto = new HomeInitResultDto();
		resultDto.employeeList = employeeService.selectAll();
		resultDto.departmentList = departmentService.selectAll();

		return resultDto;
	}
}
```
##アプリケーション実行
http://localhost:8080/Home/init にアクセスすると以下のようなJSONが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425239/4a31ee2b-27b7-e51b-0607-725afa41eeba.png)




EclipseのコンソールにはDomaのSQLログが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425239/612d9e64-4cfd-0a9c-b4d6-63c7ea2ab3f6.png)


Spring Boot編は一度ここで一区切りです。
次回はAngularでフロントエンドを作成します。
[【Spring Boot + Angular + MySQLでWebアプリ作成】 Angular編①へ](https://qiita.com/k-yamada-neut/private/939c3d043997c4b45d30)