前回「SpringBootで日付計算処理アプリ」で課題だった「計算結果の表示方法」が改善できましたので投稿させていただきます。
環境
macOS Big Sur
Java 11
Spring Boot 2.4.5
SpringToolSuite4
gradle
MySQL
MyBatis
解決方法
計算結果を格納する先として別途エンティティクラスResultを作成し、
当Resultクラスのフィールドとして計算結果を表示させます。
※前回の計算式を格納するエンティティクラス「DateCalc」の名前を「DateFormula」に変更しています。
各ソースコード(重要部分のみ)
Result.java
package com.example.demo.entity;
import java.time.LocalDate;
import lombok.Data;
@Data
public class Result {
private DateFormula formula;
private String calculated;
//計算式情報をhtmlで表示するためのフィールド設定
private int id;
private String name;
private int plusyear;
private int plusmonth;
private int plusday;
//コンストラクタその1
public Result(DateFormula formula) {
this.formula = formula;
}
//コンストラクタその2
public Result(DateFormula formula, String calculated) {
this.formula = formula;
this.calculated = calculated;
}
}
コンストラクタその1は、GetMappingで最初にtop.htmlを表示させる際に、Result型の配列生成時にDB内の計算式formulaを入れちゃうために作成しています。(本投稿には出てきません。)
コンストラクタその2は、DateCalcControllerにおいて、Result型配列生成時に計算式formulaと計算結果calculatedを入れちゃうために作成しています。
上記のコンストラクタは使用せずSetterでも問題ありません。
DateFormula.java
package com.example.demo.entity;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
public class DateFormula {
private int id;
@NotBlank(message = "入力してください")
private String name;
@NotNull
private int plusyear;
@NotNull
private int plusmonth;
@NotNull
private int plusday;
}
DateCalcController.java(一部抜粋)
//計算結果をtop.htmlに表示
@PostMapping("/calc")
public String calc(Model model, @ModelAttribute("inputdate") String inputdateHTML) {//@ModelAttributeでhtmlに入力された値を受けっ取っている
//DBから全データをselectしDateFormula型のListに格納
List<DateFormula> formulaList = service.selectAll();
//top.htmlに入力された数値をLocaDate型に変換
LocalDate inputdate = LocalDate.parse((inputdateHTML), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//yyyy年MM月dd日(曜日)の形式に変換
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)");
String inputdateDisplay = inputdate.format(dtf);
//計算結果格納用の配列
Result[] results = new Result[formulaList.size()];
//DateFormulaのデータ数分繰り返す
for(int i = 0; i < formulaList.size(); i++) {
//resultsの各要素に、formulaとcalculatedをset(コンストラクタを利用したインスタンス生成)
results[i] = new Result( formulaList.get(i), service.calculate( inputdate,formulaList.get(i) ).format(dtf) ) ;//.format(dtf)によりyyyy年MM月dd日(E)形式へ変換
//resultsの各要素に、formulaのid, name, plusyear, plusmonth, plusdayをset
results[i].setId(formulaList.get(i).getId());
results[i].setName(formulaList.get(i).getName());
results[i].setPlusyear(formulaList.get(i).getPlusyear());
results[i].setPlusmonth(formulaList.get(i).getPlusmonth());
results[i].setPlusday(formulaList.get(i).getPlusday());
}
//確認用
System.err.println("result[]表示");
for(Result value : results) {
System.err.println(value);
}
//modelを通じ、htmlへ各値を渡す
model.addAttribute("inputdate", inputdateDisplay);
model.addAttribute("results", results);
//top.htmlを表示
return "top";
}
DateCalcService.java(一部抜粋)
//calculate処理
public LocalDate calculate(LocalDate inputdate, DateFormula formula) {
LocalDate calculatedDate = inputdate.plusYears(formula.getPlusyear()).plusMonths(formula.getPlusmonth()).plusDays(formula.getPlusday());
return calculatedDate;
}
top.html(テーブル部分のみ抜粋)
<table>
<thead>
<tr>
<th>計算式ID</th>
<th>計算式名</th>
<th>加減年</th>
<th>加減月</th>
<th>加減日</th>
<th>計算結果</th>
<th>更新ボタン</th>
<th>削除ボタン</th>
</tr>
</thead>
<tbody th:each="results:${results}" th:object="${results}">
<tr>
<td th:text="*{id}"></td>
<td th:text="*{name}"></td>
<td th:text="*{plusyear}"></td>
<td th:text="*{plusmonth}"></td>
<td th:text="*{plusday}"></td>
<td th:text="*{calculated}"></td>
<td><a th:href="@{/update/id={id}(id=*{id})}"><button>更新</button></a></td>
<td>
<form method="post" th:action="@{/delete/id={id}(id=*{id})}"><button
>削除</button></form>
</td>
</tr>
</tbody>
</table>
以上です!
Resultクラスの作成により以下の点が改善されました\(^o^)/
・計算式IDが連番でなくても、計算結果を計算式情報と同じテーブルで表示できます。
・計算式IDの途中の式が削除されても、問題なく計算式と連動した計算結果が一つのテーブルで表示されます。