スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Spring MVC Spring Data JPAを使って登録する

前回まで、テーブルからレコードを取得するパターンだったので、今回はJPAを使って、テーブルへの更新処理を実装する。
なお、エンティティやBean定義ファイルの設定などについては、過去のJPA関連記事を参考にしてほしい。

■JPAの過去の関連記事
Spring MVC Spring Data JPAを使ってみる
Spring MVC Spring Data JPAを使ってみる(その2)
Spring MVC Spring Data JPAを使って検索する

◎動作検証にあたっての各バージョンは以下の通り
  • SpringFramework 3.2.8.RELEASE
  • Java 1.7
  • Tomcat 7.0

1.BookController.java


package jp.co.sample.book.controller;

import java.util.List;

import javax.validation.Valid;

import jp.co.sample.book.entity.BookEntity;
import jp.co.sample.book.form.BookForm;
import jp.co.sample.book.form.BookSearchForm;
import jp.co.sample.book.service.BookService;
import jp.co.sample.util.BookUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Controller
@RequestMapping("book")
public class BookController {

private static Logger logger = LoggerFactory.getLogger(BookController.class);

@Autowired
protected BookService<BookEntity> bookService;

@RequestMapping(method = RequestMethod.GET)
public String index(BookForm form) {
logger.info("index start");
return "newBook";
}

  //一覧
@RequestMapping(value = "list", method = RequestMethod.GET)
//public String list(Model model) {
public String list(BookSearchForm form, Model model) {
logger.info("list start");
List<BookEntity> entites = bookService.findAll();
model.addAttribute("books", entites);
//model.addAttribute("bookSearchForm", form);
return "list";
}

//検索
@RequestMapping(value = "list/search", method = RequestMethod.GET)
public String search(BookSearchForm form, Model model) {
logger.info("search start");
List<BookEntity> entites = bookService.findByNameLike(form.getBookName());
model.addAttribute("books", entites);
return "list";
}

//登録
@RequestMapping(value = "create", method = RequestMethod.POST)
public String create(@Valid BookForm form, BindingResult result, Model model) {
logger.info("create start");
if (result.hasErrors()) {
return "newBook";
}
  BookEntity entity = BookUtil.copyProperties(form);
bookService.addEntity(entity);
model.addAttribute("book", entity);
return "result";
}
}

コントローラクラス。BookUtilクラスは自作のユーティリティでリクエスト格納オブジェクトからエンティティにコピーしている。ここについては他にもいろいろやり方があると思う。登録は、ServiceクラスのaddEntityメソッドを呼び出している。

2.BookForm.java


package jp.co.sample.book.form;

import java.io.Serializable;
import javax.validation.constraints.Min;
import org.hibernate.validator.constraints.NotEmpty;

public class BookForm implements Serializable {

private static final long serialVersionUID = 1L;

//@NotBlank
private String bookId;

@NotEmpty
private String bookName;

@Min(1)
private String price;;

//getter・setterは省略
}

過去のバリデーションに関する記事で、bookIdを@NotBlankアノテーションでチェックしていたが、bookIdはBookEntityクラスにて自動インクリメントするため、チェック対象から外している。(@NotBlankアノテーションをコメントアウト)
それに伴い、登録用のnewBook.jspからbookIdのテキスト入力箇所を削除している。

■バリデーションの過去の関連記事
Spring MVC バリデーションの実装
Spring MVC メッセージリソースを使ってバリデーションエラーを定義

3.BookDao.java


package jp.co.sample.book.dao;

import java.util.List;

public interface BookDao<T> {

List<T> findAll();
List<T> findByNameLike(String name);
void addEntity(T entity);
}

BookDaoインターフェース。addEntityが今回実装する登録用メソッド。

4.BookDaoImpl.java


package jp.co.sample.book.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import jp.co.sample.book.entity.BookEntity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
public class BookDaoImpl implements BookDao<BookEntity> {

private static Logger logger = LoggerFactory.getLogger(BookDaoImpl.class);

@PersistenceContext
private EntityManager manager;

@Override
@Transactional(readOnly=true)
public List<BookEntity> findAll() {
logger.info("findAll start");
Query query = manager.createQuery("from BookEntity");
return query.getResultList();
}

@Override
@Transactional(readOnly=true)
public List<BookEntity> findByNameLike(String name) {
logger.info("findByNameLike start");
Query query = manager.createQuery("from BookEntity where bookName like '%" + name + "%'");
return query.getResultList();
}

@Override
public void addEntity(BookEntity entity) {
logger.info("addEntity start");
manager.persist(entity);
}
}

addEntityメソッドの実装。これだけでテーブルへ登録できる。
manager.persist(entity)は、エンティティを保存するだけで、コミットまでしている訳ではない。なぜこれだけでテーブルに登録されるかと言うと、クラスに付与された@Transactionalアノテーションがトランザクション制御をしてくれるからである。そのため、addEntityメソッド内でトランザクションの開始やコミット命令など記載しなくてよい。ちなみに@Transactionalアノテーションはメソッドにも付与することができるため、クラス側の@Transactionalアノテーションを削除して、メソッド側に付与しても問題なくテーブルに登録される。
裏を返せば、@Transactionalアノテーションを付与しない場合は、テーブルに登録されないので注意が必要だ。
参考までに、追加の場合、manager.persist(entity)となるが、更新⇒manager.merge(entity)、削除⇒manager.remove(entity)となる。

5.BookService.java


package jp.co.sample.book.service;

import java.util.List;

public interface BookService<T> {

List<T> findAll();
List<T> findByNameLike(String name);
void addEntity(T entity);
}


6.BookServiceImpl.java

package jp.co.sample.book.service;

import java.util.List;

import jp.co.sample.book.dao.BookDao;
import jp.co.sample.book.entity.BookEntity;

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

@Service
public class BookServiceImpl implements BookService<BookEntity> {

@Autowired
@Qualifier(value="bookDaoImpl")
BookDao<BookEntity> dao;

@Override
public List<BookEntity> findAll() {
return dao.findAll();
}

@Override
public List<BookEntity> findByNameLike(String name) {
return dao.findByNameLike(name);
}

@Override
public void addEntity(BookEntity entity) {
dao.addEntity(entity);
}
}

@Qualifierアノテーションについては過去のJPAの記事を参考にしてほしい。
実際の登録処理はDAOに委譲している。

7.動作確認
①登録

登録

②登録後の一覧
登録後一覧

登録したデータがテーブルに反映されていることが確認できた。

今回SQLやJPQLを1行も書くことなく、そしてトランザクション制御は@Transactionalアノテーションを付与しただけで、非常に少ないコード量で実現できた。

■過去のSpring関連記事
Spring関連記事 Index

スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

bookmount8

Author:bookmount8
システムエンジニア。サーバーサイドでjavaを扱うことが多い。最近は、ミドルやフロント周りも関心あり。

最新記事
カテゴリ
検索フォーム
最新コメント
月別アーカイブ
これまでの訪問者数
ブロとも申請フォーム

この人とブロともになる

RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。