コントローラ
通常のクラスに @Controller を付け、メソッドにURLを割り当てる。
@RequestMapping でURLとGET/POSTを設定する。
@Controller public class HanbaiController { @RequestMapping(value="/slist", method=RequestMethod.GET) public ModelAndView slist(ModelAndView mav) { mav.setViewName("slist"); return mav; } }
この例ではURLが /slist 、メソッドはGET でアクセスすると slistメソッドが呼ばれる。
メソッドの引数はModelAndView、これをそのまま return する。
ModelAndView に setViewNameで表示したいhtmlファイルの名前を指定する( slist.html なら slist だけでよい )。
htmlファイルはresourcesのtemplate内に置く。
フォーム
フォームからの受け取りは@RequestParamで行う。
// HTML <form method="post" action="slist"> 商品名:<input type="text" name="sname" ><br> 単価:<input type="text" name="tanka" ><br> <input type="submit" value="追加"> </form>
上のフォームからsnameとtankaが渡される。
これを下のメソッドの引数、snameとtankaで受け取る。
// Java @RequestMapping(value="/slist", method=RequestMethod.POST) public ModelAndView shouhinAdd( @RequestParam("sname")String sname , @RequestParam("tanka")Integer tanka, ModelAndView mav) { Shouhin s = new Shouhin(); s.setSname(sname); s.setTanka(tanka); repository.save(s); // データベース保存 mav.setViewName("redirect:/slist"); return mav; }
上の例ではsetViewNameで redirect:/ を付けてリダイレクトしている。
エンティティでの受け取り
フォームからエンティティを入力する場合、の受け取りは@ModelAttributeで一括して行える。これはフォームを表示する場合にも必要になる。
@RequestMapping(value="/slist", method=RequestMethod.POST) public String shouhinAdd( @ModelAttribute("formModel") Shouhin shouhin, ModelAndView mav) { repository.save(shouhin); return "redirect:/slist"; }
ビュー
htmlファイルにオブジェクトを送るには、ModelAndViewに addObjectでオブジェクトを渡す。その際に名前を付けて渡す。
String mes = "こんにちは"; // 名前 mes で、オブジェクトmesを渡した mav.addObject("mes",mes); mav.setViewName("slist"); return mav;
htmlファイルではthymeleafの書式を使って渡されたオブジェクトを表示する。
具体的には ${オブジェクト名} で取得できる。これをth:で始まる属性にセットする。
テキスト
タグに囲まれた部分に出したい場合、タグのth:text属性にセットする。
<p th:text="${mes}"></p>
上の例の場合、以下のようにHTMLが生成される(mesに「こんにちは」が入っている場合)。
<p>こんにちは</p>
リスト
List<Shouhin> list = repository.findAll(); mav.addObject("list",list); mav.setViewName("slist");上のコードでlistをhtmlファイルに送った場合、以下のようにして表示する。
<tr th:each="shouhin : ${list}"> <td th:text="${shouhin.sid}"></td> <td th:text="${shouhin.sname}"></td> <td th:text="${shouhin.tanka}">円</td> </th>
th:eachを書いたタグとそれに囲まれた部分がリストの要素数だけ繰り返される。
リストの一個の要素はshouhinに入るので ${shouhin.sid}のようにして表示する。
リストの数により処理を分けたい場合、th:ifを使って以下のように行う。
<div th:if="${#lists.isEmpty(list)}"> リストに一個も無い時 </div> <div th:if="!${#lists.isEmpty(list)}"> リストに一個以上ある時 </div> <div th:if="${#lists.size(list)}>3" > リストに3個より多い要素がある時 </div>
文字の埋め込み
||で囲むと、その中の文字列中に ${オブジェクト} の値が埋め込まれる。
例:|del?sid=${shouhin.sid}|
shouhin.sidが1なら
del?sid=1
になる。
// リンクの例 <a th:href="|del?sid=${shouhin.sid}|">削除</a>
value属性
<input type="hidden" name="sid" th:value="${shouhin.sid}">
日付の整形
<td th:text="${#dates.format(uriage.hi,'yyyy/MM/dd')}"></td>
データベース
まず、application.propertiesファイルに設定を書く。
spring.datasource.url=jdbc:mysql://localhost:3306/library?serverTimezone=JST spring.datasource.username=root spring.datasource.password= spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.jpa.database=MYSQL spring.jpa.hibernate.ddl-auto=update
テーブルの一行を表すエンティティクラスを作る。
@Tableでテーブル名、@Columnで列名を指定する。
@Entity @Table(name="Shouhin") public class Shouhin { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="sid") private int sid; @Column(name="sname") private String sname; @Column(name="tanka") private int tanka; // あとはgetter setter }
データベースを操作できるrepositoryインタフェースを作る。
これはJpaRepositoryを継承するのみである程度の操作は可能。
public interface ShouhinRepository extends JpaRepository{ }
Controller内でrepositoryを実体化し、操作する。実体化は @Autowired で自動的に出来る。
@Controller public class HanbaiController { @Autowired private ShouhinRepository repository; @RequestMapping(value="/slist", method=RequestMethod.GET) public ModelAndView slist(ModelAndView mav) { List<Shouhin> list = repository.findAll(); mav.addObject("list",list); mav.setViewName("slist"); return mav; } }
リポジトリ
基本メソッド
// 全行取得 List<Shouhin> list = repository.findAll(); // 一件取得 Optional<Shouhin> s = repository.findById(sid); mav.addObject("shouhin",s.get()); // 追加・更新 repository.save(s); // 削除 repository.delete(s);
※Optionalはnull処理を簡略化するためのクラス。
Optional<Shouhin>ならget()でShouhinを取得できる。
isPresent()でnullだったかどうかが分かる(falseならnull)
検索メソッドの追加
ルールに合わせた名前を宣言するだけで自動的に実装される。
public interface UriageRepository extends JpaRepository{ // 指定されたsid List<Uriage> findBySid(int sid); // 指定された日付 List<Uriage> findByHi(Date hi); // 指定されたsidと日付 List<Uriage> findBySidAndHi(int sid,Date hi); // 指定された個数より小さい List<Uriage> findByKosuLessThan(int kosu); // 指定された個数より大きい List<Uriage> findByKosuGreaterThan(int kosu); // 日付がNull List<Uriage> findByHiIsNull(); // 日付がNullではない List<Uriage> findByHiIsNotNull(); // 指定された日付をLikeで List<Uriage> findByHiLike(Date hi); // 指定されたsidを日付の降順 List<Uriage> findBySidOrderByHiDesc(int sid); }
セッション
実体化
Autowiredでセッションも自動的にインスタンス化できる。
@Controller public class HanbaiController { @Autowired private HttpSession session; @RequestMapping(value="/del", method=RequestMethod.GET) public ModelAndView del( @RequestParam("sid")Integer sid, ModelAndView mav) { Optionals = repository.findById(sid); // セッションに入れる。 session.setAttribute("del",s.get()); mav.setViewName("del"); return mav; } @RequestMapping(value="/del", method=RequestMethod.POST) public ModelAndView shouhinDel( ModelAndView mav) { // セッションから取り出す Shouhin s = (Shouhin)session.getAttribute("del"); repository.delete(s); mav.setViewName("redirect:/slist"); return mav; } }