背景・目的
過去に、Spring Bootについて下記の記事にまとめました。今回は、Criteria APIによるデータベースアクセスを試します。
- Spring BootでDAOからデータベースにアクセスしてみた-その1(DAOとアノテーション)
- Spring Bootでバリデーションを試してみた
- Spring Bootでデータを保存する-その2
- Spring Bootでデータを保存する-その1
- Spring Bootでデータベースへのアクセスを試してみた
- Sprint Bootの環境を構築したときのメモ
まとめ
下記に特徴をまとめます
特徴 | 説明 |
---|---|
Criteria API | テキスト文字列を使用せずに、Javaエンティティ・クラスとフィールドによって強く型付けされた問合せを作成できる |
Criteria クラス | 下記の3つのクラスがある ・CriteriaBuilder ・CriteriaQuery ・Root |
概要
前回、Spring BootでDAOからデータベースにアクセスしてみた-その1(DAOとアノテーション)では、DAOやリポジトリを介して、JPQLでクエリを実行していました。
データベースへのクエリのうち、JPQLはSQLに近いものでしたが、JPAにはCriteria APIという機能もあります。
Criteria API
JPAの新機能: Criteria APIを基に整理します。
- Criteria APIでは、テキスト文字列を使用せずに、Javaエンティティ・クラスとフィールドによって強く型付けされた問合せを作成できる
- Criteria APIは、JPQLと同じくエンティティ・クラスの抽象スキーマに基づく
- Criteria APIを使うと、オブジェクトによって強く型付けされたデータベース問合せをJavaコードだけで作成できる
- 入力したJPQLやSQLによる問合せにエラーがないかを心配する必要がなくなるため、エラーの可能性を減らすことができる
- この問合せには完全な移植性があるというメリットがある。
- Criteria APIには、型保証された問合せの生成をサポートするさまざまなMetamodel APIも含まれる。
クラス
3つのクラスがある
- CriteriaBuilderクラス
- クエリ生成を管理する
- CriteriaQueryクラス
- クエリ実行
- Rootクラス
- 検索されるエンティティのルート
- 必要なエンティティを絞る
実践
前提
Spring BootでDAOからデータベースにアクセスしてみた-その1(DAOとアノテーション)で構築した環境を基にします。
Criteria APIによる検索
getAllメソッドを修正します
DAOの修正
- PersonDAOPersonImplクラスのgetAllメソッドを、下記のように書き換えます
@Override public List<Person> getAll() { List<Person> list = null; CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Person> query = builder.createQuery(Person.class); Root<Person> root = query.from(Person.class); query.select(root); list = (List<Person>)entityManager.createQuery(query).getResultList(); return list; }
コントローラーを修正
- WebControllerクラスのindexメソッドを、下記の通り書き換えます
@RequestMapping("/") public ModelAndView index( @ModelAttribute("formModel") Person person, ModelAndView mav) { mav.setViewName("index"); mav.addObject("title","Test page"); mav.addObject("message","This is JPA sample content."); // List<Person> list = repository.findAll(); // List<Person> list = repository.findAllOrderByName(); List<Person> list = dao.getAll(); mav.addObject("people", list); return mav; }
動作確認
- ビルドしSpring Bootを再実行します
$ mvn package $ java -jar target/rest-db-0.0.1-SNAPSHOT.jar
- localhost:8080にアクセスします。表示されました
Criteria APIによる名前の検索
findメソッドを修正します。
DAOの修正
- PersonDAOPersonImplクラスの find メソッドを、下記のように書き換えます
@Override public List<Person> find(String fstr){ CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Person> query = builder.createQuery(Person.class); Root<Person> root = query.from(Person.class); query.select(root).where(builder.equal(root.get("firstName"), fstr)); List<Person> list = null; list = (List<Person>)entityManager.createQuery(query).getResultList(); return list; }
コントローラーを修正
- WebControllerクラスの search メソッドを、下記の通り書き換えます
@RequestMapping(value = "/find", method=RequestMethod.POST) public ModelAndView search(HttpServletRequest request, ModelAndView mav){ mav.setViewName("find"); String param = request.getParameter("find_str"); if (param == ""){ mav = new ModelAndView("redirect:/find"); } else { mav.addObject("title","Find result"); mav.addObject("message","Result for " + param); mav.addObject("value", param); List<Person> list = dao.find(param); mav.addObject("people", list); } return mav; // Add this return statement }
動作確認
- ビルドしSpring Bootを再実行します
$ mvn package $ java -jar target/rest-db-0.0.1-SNAPSHOT.jar
- localhost:8080/findにアクセスします。表示されました
- firstNameに「Ichiro」を入力し、Clicksします。想定通り絞り込めました
考察
今回は、Criteria APIを使ったデータアクセスを試しました。
確かに、JPQLにあるようなSQLライクなコードは書かないので、移植性は高いと思いました。
参考