Visual Studio CodeによるSpring Boot2 Webアプリ開発　SQLServer接続編

#はじめに
[こちら](https://qiita.com/t_skri/items/4e3c11050f93e4761dda)で作成したSQLServer接続WebアプリのSpring Boot版です。

#環境
OS:Windows 10 Pro 64bit
DB:SQL Server 2019(Cent OS 8 on Hyper-V)
Editor:Visual Studio Code 1.44.2
JDK:AdoptOpenJDK 11.0.6+10 x64

#ひな型作成
spring initializr[(https://start.spring.io/)](https://start.spring.io/)で、以下の設定で作成しました。

![2020-05-05 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/6fc9fd3f-c0f8-d796-829c-9ac19fa0d896.png)

作成したひな型を「D:\JAVA\Project」に展開します。

#pom.xml
SQLServerのJDBCがjre8版になっていますので、jre11版に変更します。
propertiesの中に「mssql-jdbc.version」を追加します。
（変更しなくても動作しましたが念のため）

```xml
<properties>
	<java.version>11</java.version>
	<mssql-jdbc.version>8.2.2.jre11</mssql-jdbc.version>
</properties>
```

#application.properties
DB接続情報を記述します。

```application.properties
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://xxx:1433;databaseName=Training01;QuotedID=NO
spring.datasource.username=xxx
spring.datasource.password=xxx
```


#entity作成
DBからのデータを受けるentityを作成します。

```
D:\JAVA\Project\bootSample2\src\main\java\com\example\bootSample2\persistence
└─entity
  └─ProductsMaster.java
```


```java:ProductsMaster.java
package com.example.bootSample2.persistence.entity;

import lombok.Data;

@Data
public class ProductsMaster {
    private String ProductsCode;
    private String ProductsName;
    private Integer UnitPrice;

    public ProductsMaster() {}

    public ProductsMaster(
        String ProductsCode,
        String ProductsName,
        Integer UnitPrice
        ) {
            this.ProductsCode = ProductsCode;
            this.ProductsName = ProductsName;
            this.UnitPrice = UnitPrice;
        }
}
```

#repository作成
DBに接続してSQL文を発行するrepositoryを作成します。

```
D:\JAVA\Project\bootSample2\src\main\java\com\example\bootSample2\persistence
└─repository
  ├─ProductsMasterRepository.java
  └─ProductsMasterRepositoryImpl.java
```


```java:ProductsMasterRepository.java
package com.example.bootSample2.persistence.repository;

import java.util.List;

import com.example.bootSample2.persistence.entity.ProductsMaster;

public interface ProductsMasterRepository {
    List<ProductsMaster> productsMasterList();
}
```

```java:ProductsMasterRepositoryImpl.java
package com.example.bootSample2.persistence.repository;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.bootSample2.persistence.entity.ProductsMaster;

@Repository
public class ProductsMasterRepositoryImpl implements ProductsMasterRepository {
	@Autowired
    NamedParameterJdbcTemplate jdbcTemplate;

	@Override
	public List<ProductsMaster> productsMasterList() {
		String sql = "SELECT * FROM ProductsMaster ORDER BY ProductsCode;";

        List<ProductsMaster> pMList = jdbcTemplate.query(sql,
                (rs, rowNum) -> new ProductsMaster(
                        rs.getString("ProductsCode"),
                        rs.getString("ProductsName"),
                        rs.getInt("UnitPrice")
                        )
                );

        return pMList;
	}
}
```

#service作成
ビジネスロジックとなるserviceを作成します。

```
D:\JAVA\Project\bootSample2\src\main\java\com\example\bootSample2
└─service
  ├─ProductsMasterService.java
  └─ProductsMasterServiceImpl.java
```

```java:ProductsMasterService.java
package com.example.bootSample2.service;

import java.util.List;

import com.example.bootSample2.persistence.entity.ProductsMaster;

public interface ProductsMasterService {
    List<ProductsMaster> productsMasterList();
}
```

```java:ProductsMasterServiceImpl.java
package com.example.bootSample2.service;

import java.util.List;

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

import com.example.bootSample2.persistence.entity.ProductsMaster;
import com.example.bootSample2.persistence.repository.ProductsMasterRepository;

@Service
public class ProductsMasterServiceImpl implements ProductsMasterService {
	@Autowired
	ProductsMasterRepository productsMasterRepository;

	@Override
	public List<ProductsMaster> productsMasterList() {
		List<ProductsMaster> pMList = productsMasterRepository.productsMasterList();

        return pMList;
	}
}
```

#form作成
viewでの入出力値を受け取るformを作成します。

```
D:\JAVA\Project\bootSample2\src\main\java\com\example\bootSample2\web
└─form
  └─ProductsMasterForm.java
```

```java:ProductsMasterForm.java
package com.example.bootSample2.web.form;

import java.util.List;

import com.example.bootSample2.persistence.entity.ProductsMaster;

import lombok.Data;

@Data
public class ProductsMasterForm {
	private List<ProductsMaster> pmList;
}
```

#controller作成

```
D:\JAVA\Project\bootSample2\src\main\java\com\example\bootSample2\web
└─controller
  └─ProductsMasterController.java
```

```java:ProductsMasterController.java
package com.example.bootSample2.web.controller;

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 org.springframework.web.bind.annotation.RequestMapping;

import com.example.bootSample2.service.ProductsMasterService;
import com.example.bootSample2.web.form.ProductsMasterForm;

@Controller
@RequestMapping("/productsMaster")
public class ProductsMasterController {
	@Autowired
	ProductsMasterService productsMasterService;

	@GetMapping("/index")
	public String indexGet(Model model) {
		ProductsMasterForm productsMasterForm = new ProductsMasterForm();
		productsMasterForm.setPmList(productsMasterService.productsMasterList());

		model.addAttribute("productsMasterForm", productsMasterForm);
		return "productsMaster/index";
	}

}
```

```java:RootController.java
package com.example.bootSample2.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RootController {
    @GetMapping("/")
    public String root() {
    	return "redirect:productsMaster/index";
    }
}
```

#view作成
「D:\JAVA\Project\bootSample2\src\main\resources\templates\」に「productsMaster」フォルダを作成します。
productsMasterフォルダにindex.htmlを作成します。

```
D:\JAVA\Project\bootSample2\src\main\resources\templates
└─productsMaster
  └─index.html
```

```html:index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Spring5 MVC sqlSample01</title>
</head>
<body>
    <h1>Hello Spring Products List</h1>
    <table border="1">
		<thead>
			<tr>
				<th>製品コード</th>
				<th>製品名</th>
				<th>単価</th>
			</tr>
		</thead>
		<tbody>
			<tr th:each="pm : ${productsMasterForm.pmList}" th:object="${pm}">
		    	<td th:text="*{ProductsCode}"></td>
		    	<td th:text="*{ProductsName}"></td>
		        <td th:text="*{UnitPrice}"></td>
			</tr>
		</tbody>
	</table>
</body>
</html>
```

#動作確認
「F5」キーを押して実行します。
http://localhost:8080/
にアクセスして下さい。
自動で[http://localhost:8080/productsMaster/index](http://localhost:8080/productsMaster/index)にリダイレクトされることを確認して下さい。

以下のページが表示されればOKです。
![springbootsql1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/7ff92d97-b084-7b79-b939-b6d14487b20c.jpeg)

#今回のサンプルソース
GitHubにアップしました。
[https://github.com/t-skri1/SpringSample04](https://github.com/t-skri1/SpringSample04)

#まとめ
非Bootとは階層構造とViewの配置場所が違うだけで、ソースの内容はそのままです。
それ以外の違いは

- DBの接続情報は「application.properties」に記述する
- pom.xmlでのバージョン指定方法が違う

になります。

DevToolを追加してありますので、hot deploy出来ます。
これは非常に便利です。