Implémenter une requête conjointe multi-table
Ou créer une nouvelle classe de site Web dans le package David.mybatis.Model pour persister les données et réécrire la méthode TOSTRING () correspondante pour faciliter l'utilisation des programmes de test.
package david.mybatis.model; import java.text.simpledateFormat; import java.util.date; site Web de classe publique {private int id; nom de chaîne privé; Int privé VisitorId; Statut int privé; Date privée CreateTime; visiteur privé; Public Site Web () {// Todo Auto-Generated Constructor Stub CreateTime = new Date (); Visiteur = nouveau visiteur (); } site Web public (nom de chaîne, int visitorId) {this.name = name; this.VisitorId = VisitorId; Visiteur = nouveau visiteur (); status = 1; createTime = new Date (); } public int getID () {return id; } public void setid (int id) {this.id = id; } Visiteur public getVisitor () {return Visitor; } public void setVisitor (visiteur visiteur) {this.visitor = visiteur; } public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } public int getStatus () {return status; } public void setStatus (int status) {this.status = statut; } public Date getcreatetime () {return CreateTime; } public void setCreateTime (date CreateTime) {this.createtime = CreateTime; } public int getVisitorId () {int id = 0; if (visiteur == null) id = visitorId; else id = visitor.getId (); Retour ID; } public void setVisitorId (int visitorId) {this.VisitorId = visitorId; } @Override public String toString () {StringBuilder sb = new StringBuilder (string.format ("site Web => {id:% d, name:% s, createTime:% s} / r / n", id, nom, new simledateFormat ("yyyy-mm-dd hh: mm: ss"). Format (CreateTime))); if (visiteur! = null) sb.append (string.format ("visiteur =>% s", visitor.toString ())); return sb.toString (); }}Créez les interfaces d'opération correspondantes sous David.mybatis.demo:
package david.mybatis.demo; import java.util.list; import david.mybatis.model.website; interface publique iwebsiteoperation {public int add (site Web site Web); public int Delete (int id); Public Int Update (site Web du site Web); Query du site Web public (int id); LISTE PUBLIQUE <SIDEAU> GETLIST (); }Créez un nouveau fichier de mappage de sites WebSitEmapper.xml dans le dossier du mappeur et reportez-vous à la précédente pour ajouter, supprimer, modifier et vérifier la configuration de l'opération de table unique, afin que vous puissiez créer des données de test. comme suit
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mappep Public "- // Mybatis.org//dtd Mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><Mapper namespace = "david.mybatis.demo.iwebsiteoperation"> <sql id = "getListsql"> Sélectionner ID, nom, visitorId, statut, createTime à partir du site Web où le statut> 0 </ql> <insert id = "Add" ParameterType = "Site Web" useGeneratedKey VALEURS (# {name}, # {VisitorId}, # {status}, # {CreateTime}) </serser> <delete id = "Delete" ParameterType = "int"> Delete du site Web où status> et id = # {id} </ delete> <update id = "Update" ParametType = "site Web"> SETT de mise à jour Nom = # # # # #} Where Status> 0 et le site Web = "Site Web Set Set Name = # # # # #} Where Status> 0 et 0e site Web"> Site Web de mise à jour Set Name = # # # # #} WHERE STATRACT> 0 ET STAT id = # {id} </ update> <select id = "query" ParameterType = "int" resultmap = "sites Web"> select sitee.id SiteId, webswame.name sitename, visitor.id VisitorId, visitor.name VisitorName interne et site Web.id = # {id} </ select> <resultMap type = "site Web" id = "sites Web"> <id column = "siteID" propriété = "id" /> <result Column = "SitEname" Property = "name" /> <result Column = "Sitestatus" Property = "Status" /> <Resulter Column = "SITecreatEtime" Property = "Createtime" /> <Association Property = "Visitor" javatype = "visitor" resultMap = "Visitorrs" /> </ résultatmap> <resultmap type = "Visitor" id = "Visitorrs"> <id Column = "VisitorId" propriété = "id" /> <result Column = "visiter" /> </ select> </ mapper>Ce dont nous parlons principalement aujourd'hui, c'est la recherche. Maintenant, nous voulons interroger le site Web et retirer les informations correspondantes des visiteurs ensemble. Comment faire? Vous pouvez vous référer à la requête dans la configuration et noter le SQL pour la requête de la table de liaison.
La principale chose à noter ici est que les deux propriétés d'identification et de nom dans l'entité du site Web et l'entité de visite sont les mêmes. Par conséquent, afin d'éviter les erreurs de mappage, énumérez les résultats de la requête correspondants avec différents alias, afin qu'il puisse être évité lors de la liaison.
Qu'obtiendrais-je si je le configure comme ce qui suit?
<select id = "query" ParameterType = "int" resultMap = "Websiter"> select sitee.id, webswame.name sitename, Visitor.id, visitor.name VisitorName, sitee.status Sitestatus, site Web.createTime SitEcreateTime à partir du site Web Inner Rejoignez le visiteur sur site Web.visity. Website.id = # {id} </lect> <resultMap type = "site Web" id = "sites Web"> <id chronn = "id" propriété = "id" /> <résultat column = "status" statut " javatype = "visitor" resultMap = "Visitorrs" /> </ résultatmap> <resultmap type = "Visitor" id = "Visitorrs"> <id Column = "id" Property = "id" /> <result Column = "VisitorName" Property = "Name" /> </ ResultMap> Avez-vous remarqué que l'ID du visiteur est également devenu 2. En fait, il cartographier l'ID du site Web par défaut, car le résultat de la requête de l'énoncé SQL est devenu 2. Certaines personnes peuvent demander pourquoi elle n'est pas 4, car elle correspond par par défaut le premier. Si vous changez les emplacements de Site Web.id et Visit.id, vous constaterez que le résultat a à nouveau changé par magie.
Vous devez donc donner un alias pour éviter cette situation, vous constaterez donc qu'il n'y a en fait qu'une seule vérité, qui est la suivante:
Vous pouvez voir que la méthode de traitement multi-tables ResultMap est la même que celle des tables uniques. Ce n'est rien de plus que de répertorier le nom de l'attribut Javabean. Vous pouvez voir qu'il existe un autre résultat dans la réception dans le nœud <SultMap> du site Web. Il représente l'entité qui doit être mappée par l'entité visiteuse. Vous pouvez utiliser la méthode suivante pour créer des associations.
<association propriété = "Visitor" javatype = "Visitor" resultMap = "Visitorrs" />
Le visiteur est le nom du champ de visite dans l'entité du site Web. Le nom doit être cohérent. Sinon, une exception de ce n'est pas un getter pour la propriété nommée 'xxx' dans 'Class David.mybatis.model.website' sera lancée. Cela a été décrit dans les chapitres précédents. Bien sûr, si vous pensez qu'il est acceptable de ne pas nidmap de résultat, la nidification est également due au fait que cette configuration peut être utilisée ailleurs, elle sera extraite, ce qui est également une idée abstraite. Utilisez l'ID et résultats dans <SultMap> pour trouver les différences correspondantes par rapport au site officiel: http://mybatis.github.io/mybatis-3/sqlmap-xml.html#result_maps
De cette façon, une simple requête conjointe multi-table sera publiée. S'il y a des frais de requête plus complexes, certaines modifications seront apportées à cela.
Logique d'effet de pagination
Ce que nous voulons parler, c'est le problème de pagination que nous rencontrons souvent dans un problème commercial. Lors du développement de projets Web, nous utilisons souvent l'affichage de la liste. Généralement, nous utilisons des contrôles de liste couramment utilisés, tels que les données (je me sens personnellement très bien), et les commandes de table encapsulées sous une interface utilisateur facile.
Idée: Pour réaliser l'effet de la pagination dans ces contrôles, nous passons généralement 2 paramètres. La première consiste à représenter l'index de la page actuelle (à partir généralement de 0), la seconde consiste à représenter le nombre d'enregistrements commerciaux affichés sur la page actuelle, puis à transmettre les paramètres correspondants à la méthode List <T> GetList (PagenatEargs Args). Lorsque vous implémentez enfin la pagination dans la base de données, nous pouvons utiliser le mot-clé limite (pour MySQL) pour la pagination. S'il s'agit d'un serveur Oracle ou SQL, ils ont tous leur propre fonction Rownum à utiliser.
Pour aborder les idées ci-dessus, tout d'abord, nous devons créer une nouvelle classe d'entité de paramètre de page nommée Pagenateargs sous Demo.mybatis.model comme toujours, et une classe d'énumération nommée SortDirectionEnum, qui contient la page d'index de page actuelle, la page d'affichage de la page actuelle PageSize, et l'attribution de Pagestart indique de l'élément. (PAGESTART = PAGEIDEX * PAGESIZE) Parce que l'utilisation du mot-clé limite est de représenter [Limit Start Number (non inclus), prenez quelques éléments], champ de tri de commande de commandes, direction de tri OrderDirectionstr, de sorte que la création spécifique est la suivante:
Package David.Mybatis.Model;
/ * * Pagination Paramètre Classe d'entité * / Classe publique Pagenateargs {private int pageIndex; Private int pagesize; Int privé Pagestart; String Private StringFielDstr; String private orderDirectionstr; public pagenateargs () {// TODO Auto-généré de constructeur Stub} public pagenateargs (int pageIndex, int pagesize, chaîne d'ordres. this.pagesize = pagesize; this.OrderFielDstr = orderFielDstr; this.OrderDirectionstr = OrderDirectionstr; Pagestart = PageIndex * PageSize; } public int getPageIndex () {return pageIndex; } public int getPAGEstart () {return Pagestart; } public int getPageSize () {return pagesize; } public String OrderFielDSTR () {return orderFielDstr; } public String getOrderDirectionSTR () {return orderDirectionstr; }} package david.mybatis.model; / * * Trier enum * / public Enum sortDirectionENUM {/ * * ascendant * / asc, / * * Descending * / desc}Après avoir terminé les étapes ci-dessus, nous continuons d'ajouter une méthode Liste publique <Sisitor> getListBypagenate (Pagenateargs args) à la classe d'interface IvisitorOperation. Dans les chapitres précédents, nous avons déjà la méthode GetList. Cette pagination est en fait juste un petit changement basé sur cela. Une fois la classe d'interface IvisitorOperation modifiée, c'est le suivant:
Package David.mybatis.demo; Import Java.util.list; import david.mybatis.model.pagenateargs; import david.mybatis.model.visitor; import david.mybatis.model.visitorwithrn; interface publique ivisitoroperme {/ * * Basic Query * / Visitor publique BasicQuery (int id); / * * Add Visitor * / public int Add (Visitor Visitor); / * * Supprimer le visiteur * / public int Delete (int id); / * * Mise à jour Visitor * / public int mettrate (visiteur visiteur); / * * Requête Visitor * / Public Visitor Query (int id); / * * Liste de requête * / Liste publique <Sisitor> getList (); / * * Liste des requêtes de pagination * / Liste publique <Sisetor> getListBypageNate (pagenateargs args); }Ensuite, nous devons commencer à modifier notre fichier de configuration VisitorMapper.xml, ajouter un nouveau type d'ID de nœud <lect> pour le configurer en fonction des chapitres précédents. Le nouvel ID ajouté ici est GetListBypagenate. Après la configuration, ce qui suit
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mappep Public "- // Mybatis.org//dtd Mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><Mapper namespace = "david.mybatis.demo.ivisitoroperation"> <! - useGeneratedKeys = "true" signifie s'il faut utiliser une séquence d'auto-croissance, keyproperty = "id" spécifie quelle colonne est la colonne de croissance, paramètreType = "Visitor" - Ajout de "INSERTER IDSERS dans la définition dans l'interface IVisitorOper ParameterType = "Visitor" useGeneratedKeys = "true" keyproperty = "id"> insérer dans le visiteur (nom, e-mail, statut, createTime) (# {name}, # {email}, # {status}, # {CreateTime}) </ insert> <supprimer id = "Delete" ParamEterType = "int"> delete # {id} </ delete> <update id = "update" ParameterType = "Visitor"> Mise à jour le set du visiteur Nom = # {name}, e-mail = # {email}, status = # {status} où id = # {id} et status> 0; </datedate> <sélectionnez id = "query" ParameterType = "int" resultType = "Visitor"> SELECT ID, nom, e-mail, statut, CreateTime depuis Visitor où id = # {id} et status> 0 Commande par id </lect> <sélectionnez id = "BasicQuery" ParamEterType = "int" ResultType = "Visitor"> SELECT * FROM VOIR </ select> <select id = "getList" resultMap = "Visitorrs"> <inclure refid = "getListsql" /> </lect> <sql id = "getListSQL"> SELECT * From Visitor où le statut> 0 </ql> <! - Ce qui suit est une nouvelle partie pour la pagination. L'OrderBysQL est extrait par exemple réutiliser plus tard-> <resultMap type = "Visitor" id = "Visitorrs"> <id Column = "id" Property = "id" /> <le résultat Column = "name" Property = "name" /> <result Column = "Courriel" Property = "Email" /> <Result Column = "Status" Property = "Status" /> <Result Column = "CreateTime" Property = "CreatEIM </sultMap> <sélectionnez id = "getListBypageNate" ParameterType = "PageNateargs" resultType = "Visitor"> SELECT * FROM (<include refId = "getListSQL" /> <include refid = "orderBysql" />) T <! - # {} signifie la sortie paramétrée, $ {} signifie directement les opérations d'évacuation, les opérations de paramétrie pour le transfert, c'est le paramétrie, $ {} signifie directement test = "Pagestart> -1 et pagesize> -1"> limite # {pagestart}, # {pagesize} </ if> </lect> <sql id = "OrderBysQl"> Order par $ {OrderFieldstr} $ {OrderDirectionstr} </ql> </1 / Masper>Vous trouverez des configurations similaires dans la figure ci-dessous. Les attributs de champ ici sont tous cohérents avec les noms d'attribut dans la classe de paramètres PagenatEargs.
<if test = "Pagestart> -1 et pagesize> -1"> limite # {Pagestart}, # {pagesize} </ if>Créez une méthode de test dans la classe Demorun:
/ * * Paramètres de pagination * / public static void queryVisitorListwithPageNate (int pageIndex, int pagesize, String orderField, String OrderDire) {pagenateargs args = new pagenateargs (pageIndex, pagesize, ordonnance, ordonnance); SESSESSE SQLSESSION = MyBatisUtils.getsQlSession (); IVisitorOperation Voperation = session.getMapper (iVisitorOperation.class); List <Visitor> visiteurs = voperation.getListBypageNate (args); pour (visiteur visiteur: visiteurs) {System.out.println (visiteur); } Mybatisutils.closeSession (session); Mybatisutils.showmessages (crud_enum.list, visiteurs.size ());}Demorun.QueryVisitorListwithPagenate (0, 100, "id", sortDirectionEnum.desc.ToString ());
Après l'exécution, les résultats des tests sont triés dans l'ordre inverse dans les ID. Il y a 14 enregistrements dans la table des visiteurs.
Supposons que nous prenions 5 pièces à la page 2 et exécutons les 6 à 10 données suivantes, alors passez simplement les paramètres.
Demorun.QueryVisitorListwithpagenate (1, 5, "id", sortDirectionEnum.desc.ToString ());
Les résultats sont les suivants:
Ceci est une logique de pagination que j'ai implémentée par moi-même ~ ^ 0 ^. Ce que vous devez noter ici, c'est que je n'ai porté aucun jugement sur le champ OrderFieldStr ici. Théoriquement, il est nécessaire de le faire face pour empêcher le passage des mauvais noms de colonne. Cependant, il devrait y avoir maintenant une encapsulation prête à l'emploi sur Internet, afin que vous puissiez également aller sur Google. Voici juste un moyen de démontrer comment utiliser la pagination MyBatis.
Après avoir terminé cela, parce que c'est MySQL, il n'a pas son propre ID de séquence Rownum dans le résultat de la requête. Par conséquent, il peut ne pas être évident lors de la vérification des données de test. Si vous n'avez pas à vous dépêcher, nous pouvons le faire vous-même pour compenser la nourriture et les vêtements et transformer la méthode ci-dessus. Ici, je vais créer une entité de visiteur complètement identique avec une entité dans le package du modèle et apporter un ID de Rownum supplémentaire renvoyé par la persistance du paramètre Rownum, comme suit:
package david.mybatis.model; import java.text.simpledateFormat; import java.util.date; classe publique visitorwithrn {private int id; nom de chaîne privé; e-mail de chaîne privée; Statut int privé; Date privée CreateTime; Int privé Rownum; Visitorwithrn () {// TODO Générteur généré automatique Stub CreateTime = new Date (); } public Visitorwithrn (String Name, String Email) {this.name = name; this.email = e-mail; this.setStatus (1); this.CreateTime = new Date (); } public int getID () {return id; } public void setName (string name) {this.name = name; } public String getName () {Nom de retour; } public void setEmail (chaîne e-mail) {this.email = e-mail; } public String getEmail () {return e-mail; } public Date getcreatetime () {return CreateTime; } public int getStatus () {return status; } public void setStatus (int status) {this.status = statut; } public int getRownum () {return rownum; } public void setRownum (int rownum) {this.rownum = rownum; } @Override public String toString () {// TODO Méthode générée automatique Stume de retour String.format ("{Rownum:% D, ID:% D, Name:% S, CreateTime:% S}", Rownum, Id, Name, New SimpledateFormat ("Yyyy-mm-dd HH: MM: SS"). Format (CreateTime)); }}Dans iVisitorOperation, créez une nouvelle méthode intitulée Public List <Visitorwithrn> GetListBypageNateWithrn (Pagenateargs Args). De même, nous devons configurer le nœud <lect> correspondant et le script dans VisitorMapper. La seule différence ici est que nous devons modifier le script SQL, comme suit:
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mappep Public "- // Mybatis.org//dtd Mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><Mapper namespace = "david.mybatis.demo.ivisitoroperation"> <! - useGeneratedKeys = "true" signifie s'il faut utiliser une séquence d'auto-croissance, keyproperty = "id" spécifie la colonne est la colonne de croissance, paramètreType = "Visitor" - Ajout de "INSERTER IDSERS dans la définition dans l'interface IVisitorOper ParameterType = "Visitor" useGeneratedKeys = "true" keyproperty = "id"> Insérer dans le visiteur (nom, e-mail, statut, createTime) (# {nom}, # {email}, # {status}, # {CreateTime}) </ insert> <delete id = "Delete" ParamEterType = "int"> DeleLE # {id} </ delete> <update id = "update" ParameterType = "Visitor"> Mise à jour le set du visiteur Nom = # {name}, e-mail = # {email}, status = # {status} où id = # {id} et status> 0; </datedate> <sélectionnez id = "query" ParameterType = "int" resultType = "Visitor"> SELECT ID, nom, e-mail, statut, CreateTime depuis Visitor où id = # {id} et status> 0 Commande par id </lect> <sélectionnez id = "BasicQuery" ParamEterType = "int" ResultType = "Visitor"> SELECT * FROM VOIR </ select> <select id = "getList" resultMap = "Visitorrs"> <include refid = "getListsql" /> </lect> <sql id = "getListSQL"> SELECT * FROM Visitor où Status> 0 </QL> <ResultMap Type = "Visitor" id = "Visitorrs"> <id colonnes = "id" Property = "Id" /> <sult "Clown =" Nom " <Result Column = "Email" Property = "Email" /> <Result Column = "Status" Property = "Status" /> <Result Column = "CreateTime" Property = "CreateTime" /> </ ResultMap> <Select Id = "GetListBypEnet" ParametType = "PageneNatEargs" refid = "orderBysql" />) t <! - # {} signifie la sortie paramétrée, $ {} signifie que la sortie directe n'effectue aucune opération d'évasion, la transférer vous-même -> <if test = "Pagestart> -1 et pagesize> -1"> limite # {pageStart}, # {pageSize} </ if> </lect> <! - REFINE id = "OrderBysQl"> Commande par $ {orderFielDSTR} $ {OrderDirectionstr} </QLL> <! - Comment écrire des scripts SQL avec Rownum -> <ResultMap Type = "Visitorwithrn" id = "Visitorwithrnrs"> <id Collum Column = "email" propriété = "e-mail" /> <résultat chronn = "status" propriété = "status" /> <résultat chronn = "createTime" propriété = "CreateTime" /> <result Column = "rownum" Property = "Rownum" /> </ resultMaps $ {} signifie que la sortie directe n'effectue aucune opération d'évacuation, la transférer vous-même -> Sélectionnez T.Rownum, T.id, T.Name, T.Email, T.Status, T.Createtime From (<inclure refid = "getListSqlContainsrn" /> <inclure refid = "orderBysQl" />) t <if test = "Pagestart> -1 et pagesize> -1" # {Pagestart}, # {pagesize} </ if> </lect> <sql id = "getListsQlContainsrn"> SELECT @Rownum: = @ Rownum + 1 Rownum, result.id, result.name, result.email, résultat.status, résultat de la visitation> 0) </ql> </cappe> La prochaine chose qui reste est d'ajouter la méthode de test sous Demorun tout à l'heure, donc je ne collerai pas la carte ici. Une fois terminé, vous pouvez voir que les 6-10 éléments de données deviendront tout à l'heure comme suit