web-dev-qa-db-ja.com

Spring Boot Data Jpaアプリケーションで基準クエリを使用する方法

Spring Boot Data jpaを使用するアプリケーションがあります。これまでのところ、私はこのようなリポジトリを使用しています

public interface StudentRepository extends CrudRepository<StudentEntity, Integer>{
    @Query(value = "" 
        + "SELECT s.studentname "
        + "FROM   studententity s, "
        + "       courseentity c "
        + "WHERE  s.courseid = c.courseid "
        + "       AND s.courseid IN (SELECT c.courseid "
        + "                          FROM   courseentity c "
        + "                          WHERE  c.coursename = ?1)")
    List<String> nameByCourse(String coursename);
}

Criteria Queryを使用して、HibernateがSpring Bootアプリケーションでそのような場合に提供する方法

11
Rahul

docs から

リポジトリをカスタム機能で強化するには、最初にカスタム機能のインターフェイスと実装を定義します。指定したリポジトリインターフェイスを使用して、カスタムインターフェイスを拡張します。

そのようにインターフェースを定義する

public interface StudentRepositoryCustom {

    List<String> nameByCourse(String coursename);

}

次に、このインターフェースのカスタム実装を次のように定義します

@Service
class StudentRepositoryImpl implements StudentRepositoryCustom {

    @PersistenceContext
    private EntityManager em;

    public List<String> nameByCourse(String coursename) {            
        CriteriaBuilder cb = em.getCriteriaBuilder();
        //Using criteria builder you can build your criteria queries.
    }

}

これで、JPAリポジトリでこのカスタムリポジトリ実装を拡張できます。

public interface StudentRepository extends CrudRepository<StudentEntity, Integer>, StudentRepositoryCustom {

}

条件クエリと条件ビルダーの詳細 here

20
Abdullah Khan

Spring-boot-jpaほぼすべての場所でentityManagerを使用できます。最も一般的な方法は、カスタムメソッド用に独自のinterfaceを作成することです。

public interface StudentCustomRepository {

    void anyCustomMethod();
    Student getStudentByName(String name);
}

次に、entityManagerを自動配線して使用できるサービスクラスにこのインターフェイスを実装します。

@Service
public class StudentCustomRepositoryServiceImpl implements StudentCustomRepository {

     @PersistenceContext
     private EntityManager em;

     @Override
     public void anyCustomMethod(){
         //here use the entityManager
     }

     @Override
     StudentEntity getStudentByName(String name){
         Criteria crit = em.unwrap(Session.class).createCriteria(StudentEntity.class);
         crit.add(Restrictions.eq("name", name));
         List<StudentEntity> students = crit.list();
         return students.get(0);
     }
 }

StudentRepositoryを新しいStudentCustomRepositoryServiceImplクラスに実装することもできます。

5
Patrick

JPA 2は、クエリをプログラムで作成するために使用できる基準APIを導入しています。

JpaSpecificationExecutorから新しいインターフェースを拡張できます

public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaSpecificationExecutor {
    default List<Customer> findCustomers() {
    return findAll(CustomerSpecs.findCustomers());
}

次に、顧客仕様を作成します

public final class CustomerSpecs {

public static Specification<Customer> findCustomers() {
    return new Specification<Customer>() {
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query,
        CriteriaBuilder builder) {

     LocalDate date = new LocalDate().minusYears(2);
     return builder.lessThan(root.get("birthday"), date);
  }
};
}

詳細については、この春のドキュメントを参照してください

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#specifications

3
sendon1982

Spring docによると HibernateTemplate

注:Hibernateアクセスコードは、プレーンなHibernateスタイルでコーディングすることもできます。したがって、新しく開始されたプロジェクトの場合は、SessionFactory.getCurrentSession()に基づいて、データアクセスオブジェクトをコーディングする標準のHibernateスタイルを採用することを検討してください。このHibernateTemplateは、主にHibernate 4.xのバグ修正の恩恵を受けるために、Hibernate 3ベースのデータアクセスコードの移行ヘルパーとして存在します。

Hibernateのドキュメントによると:

新規開発では、JPA javax.persistence.criteria.CriteriaQuery APIに焦点を当てる必要があります。最終的に、Hibernate固有の基準機能は、JPA javax.persistence.criteria.CriteriaQueryの拡張機能として移植されます。

したがって、JPQL基準を使用する方が適切です: JPA基準APIクエリ

例:

  CriteriaBuilder cb = entityManager.getCriteriaBuilder();

  CriteriaQuery<Country> q = cb.createQuery(Country.class);
  Root<Country> c = q.from(Country.class);
  q.select(c);

entityManagerは@Autowiredである必要があります。詳細情報については、上記のリンクを参照してください

2
Afridi

APIは非常に冗長で邪魔にならないため、JPA基準を使用して仕様を作成することは非常に複雑です。

Lambda JDK 8では、単純な述語を使用して、非常に型付けされたクエリを作成できます。

@Test
public void testSimpleSpec() {
    String expected = 
        "select e0.id, e0.name "
        + "from Customer e0 "
        + "where (e0.regionCode = :p0)";

    Consumer<Query<Customer>> regionCode1 = 
        q -> q.where(i -> i.getRegionCode()).eq(1L);

    NativeSQLResult result = new QueryBuilder()
        .from(Customer.class)
        .whereSpec(regionCode1)
        .select(i -> i.getId())
        .select(i -> i.getName())
        .to(new NativeSQL())
        ;
    String actual = result.sql();

    Assert.assertEquals(expected, actual);
    Assert.assertEquals(result.params().get("p0"), 1L);
}

条件を分離し、他のクエリ、つまり仕様で再利用できます。

https://github.com/naskarlab/fluent-query

https://github.com/naskarlab/fluent-query-eclipselink

0
naskar

クエリ作成 を参照してスプリングデータJPAドキュメントを参照し、表を見ると、JPAは文字列クエリの使用を避けることができるメソッド名から複数のクエリを作成できます。

0
Mohamed Dernoun