この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
これまでのJPQLに関する記事は、クエリを"from MyData where id = :id"の様に文字で書いていました。 SQLをほぼそのままなので分かりやすいと言えばそうなのですが、Javaとしてどうなのかと言われると疑問です。 EclipseなどのIDEの自動エラーチェックにも引っかからないので、スペルミスでコンパイルが通らなくて原因解明に時間を取られる...なんて事は無くしたいです。 そこで今回は、JPAが実装しているCriteria APIを使用して、Javaらしいクエリの作成と実行を試してみたいと思います。
環境
Mac OSX 10.10.5 Yosemite Eclipse Mars2 Java 8 Spring Boot 1.3.6 PostgreSQL 9.5.1
テーブル準備
PostgreSQLで作成しました。
CREATE TABLE fruit (
id VARCHAR(2) NOT NULL,
name VARCHAR(10),
price integer,
PRIMARY KEY(id)
);
INSERT INTO fruit VALUES
('1','apple',300),
('2','orange',200),
('3','banana',100),
('4','cherry',100),
('5','pineapple',500),
('6','melon',800),
('7','watermelon',600),
('8','strawberry',450)
;
postgres=# select * from fruit ;
id | name | price
----+------------+-------
1 | apple | 300
2 | orange | 200
3 | banana | 100
4 | cherry | 50
5 | pineapple | 500
6 | melon | 800
7 | watermelon | 600
8 | strawberry | 450
(8 rows)
コード
エンティティ
package com.jpa.mydao;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Data
@Table(name="fruit")
public class Fruit {
@Id
private String id;
private String name;
private Integer price;
}
今回もlombokの@DataでGetter/Setterを生成しています。
DAOインターフェース
package com.jpa.mydao.dao;
import java.io.Serializable;
import java.util.List;
public interface FruitDao <T> extends Serializable {
public List<T> getAll();
}
DAOオブジェクト
package com.jpa.mydao.dao;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.jpa.mydao.Fruit;
@Repository
public class FruitDaoJpql implements FruitDao<Fruit>{
private EntityManager entityManager;
public FruitDaoJpql() {
}
public FruitDaoJpql(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public List<Fruit> getAll() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Fruit> query = builder.createQuery(Fruit.class);
Root<Fruit> root = query.from(Fruit.class);
query.select(root);
List<Fruit> list = (List<Fruit>) entityManager.createQuery(query).getResultList();
return list;
}
}
基本の流れは下記になっている様です。 builder -> query -> root -> メソッド実行 -> 結果を取得
29~37行目はDAOインターフェースで作成したメソッドです。 31行目、CriteriaBuilder。クエリ生成の管理クラス。 32行目、CriteriaQuery。クエリ実行のクラス。 33行目、Root。ここからエンティティの絞り込みなどを行います。 34行目、クエリの生成。テーブル検索の準備完了です。 35行目、クエリを実行してListで取得。 SQLだと、"select * from fruit;"となります。
コントローラー
package com.jpa.mydao;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.jpa.mydao.dao.FruitDaoJpql;
@RestController
public class EntityManagerController {
@PersistenceContext
EntityManager entityManager;
FruitDaoJpql dao;
@PostConstruct
public void init() {
dao = new FruitDaoJpql(entityManager);
}
@RequestMapping(value="/all", method=RequestMethod.GET)
public List<Fruit> all() {
List<Fruit> list = dao.getAll();
return list;
}
}
"http://localhost:8080/all"で呼ばれるメソッドが一つだけです。 30行目、DAOオブジェクトからgetAll()を実行してListで取得しています。
実行
$ curl http://localhost:8080/all
[{"id":"1","name":"apple","price":300},{"id":"2","name":"orange","price":200},{"id":"3","name":"banana","price":100},{"id":"4","name":"cherry","price":50},{"id":"5","name":"pineapple","price":500},{"id":"6","name":"melon","price":800},{"id":"7","name":"watermelon","price":600},{"id":"8","name":"strawberry","price":450}]
さいごに
SQLが読めれば、後は処理の流れを覚えるだけで良さそうです。 次回は、より詳細な検索を試してみたいと思います。