web-dev-qa-db-fra.com

Comment utiliser les requêtes de critères dans l'application Spring Boot Data Jpa

J'ai une application qui utilise Spring Boot Data jpa . Jusqu'à présent, j'utilise un référentiel comme celui-ci.

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);
}

Comment puis-je utiliser Interrogation sur les critères qu'Hibernate fournit pour de tels cas dans une application Spring Boot

9
Rahul

De la docs

Pour enrichir un référentiel avec des fonctionnalités personnalisées, vous devez d'abord définir une interface et une implémentation pour les fonctionnalités personnalisées. Utilisez l'interface de référentiel que vous avez fournie pour étendre l'interface personnalisée.

Définir une interface comme ça

public interface StudentRepositoryCustom {

    List<String> nameByCourse(String coursename);

}

Puis définissez une implémentation personnalisée de cette interface comme

@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.
    }

}

Vous pouvez maintenant étendre cette implémentaion de référentiel personnalisé dans votre référentiel JPA comme suit.

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

}

En savoir plus sur la requête de critères et le générateur de critères here

17
Abdullah Khan

Avec Spring-boot-jpa, vous pouvez utiliser entityManager presque partout. La méthode la plus courante consiste à créer une propre variable interface pour les méthodes personnalisées.

public interface StudentCustomRepository {

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

Puis implémentez cette interface dans une classe de service sur laquelle vous êtes en mesure de connecter automatiquement et utilisez la variable 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);
     }
 }

Vous pouvez également décider d'implémenter votre StudentRepository dans votre nouvelle classe StudentCustomRepositoryServiceImpl

4
Patrick

JPA 2 introduit une API de critères qui peut être utilisée pour créer des requêtes par programme.

Vous pouvez étendre une nouvelle interface de JpaSpecificationExecutor

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

Puis créez une spécification client

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);
  }
};
}

Pour plus de détails, référez-vous à la doc de ce printemps ici

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

3
sendon1982

Selon Spring, le document HibernateTemplate :

REMARQUE: Le code d'accès Hibernate peut également être codé en clair. Hibernate style. Par conséquent, pour les projets récemment lancés, envisagez d’adopter le Le style standard d’Hibernate de codage des objets d’accès aux données, basé sur sur SessionFactory.getCurrentSession (). Ce modèle Hibernate existe principalement comme assistant de migration pour les données basées sur Hibernate 3./ code d'accès, pour bénéficier des corrections de bugs dans Hibernate 4.x.

Selon la documentation d'Hibernate:

Les nouveaux développements devraient se concentrer sur l’APP API javax.persistence.criteria.CriteriaQuery. Finalement, Les critères spécifiques à Hibernate seront portés en tant qu'extensions vers JPA javax.persistence.criteria.CriteriaQuery.

Il est donc préférable d’utiliser les critères JPQL: Requêtes API JPA Criteria

Exemple:

  CriteriaBuilder cb = entityManager.getCriteriaBuilder();

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

où entityManager devrait être @Autowired. Pour plus d'informations, voir le lien ci-dessus

2
Afridi

Il est très compliqué de créer des spécifications à l'aide de critères JPA, car l'API est très détaillée et instructive.

Avec le JDK Lambda 8, vous pouvez créer des requêtes très typées en utilisant des prédicats simples.

@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);
}

Vous pouvez isoler les conditions et les réutiliser dans d'autres requêtes, par exemple des spécifications.

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

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

0
naskar

vous pouvez vous référer à Création de requête dans la documentation JPA de Spring Data et consulter le tableau. JPA permet de créer plusieurs requêtes à partir de noms de méthodes, ce qui vous évite d'utiliser une requête String 

0
Mohamed Dernoun