Maison >Java >javaDidacticiel >Explication détaillée du code de requête dynamique dans JAVA Spring Data JPA
spring Data JPA simplifie grandement le développement de notre couche de persistance, mais dans les applications réelles, nous avons toujours besoin de requêtes dynamiques.
Par exemple, si le front-end a plusieurs conditions, dont beaucoup sont facultatives, alors le SQL du back-end doit être personnalisable. Lors de l'utilisation de la mise en veille prolongée, vous pouvez juger que les conditions sont utilisées. pour épisser SQL (HQL). Bien sûr, Spring Data JPA simplifie non seulement notre développement, mais fournit également un support.
En implémentant la requête dynamique implémentée par Criteria 2, notre interface Repo doit hériter de l'interface JpaSpecificationExecutor, qui est une interface générique.
Ensuite, lors de l'interrogation, transmettez simplement les paramètres de requête dynamiques, les paramètres de pagination, etc.
C'est très simple à utiliser, mais afin de comprendre pourquoi, introduisons d'abord l'API Criteria.
API Critères
Une requête est de type sécurisé pour les objets Java si le compilateur peut effectuer des vérifications d'exactitude de la syntaxe sur la requête. La version 2.0 de l'API Java™ Persistence (JPA) introduit l'API Criteria, qui apporte pour la première fois des requêtes de type sécurisé aux applications Java et fournit un mécanisme de construction dynamique de requêtes au moment de l'exécution. Cet article décrit comment écrire des requêtes dynamiques et de type sécurisé à l'aide de l'API Criteria et de l'API Metamodel étroitement liée.
Lors de l'utilisation de Spring Data JPA, tant que notre couche Repo hérite de l'interface JpaSpecificationExecutor, nous pouvons utiliser la spécification pour la requête dynamique. Jetons d'abord un coup d'œil à l'interface JpaSpecificationExecutor :
public interface JpaSpecificationExecutor<T> { T findOne(Specification<T> spec); List<T> findAll(Specification<T> spec); Page<T> findAll(Specification<T> spec, Pageable pageable); List<T> findAll(Specification<T> spec, Sort sort); long count(Specification<T> spec); }
Vous pouvez voir que 5 méthodes sont fournies, et les paramètres et valeurs de retour des méthodes ont clairement exprimé leurs intentions. Parmi les paramètres, Pageable et Sort devraient être relativement simples, ce sont respectivement des paramètres de pagination et des paramètres de tri, et l'accent est mis sur le paramètre Spécification. Regardons d'abord la définition de cette interface :
public interface Specification<T> { Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); }
L'une des. les méthodes renvoyées sont la structure de données de la requête dynamique.
javax.persistence.criteria.Predicate toPredicate(javax.persistence.criteria.Root<T> root, javax.persistence.criteria.CriteriaQuery<?> query, javax.persistence.criteria.CriteriaBuilder cb);
Toutes les spécifications de Java EE sont utilisées ici Pour l'implémentation spécifique, j'utilise Hibernate. Bien sûr, vous pouvez également en choisir d'autres. implémentez la spécification JPA.
Ici, nous devons revenir en arrière et examiner certaines choses dans l'API Criteria :
Les requêtes de critères sont basées sur le concept de métamodèle, qui est une entité gérée pour une unité de persistance spécifique définie, ces entités peuvent être des classes d'entités, des classes intégrées ou des classes parents mappées.
Interface CriteriaQuery : représente un objet de requête spécifique de niveau supérieur, qui contient différentes parties de la requête, telles que : sélectionner, depuis, où, regrouper par, trier par, etc. Remarque : objets CriteriaQuery ne fonctionne qu'avec les types d'entités Ou le type intégré de requête Critères fonctionne
Interface racine : représente l'objet racine de la requête Critères. La racine de la requête Critères définit le type d'entité et peut obtenir les résultats souhaités. pour une navigation future. Elle est liée à La clause FROM dans une requête SQL est similaire à
1 : les instances racine sont typées et définissent les types qui peuvent apparaître dans la clause FROM de la requête.
2 : L'instance racine de la requête peut être obtenue en transmettant un type d'entité à la méthode AbstractQuery.from.
3 : Requête de critères, qui peut avoir plusieurs racines de requête.
4 : AbstractQuery est la classe parent de l'interface CriteriaQuery, qui fournit des méthodes pour obtenir la racine de la requête. Interface CriteriaBuilder : l'objet constructeur utilisé pour construire CritiaQuery Predicate : un type de prédicat simple ou complexe, qui est en fait équivalent à une condition ou une combinaison de conditions
Les méthodes prises en charge sont très puissantes, comme indiqué ci-dessous Vous pouvez vous référer à un exemple. De même, vous pouvez écrire des requêtes plus complexes basées sur l'exemple :
Interface Repo :
public interface DevHREmpConstrastDao extends JpaRepository<DevHREmpConstrast, Long>,JpaSpecificationExecutor<DevHREmpConstrast>
Exemple de requête 1 :
/** * 条件查询时动态组装条件 */ private Specification<DevHREmpConstrast> where( final String corg,final String name,final String type,final String date,final String checker){ return new Specification<DevHREmpConstrast>() { @Override public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<Predicate>(); //机构 if(corg!=null&&!corg.equals("")){ List<String> orgIds = organizationDao.findByName("%"+corg+"%"); if(orgIds.size()>0&&orgIds.size()<1000) predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo } //名字 if(name!=null&&!name.equals("")){ List<String> userIds = userDao.findByName(name); if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了 predicates.add(root.<String>get("hrUserName").in(userIds)); } //类型 if(type!=null&&!type.equals("")) predicates.add(cb.equal(root.<String>get("hrUpdateType"),type)); //日期 if(date!=null&&!date.equals("")){ //处理时间 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date startDate; Date endDate; try { startDate = format.parse(date); } catch (ParseException e) { startDate = new Date(946656000000L);//2000 01 01 } endDate = startDate; Calendar calendar = Calendar.getInstance() ; calendar.setTime(endDate); calendar.add(Calendar.DATE, 1); endDate = calendar.getTime(); calendar = null; predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate)); } //审核人 if(checker!=null&&!checker.equals("")){ List<String> userIds = userDao.findByName(checker); if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了 predicates.add(root.<String>get("confirmUserId").in(userIds)); } return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); } }; }
Exemple de requête 2 :
/** * 条件查询时动态组装条件 */ private Specification<DevHREmpConstrast> where( final String corg,final String name,final String type,final String date,final String checker){ return new Specification<DevHREmpConstrast>() { @Override public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<Predicate>(); //机构 if(corg!=null&&!corg.equals("")){ List<String> orgIds = organizationDao.findByName("%"+corg+"%"); if(orgIds.size()>0&&orgIds.size()<1000) predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo } //名字 if(name!=null&&!name.equals("")){ List<String> userIds = userDao.findByName(name); if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了 predicates.add(root.<String>get("hrUserName").in(userIds)); } //类型 if(type!=null&&!type.equals("")) predicates.add(cb.equal(root.<String>get("hrUpdateType"),type)); //日期 if(date!=null&&!date.equals("")){ //处理时间 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date startDate; Date endDate; try { startDate = format.parse(date); } catch (ParseException e) { startDate = new Date(946656000000L);//2000 01 01 } endDate = startDate; Calendar calendar = Calendar.getInstance() ; calendar.setTime(endDate); calendar.add(Calendar.DATE, 1); endDate = calendar.getTime(); calendar = null; predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate)); } //审核人 if(checker!=null&&!checker.equals("")){ List<String> userIds = userDao.findByName(checker); if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了 predicates.add(root.<String>get("confirmUserId").in(userIds)); } return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); } }; }
Appelez ensuite la méthode dao layer et transmettez les paramètres renvoyés par la méthodewhere().
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!