Il utilise Spring Data JPA depuis un certain temps. Au cours de cette période, j'ai appris certaines choses et rencontré certains problèmes. Je les partagerai avec vous ici.
Préface:
Introduction aux données de printemps:
Spring Data est un framework open source pour simplifier l'accès à la base de données et prendre en charge les services cloud. Son objectif principal est de rendre l'accès aux données continues et rapides, et de prendre en charge les services de données Map-Reduce et de cloud computing. Les données de printemps contient plusieurs sous-projets:
Commons - Fournit un cadre de base partagé adapté à une utilisation dans chaque sous-projet et prend en charge la persistance de la database transversale
JPA - simplifie la possibilité de créer des niveaux d'accès aux données JPA et des niveaux de persistance à travers le stockage
Hadoop - Job MapReduce basé sur la configuration du travail Hadoop de Spring et un modèle de programmation POJO
Key-Value - intègre Redis et Riak pour fournir des emballages simples dans plusieurs scénarios communs
Document - Intégrer les bases de données de documents: CouchDB et MongoDB et fournir une cartographie de configuration de base et une prise en charge de la bibliothèque
Graphique - NEO4J intégré pour fournir un puissant modèle de programmation basé sur Pojo
Graph Roo Addon - Prise en charge de Roo pour Neo4j
Extensions JDBC - prend en charge Oracle Rad, les files d'attente avancées et les types de données avancées
Mappage - Frame de cartographie d'objets à condition basé sur les grails, prenant en charge différentes bases de données
Exemples - Exemples de programmes, de documents et de bases de données de graphiques
Guidance - Documentation avancée
1. Introduction aux données de printemps JPA
Spring Data JPA est un cadre d'application JPA encapsulé par Spring basé sur le cadre ORM et les spécifications JPA, et fournit un ensemble complet de solutions de couche d'accès aux données.
2. Données de printemps Fonctions JPA
Spring Data JPA a des fonctions très puissantes. Ici, nous ignorons l'étape de construction de l'environnement et jetons un coup d'œil à la "douceur" de Spring Data JPA.
Spring Data JPA fournit aux utilisateurs les interfaces suivantes:
3. Interface JPA de données de printemps
1. Interface crudrepository
Créer une classe d'entité:
@Entity @Table (name = "User") public classe utilisateur {@id @genereatedvalue ID entier privé; // compte de chaîne privée compte; // Nom de la chaîne privée Nom; // mot de passe de mot de passe de chaîne privée; // Envoyez un e-mail à la chaîne privée e-mail; } Écrivez une interface et héritez de l'interface CruDrepository:
Interface publique UserRepository étend CruDrepository <utilisateur, entier> {} Écrivez une classe de test (pour voir l'effet plus intuitivement, toutes les classes de test n'utilisent pas d'affirmations et les instructions d'impression directement utilisées):
classe publique UserRepositoryTest {@autowired private userRepository dao; @ Test // Enregistrer public void testsave () {user user = new User (); user.setName ("chhliu"); user.setAccount ("10000"); user.setEmail ("chhliu @ .com"); user.setpassword ("123456"); dao.save (utilisateur); } @ Test // Enregistrer le public void testsave1 () {list <utilisateur> users = new ArrayList <User> (); Utilisateur utilisateur = nouveau utilisateur (); user.setName ("tanjie"); user.setAccount ("10000"); user.setEmail ("tanjie @ .com"); user.setpassword ("123456"); users.add (utilisateur); user = new User (); user.setName ("esdong"); user.setAccount ("10000"); user.setEmail ("esdong @ .com"); user.setpassword ("123456"); users.add (utilisateur); user = new User (); user.setName ("qinhongfei"); user.setAccount ("10000"); user.setEmail ("qinhongfei @ .com"); user.setpassword ("123456"); users.add (utilisateur); user = new User (); user.setName ("Huizhang"); user.setAccount ("10000"); user.setEmail ("Huizhang @ .com"); user.setpassword ("123456"); users.add (utilisateur); user = new User (); user.setName ("Caican"); user.setAccount ("10000"); user.setEmail ("caican @ .com"); user.setpassword ("123456"); users.add (utilisateur); dao.save (utilisateurs); } @ Test // met à jour public void TestupDate () {user user = dao.findOne (1); user.setpassword ("123890"); // Pour implémenter la fonction de mise à jour de cette manière, vous devez ajouter @Transaction Thing Annotation à la couche de service} @ test // Supprimer public void testDelete () {dao.delete (2); } @ Test // rejeter tous les publics publics testFindall () {list <serv> users = (list <utilisateur>) dao.findall (); System.out.println (JSON.TojSontring (utilisateurs)); } @ Test // interroge si l'objet ID spécifié existe publique Testisexist () {boolean isExist = dao.exists (8); System.out.println (isExist); } @ Test // Query public void testFindUserByids () {list <Integer> listides = new ArrayList <Integer> (); listIDS.Add (2); listIdS.Add (4); listIdS.Add (7); List <ser utilisateur> users = (list <utilisateur>) dao.findall (listides); System.out.println (JSON.TojSontring (utilisateurs)); }} Comme vous pouvez le voir, à ce stade, je n'ai écrit qu'une seule classe d'interface et je n'ai pas implémenté cette classe d'interface, afin que je puisse terminer l'opération CRUD de base. Parce que cette interface créera automatiquement des méthodes pour ajouter, supprimer, modifier et rechercher des objets de domaine, pour une utilisation directe de la couche commerciale.
L'interface est définie comme suit, et un total de 11 méthodes sont fournies, ce qui peut essentiellement répondre aux opérations de crud simples et aux opérations par lots:
@NorePositoryBean Interface publique CruDrepository <T, ID étend Serializable> étend le référentiel <T, id> {<s étend t> s Save (s entité); // Save <s étend t> itable <s> Itéable <t> findall (); // interroger tous les objets iTable <T> findall (iTable <id> ids); // interroger tous les objets basés sur la liste des id à long terme (); // calculer le nombre total d'objets void delete (id id); // delete void delete (t entity); // delete void Delete (itable <? Extend T> entités); DeleTeAll (); // Supprimer tout} 2. Interface PageandSortingRepository
L'interface PAGINETANDSORTINGREPOSITORY hérite de l'interface CruDrepository.
Écrire des interfaces et hériter de la pagination et une interface
Interface publique UserRepositoryWithOrder étend PagingandSortingRepository <utilisateur, entier> {} Écrire des classes de test:
@Runwith (springjunit4classrunner.class) @contextconfiguration (locations = {"classPath: applicationContext-config.xml"}) @transactionConfiguration (defaulTrollback = false) @Transactional public class userRepositoryWithOrdTest {@Autowired private userRepositoryWithOrder Dao; @Test public void testOrder () {sriet SORT = nouveau tri (direction.desc, "id"); Pagable Pagable = New PageRequest (0, 5, tri); Page <User> page = dao.findall (pagable); System.out.println (json.tojSontring (page)); System.out.println (page.getSize ()); }} Tant que vous héritez de cette interface, Spring Data JPA vous fournira déjà les fonctions de pagination et de tri. L'interface est définie comme suit, et deux méthodes sont fournies pour une utilisation, où t est la classe d'entité à utiliser et l'ID est le type de la clé primaire de la classe d'entité
@NorepositoryBean Interface publique PAGINGAndSortingRepository <T, ID étend Serializable> étend CruDrepository <T, ID> {Iteable <T> FindAll (tri Sort); // Trier sans pagination <T> FindAll (Pagable Pagable); // Trier avec la pagination} 3. Interface JParePository
Si l'entreprise doit fournir des opérations CRUD et également fournir des fonctions de pagination et de tri, vous pouvez hériter directement de cette interface. Cette interface hérite de l'interface PAGINEANDSORTINGREPOSITORY.
L'interface est définie comme suit:
Interface publique JParepository <T, ID étend Serializable> étend PAGINYAndSortingRepository <t, id> {list <t> findall (); // remettre tous les objets, ne pas trier la liste <T> findall (tri (tri); // requérir tous les objets, et le tri <s étend T> List <s>; Synchronise avec la base de données t SAVEAndFlush (entité t); // Enregistrer et force à synchroniser void DeleteInBatch (iTable <T> Entités); // Batch Delete void DeletealLinbatch (); // Supprimer tout} 4. Interface JPaspecificationExecutor
Cette interface fournit une prise en charge des requêtes de critères JPA. Notez que cette interface est très spéciale et n'appartient pas au système de référentiel. Les données de printemps JPA ne scanneront pas et ne reconnaîtront pas automatiquement, de sorte que le haricot correspondant ne sera pas trouvé. Nous n'avons qu'à hériter de toute sous-interface qui hérite du référentiel ou hériter directement de l'interface du référentiel. Spring Data JPA analysera automatiquement et reconnaîtra et effectuera une gestion unifiée.
L'interface est écrite comme suit:
Interface publique SpécificationExEcutorRepository étend CruDrepository <utilisateur, entier>, jpaspecificationExecutor <ser utilisateur> {} Classe de service:
@Service public class SpecificationExECutorRepositoryManager {@Autowired Private SpecificationExECutorRepository DAO; / ** * Description: Interrogez l'utilisateur en fonction du nom * / utilisateur public finseserByName (nom de chaîne finale) {return dao.findOne (new Specification <User> () {@Override Public Predicate Topricedicate (root <ser> root, criteriaQuey <?> Query, criteriAbuilder cb) {prédicat = cb.equal (root.get ("nue"); }); } / ** * Description: Interrogez l'utilisateur en fonction du nom et de l'e-mail * / utilisateur public findUserByNameAnDemail (Nom de la chaîne finale, e-mail de chaîne finale) {return dao.findOne (new Specification <User> () {@Override Public Predicateddicate (root <user> root, criteriaQuel <?> Newery, craiRiaLder CB) {list <prédicate> list = list = list = prédate <);); Prédication prédictive1 = CB.Equal (root.get (nom "), Nom); } / ** * Description: Force de combinaison * / utilisateur public FindUserByUser (user userVo final) {return dao.findOne (new Specification <User> () {@Override Public Predicate Topricedicate (root <User> root, criteriaQuey <?> Query, CriteriAbuilder CB) {prédicat = cb.equal (root.get ("nue"), uservo.getName ()); } / ** * Description: Range Requête dans la méthode, tels que l'interrogation de l'utilisateur avec l'ID utilisateur dans [2,10] * / public List <Derser> FindUserByIds (Final List <Integer> IDS) {return dao.findall (nouvelle spécification <User> () {@Override Public Predicat TopRedicate (Root <user> Root, criteriaquery <?> Query, CriterIaBuder CB) root.in (ids);}}); } / ** * Description: Range Requête GT Méthode, tels que l'interrogation à tous les utilisateurs avec l'ID utilisateur supérieur à 9 * / publique <utilisateur> findUserBygTid (final int id) {return dao.findall (nouvelle spécification <User> () {@Override Public Predicat TopRedicate (root> root, critère <?> cb.gt (root.get ("id"). as (Integer.class), id);}}); } / ** * Description: Range Query Lt Method, tels que l'interrogation des utilisateurs avec l'ID utilisateur de moins de 10 * / public List <Derser> findUserByltid (final int id) {return dao.findall (nouvelle spécification <User> () {@Override Public Predicat TopRedicate (root <user> root, critère <?> Query, critère-ibuilder CB) {retour cb.lt (root.get ("id"). as (Integer.class), id);}}); } / ** * Description: Requête de plage entre des méthodes, telles que l'interrogation des utilisateurs avec des ID entre 3 et 10 * / / public <utilisateur> finduserBetweId (final int start, final int end) {return dao.findall (new specific <user> () {@Override public Predicat topRedicate (root <user> root, criteriaquey <?> Query, critère cb.between (root.get ("id"). as (Integer.class), start, end);}}); } / ** * Description: Opérations de tri et de pagination * / PAGE PUBLIQUE <DERSER> FINDUSERANDORD (Final int id) {SORT SORT = NOUVEAU SORT (Direction.DESC, "ID"); return dao.findall (new Specification <User> () {@Override Public Predicate Topricatedicate (root <User> root, criteriaQuery <?> Query, criteriAbuilder cb) {return cb.gt (root.get ("id"). as (Integer.class), id);}}, new pagerequest (0, 5, sart)); } / ** * Description: Opérations de tri uniquement * / Liste publique <User> findUserAndordersEnondMethod (final int id) {return dao.findall (new Specification <User> () {@Override Public Predicateddicate (root <User> root, criteriaQuery <?> Query, critère CB) { cb.gt (root.get ("id"). As (Integer.class), id); }} Classe de test:
@Runwith (springjunit4classrunner.class) @contextConfiguration (Locations = {"classPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DefaulTrollback = false) @Transactional Public Class SpecificationExECUTORREOSPOSITORYMANGEREST; @Test public void TestFindUserByName () {user user = manager.finDuserByName ("chhliu"); System.out.println (JSON.TojSontring (utilisateur)); } @Test public void testFinDuserByNameAnDemail () {user user = manager.finSuserByNameAnDemail ("chhliu", "chhliu @ .com"); System.out.println (JSON.TojSontring (utilisateur)); } @Test public void testFindUserByUserVo () {utilisateur utilisateur = new User (); user.setName ("chhliu"); user.setEmail ("chhliu @ .com"); User u = manager.finSuserByUser (utilisateur); System.out.println (JSON.TojSontring (U)); } @Test public void testFindUserByIDS () {list <user> users = manager.finSUserByIds (new ArrayList <Integer> (arrays.aslist (1,3,5,6))); System.out.println (JSON.TojSontring (utilisateurs)); } @Test public void testFindUserBygTid () {list <serv> users = manager.finDuserByGtid (5); System.out.println (JSON.TojSontring (utilisateurs)); } @Test public void testFindUserBylTid () {list <serv> users = manager.finDuserByltid (5); System.out.println (JSON.TojSontring (utilisateurs)); } @Test public void testFinSUserBetweenId () {list <serv> users = manager.finSUserBetweenId (4, 9); System.out.println (JSON.TojSontring (utilisateurs)); } @Test public void testFindUserAndOrder () {page <utilisateur> utilisateurs = manager.finUserAndOrder (1); System.out.println (JSON.TojSontring (utilisateurs)); } @Test public void testFindUserAndordersEnondMethod () {list <serv> users = manager.finSuSerAndordersEcondMethod (1); System.out.println (JSON.TojSontring (utilisateurs)); }} 5. Interface du référentiel
Cette interface est l'interface la plus élémentaire, c'est juste une interface emblématique, et aucune méthode n'est définie, alors quelle est l'utilisation de cette interface? Étant donné que Spring Data JPA fournit cette interface, elle est bien sûr utile. Par exemple, certaines méthodes que nous ne voulons pas fournir à l'extérieur. Par exemple, nous voulons seulement fournir des méthodes d'addition et de modification et non des méthodes de suppression, alors les interfaces précédentes ne peuvent pas le faire. À l'heure actuelle, nous pouvons hériter de cette interface et copier les méthodes correspondantes dans l'interface CruDrepository à l'interface du référentiel.
Résumé: Comment les développeurs devraient-ils choisir les cinq interfaces ci-dessus? En fait, la base est très simple. Choisissez l'un d'eux en fonction des besoins commerciaux spécifiques. Parce qu'il n'y a pas de problème de force et de force entre chaque interface.
4. Données de printemps JPA Query
1. Créez une requête en utilisant @Query
L'utilisation de l'annotation @Query est très simple. Il vous suffit d'étiqueter l'annotation sur la méthode déclarée et de fournir une instruction de requête JP QL. De nombreux développeurs aiment utiliser des paramètres nommés au lieu de numéros de position lors de la création de JP QL, et @Query fournit également une prise en charge de cela. Dans l'instruction JP QL, les paramètres sont spécifiés via le format de ": variable", et en même temps, @param est utilisé devant les paramètres de la méthode pour correspondre aux paramètres nommés dans JP QL. De plus, les développeurs peuvent également effectuer une opération de mise à jour en utilisant @Query. Pour ce faire, nous devons utiliser @Modifier pour identifier l'opération en tant que requête modifiée lors de l'utilisation de @Query, afin que le framework génére finalement une opération mise à jour, pas une opération de requête.
Écrivez une interface comme suit:
/ ** * Description: Requête personnalisée. Lorsque Spring Data JPA ne peut pas fournir, une interface personnalisée est requise. Cette méthode peut être utilisée à l'heure actuelle * / interface publique UserDeFineByself étend JParePository <utilisateur, entier> {/ ** * Paramètres nommés * Description: Il est recommandé d'utiliser cette méthode, vous pouvez ignorer l'emplacement des paramètres * / @Query ("Sélectionner U From User U Where U.Name =: Name") utilisateur FindUseryName (@Param ("Name") String); / ** * Paramètres d'index * Description: Utiliser? Payholder * / @Query ("Sélectionnez U depuis l'utilisateur U où u.email =? 1") // 1 indique le premier paramètre utilisateur finseUserByEmail (chaîne e-mail); / ** * Description: Les mises à jour peuvent être réalisées via @Modifier et @ query * Remarque: La valeur de retour des requêtes de modification ne peut être que vide ou int / enter * / @moditify @Query ("Update User U set u.Name =: Name Where U.ID =: id") int updateSerbyid (@param ("name") String name, @param ("") int id); } Remarque: @moditify annotation a une configuration claire-uutomatiquement
Il indique que le contexte de persistance sous-jacent peut être effacé, qui est la classe EntityManager. Nous savons que l'implémentation sous-jacente de JPA aura un cache secondaire, c'est-à-dire après la mise à jour de la base de données, si vous utilisez cet objet plus tard, vous vérifierez l'objet. Cet objet est mis en cache au premier niveau, mais il n'est pas synchronisé avec la base de données. À l'heure actuelle, ClearAutoMatal = True sera utilisé pour actualiser le premier cache de niveau d'hibernate. Sinon, vous metterez à jour un objet dans la même interface, puis vous interrogez cet objet, puis l'objet que vous avez trouvé est toujours l'état précédent qui n'a pas été mis à jour auparavant.
Classe de test:
@Runwith (springjunit4classrunner.class) @contextconfiguration (locations = {"classpath: applicationContext-config.xml"}) @transactionConfiguration (DefaulTrollback = false) @Transactional public class userDefineByselftest {@autowired privateddefineByself dao; @Test public void TestFinDuserByName () {user user = dao.findUserByName ("chhliu"); Assert.asserTequals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void testFindUserByEmail () {user user = dao.finDuserByEmail ("chhliu @ .com"); Assert.asserTequals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void TESTUPDATEUSERBYID () {dao.upDateUserById ("Tanjie", 4); }} À partir du code de test, nous pouvons voir que nous définissons l'interface, sans aucune classe d'implémentation, mais implémentons les fonctions dont nous avons besoin.
2. Créez une requête en utilisant @NamedQueries
La question nommée est une fonction fournie par JPA qui sépare les instructions de requête du corps de la méthode pour partager plusieurs méthodes. Spring Data JPA fournit également un bon support pour les requêtes nommées. Les utilisateurs doivent uniquement définir l'instruction de requête dans le fichier ORM.XML ou dans le code en fonction de la spécification JPA. La seule chose qu'ils doivent faire est de respecter les règles de dénomination de "DomainClass.MethodName ()" lors de la dénomination de la déclaration.
Rédaction d'une interface:
Interface publique FindUserByNameDqueryRepository étend JParePository <utilisateur, entier> {utilisateur finseserWithName (@param ("name") Nom de chaîne); } Écrire une classe:
@Entity @NameDquery (value = {@NameDquery (name = "user.finDuserWithName", query = "SELECT U FROM User U Where U.Name =: Name")}) // Remarque: S'il existe plusieurs méthodes ici, vous devez utiliser @NameDquery. S'il n'y a qu'une seule méthode, vous pouvez utiliser @NameDquery. La méthode d'écriture est la suivante: @NameDquery (name = "user.finSuserWithName", query = "select u from user u where u.name =: name") public class finserUserByNameDquery {/ ** * note: cette classe d'entité doit être définie ici, sinon une exception sera signalée * / @id @generatedvalue private INGER ID; } Remarque: Les pièces marquées en rouge dans l'article doivent correspondre une par une, sinon elles ne respecteront pas les spécifications JPA.
Classe de test:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Locations = {"ClassPath: ApplicationContext-Config.xml"}) @transactionConfiguration (DefaulTrollback = false) @Transactional Public Class FindUserByNameDeReryRepository; @Test public void TestFindUserByName () {user user = dao.findUserWithName ("caican"); System.out.println (JSON.TojSontring (utilisateur)); }} 3. Créez une requête en analysant le nom de la méthode
Comme son nom l'indique, il s'agit de créer une requête basée sur le nom de la méthode. Peut-être que cela semble incroyable au début, mais après les tests, j'ai trouvé que tout est possible.
Rédaction d'une interface:
L'interface publique SimpleConditionQueryRepository étend JParePository <utilisateur, entier> {/ ** * Description: Selon les règles définies par les données de printemps, la méthode de requête commence par Find | Read | Get * En ce qui concerne la requête conditionnelle, les propriétés de la condition sont connectées à des mots clés conditionnels. Il convient de noter que: La première lettre de l'attribut conditionnel doit être en maîtrelle maîtresse * / / ** * Remarque: Cette interface ici est équivalente à l'envoi d'un SQL: Sélectionnez U From User U Where U.Name =: Name et U.Email =: Email Nom du paramètre est Liste * / utilisateur findByNameAnDemail (nom de chaîne, courriel de chaîne); / ** * Remarque: Cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U From User U Where U.Name =? 1 ou U.Password =? 2 * / list <serv> findByNameorPassword (nom de chaîne, mot de passe de chaîne); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Id entre? 1 et? 2 * / list <ser utilisateur> findByIdBetween (start Integer, End End); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Id entre? 1 et? 2 * / list <ser utilisateur> findByIdBetween (start Integer, End End); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur u où u.id <? 1 * / list <utilisateur> findByIdlessThan (End End); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.ID>? 1 * / List <Derser> findByIdGreaterThan (start Integer); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Name est null * / list <ser utilisateur> findByNameisnull (); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Name n'est pas null * / list <utilisateur> findByNameisNotNull (); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur u où nous sommes comme? 1 * / list <utilisateur> findByNameLike (nom de chaîne); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où nous ne commette pas? 1 * / list <utilisateur> findByNaMenotLILY (nom de chaîne); / ** * Remarque: Cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Password =? 1 Commande par U.ID DESC * / List <Derser> findByPasswordOrderByIdDesc (String Motway); / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: sélectionnez U depuis l'utilisateur u où nous / ** * Remarque: cette interface ici équivaut à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur u où u.id in? 1 * / list <ser utilisateur> findByIdin (list <Integer> ids); / ** * Remarque: cette interface ici est équivalente à l'envoi d'un SQL: Sélectionnez U depuis l'utilisateur U où U.Id Not in? 1 * / List <Derser> findByIdNotin (list <Integer> ids); } Classe de test (la pièce de commentaire est l'instruction SQL envoyée réelle):
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Locations = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DefaulTrollback = false) @Transactional Public Class SimpleconditionQueryrepositoryTest {@Autowired Private SimlePlexonDITIERQUIRERVERTORYE; / ** * Sélectionnez user0_.id en tant qu'id0_, user0_.account en tant que compte0_, user0_.email as e-mail0_, user0_.name as name0_, user0_.password as Password0_ from user 0, where user0_.name =? et user0_.email =? limiter? * / @Test public void TestFinDuserByNameAnDemail () {utilisateur utilisateur = dao.findByNameAnDemail ("chhliu", "chhliu @ .com"); System.out.println (JSON.TojSontring (utilisateur)); } / ** * Sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password as password1_ from user0_ where user0_.name =? ou user0_.password =? * / @Test public void testFindUserByNameorPassword () {list <user> users = dao.findByNameorPassword ("chhliu", "123456"); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password en tant que mot de passe1_ de l'utilisateur user0_ où user0_.id entre? et ? * / @Test public void TestFindByIdBetween () {list <serv> users = dao.findbyidbetween (5, 8); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password as password1_ from user0_ where user0_.id <? * / @Test public void testFindByIdlessThan () {list <serv> users = dao.findbyidlessThan (4); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id en tant qu'id0_, user0_.account en tant que compte0_, user0_.email as e-mail0_, user0_.name as name0_, user0_.password en tant que mot de passe0_ de l'utilisateur user0_ où user0_.id>? * / @Test public void TestFindByIdGreaterThan () {list <utilisateur> utilisateurs = dao.findByIdGreaterThan (6); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez User0_.id As ID0_, User0_.Account en tant que compte0_, user0_.email As Email0_, user0_.name as name0_, user0_.password as password0_ from user0_ where user0_.name est null * / @test public Void testFindBameisnull () {list <user> users = dao.finds System.out.println (JSON.TojSontring (utilisateurs)); } / ** * sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password en tant que mot de passe1_ à partir de l'utilisateur user0_ où user0_.name n'est pas null * / @test public Void testFindNameisNoTNull () {list <user> userst users dao.findByNameisnotnull (); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password en tant que mot de passe1_ de l'utilisateur user0_ où user0_.name comme? * / @Test public void TestFindByNameLike () {list <user> users = dao.findByNamelike ("chhliu"); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id en tant qu'id0_, user0_.account en tant que compte0_, user0_.email as e-mail0_, user0_.name as name0_, user0_.password comme mot de passe0_ de l'utilisateur user0_ où user0_.name ne comme? * / @Test public void testFindByNameNotLIVIL () {list <serv> users = dao.findByNameNotLILY ("chhliu"); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id en tant qu'id0_, user0_.account en tant que compte0_, user0_.email as e-mail0_, user0_.name as name0_, user0_.password en tant que mot de passe0_ de l'utilisateur user0_ où user0_.password =? Ordre par user0_.id desc * / @test public void testFindByPasswordOrderByIdDesc () {list <utilisateur> users = dao.findByPasswordOrderByIdDesc ("123456"); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id as id1_, user0_.account en tant que compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password en tant que mot de passe1_ de l'utilisateur user0_ où user0_.name <>? * / @Test public void testFindByNenot () {list <user> users = dao.findByNameNot ("chhliu"); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionnez user0_.id as id1_, user0_.account as compte1_, user0_.email as e-mail1_, user0_.name as name1_, user0_.password as password1_ from user0_ where user0_.id in (? ,? ,?) * userst ArrayList <Integer> (arrays.aslist (3,4,6,8))); System.out.println (JSON.TojSontring (utilisateurs)); } / ** * Sélectionner user0_.id as id0_, user0_.account en tant que compte0_, user0_.email as e-mail0_, user0_.name as name0_, user0_.password en tant que mot de passe0_ de l'utilisateur user0_ where user0_.id not in (? ,?,?) * / userS dao.findByIdNotin (New ArrayList <Integer> (arrays.aslist (3, 4, 6, 8))); System.out.println (JSON.TojSontring (utilisateurs)); }} Ici, nous ne définissons qu'une seule interface. Il n'y a que des méthodes dans l'interface, mais il n'y a pas d'implémentation, mais diverses opérations sont terminées.
Après avoir vu cela, beaucoup de gens demanderont probablement, comment les données de printemps ont-elles fait JPA? Il s'avère que lorsque le cadre analyse le nom de la méthode, il interceptera d'abord les préfixes excédentaires du nom de la méthode, tels que Find, Findby, Read, Readby, Get, Getby, puis analyser la partie restante. Et si le dernier paramètre de la méthode est en nature ou un type pagable, les informations pertinentes seront également extraites pour le tri ou la requête de pagination par des règles. Lors de la création d'une requête, nous l'exprimons en utilisant des noms d'attribut dans le nom de la méthode, tels que findByIdin (). Lorsque le cadre analyse cette méthode, il élimine d'abord Findby puis analyse les attributs restants.
Lors de l'interrogation, il est généralement nécessaire de s'interroger en fonction de plusieurs attributs en même temps, et les conditions de requête sont également de formats différents (supérieure à une certaine valeur, dans une certaine plage, etc.). Spring Data JPA fournit quelques mots clés pour exprimer une requête conditionnelle, à peu près comme suit:
Et --- l'équivalent du mot clé et de SQL, tel que findByUserAmandPassword (utilisateur de la chaîne, Striang Pwd)
Ou --- équivalent ou mots clés dans SQL, tels que findByUserNameorAddress (Utilisateur de chaîne, String addr)
Entre --- le mot-clé équivalent à SQL, comme FindBysalaryBetween (int max, int min)
MOINSTHAN --- Équivalent à "<" dans SQL, comme FindBysalarylessthan (int max)
Plus grande --- équivalent à ">" dans SQL, comme FindBysalaryGreaterThan (int min)
ISNULL --- équivalent à "est nul" dans SQL, comme FindByUserNameisnull ()
ISNOTNULL --- équivalent à "n'est pas nul" dans SQL, comme FindByUsernameisnotnull ()
Notnull --- équivalent à Isnotnull
Comme --- équivalent à "like" dans SQL, comme FindByUserAmElike (utilisateur de chaîne)
Not comme --- équivalent à "pas comme" dans SQL, comme findbyUserAnotLILLy (Utilisateur de chaîne)
OrderBy ---- équivalent à "Order by" en SQL, comme findByUserNameOrderBysalaryAsC (utilisateur de chaîne)
Pas --- équivalent à "! =" Dans SQL, par exemple, findByUserAnNot (Utilisateur de chaîne)
Dans --- équivalent à "in" in sql, tel que findByUserNameIn (collection <string> userList). Les paramètres de la méthode peuvent être de type de collecte, ou un tableau ou un paramètre de longueur indéfini.
Nottin --- équivalent à "Not In" en SQL, tel que FindByUserAnnotin (Collection <string> UserList). Les paramètres de la méthode peuvent être de type de collecte, ou un tableau ou un paramètre de longueur indéfini.
5. L'ordre de création de requêtes
Lors de la création d'un objet proxy pour une interface, s'il constate que plusieurs des situations ci-dessus sont disponibles en même temps, quelle stratégie devrait-elle adopter en premier? Pour ce faire, <JPA: Repositories> fournit la propriété Query-Lookup-Strategy pour spécifier l'ordre des recherches. Il a les trois valeurs suivantes:
Créer --- Créez une requête en résolvant le nom de la méthode. Même s'il y a une question nommée correspondante ou l'instruction de requête spécifiée par la méthode via @Query, elle sera ignorée.
create-if-not-fond --- Si la méthode spécifie une instruction de requête via @Query, la requête est implémentée; Sinon, il est constaté si une requête nommée qui répond aux critères est définie, si elle est trouvée, la requête nommée est utilisée; Si aucun n'est trouvé, la requête est créée en analysant le nom de la méthode. This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
Careful readers may see some clues from the above code. When we use Spring data JPA, we just define the interface. When using it, we can just inject it directly, and we do not do any processing related to things. But in fact, things have already achieved results. Pourquoi est-ce?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.