Implementar una consulta conjunta múltiple
O cree una nueva clase de sitio web bajo el paquete David.Mybatis.Model para persistir en datos y reescribir el método ToString () correspondiente para facilitar el uso de programas de prueba.
paquete David.mybatis.model; import java.text.simpledateFormat; import java.util.date; sitio web de clase pública {private int id; nombre de cadena privada; privado int visitorido; estado privado int; Fecha privada CreateTime; visitante privado visitante; Sitio web público () {// TODO Constructor Generado Auto STUB CreateTime = new Date (); visitante = nuevo visitante (); } sitio web público (nombre de cadena, int visitorId) {this.name = name; this.VisitorId = VisitorId; visitante = nuevo visitante (); estado = 1; CreateTime = new Date (); } public int getId () {return id; } public void setid (int id) {this.id = id; } visitante público getVisitor () {Visitor de retorno; } public void setVisitor (visitante visitante) {this.visitor = visitor; } public String getName () {nombre de retorno; } public void setName (nombre de cadena) {this.name = name; } public int getStatus () {Estado de retorno; } public void setstatus (int status) {this.status = status; } fecha pública getCreateTime () {return CreateTime; } public void setCreateTime (date CreateTime) {this.CreateTime = CreateTime; } public int getVisitorId () {int id = 0; if (visitante == null) id = visitorId; else id = visiter.getId (); ID de retorno; } public void setVisitorId (int visitorId) {this.visitorId = visitorId; } @Override public String toString () {StringBuilder sb = new StringBuilder (String.Format ("Sitio web => {id: %D, Nombre: %S, CreateTime: %S}/R/N", id, nombre, nuevo SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"). Format (creatime)));); if (visitante! = null) sb.append (string.format ("visitor => %s", visiter.toString ())); return sb.ToString (); }}Cree las interfaces de operación correspondientes en David.Mybatis.Demo:
Paquete David.Mybatis.Demo; import java.util.list; import david.mybatis.model.website; interfaz pública iwebsiteoperation {public int add (sitio web del sitio web); public int delete (int id); Public int actualización (sitio web del sitio web); Consulta del sitio web público (INT ID); Lista pública <Sitio web> GetList (); }Cree un nuevo archivo de asignación WebsitSeMapper.xml en la carpeta Mapper y consulte el anterior para agregar, eliminar, modificar y verificar la configuración de la operación de la tabla única, para que pueda crear algunos datos de prueba. como sigue
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype mapper 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"> seleccionar id, nombre, visitorid, status, createTime desde el sitio web donde status> 0 </sql> <insertar id = "add" parametType = "Sitio web" Use GeneratedKeys = "True" KeyProperty = "Id"> Insertar en el sitio web (nombre, ",", "Sitio web", Usate, createSeRedKeys = "True" KeyProperty = "ID" ( #{Name}, #{visitorId}, #{status}, #{createTime}) </sert> <eliminar id = "eliminar" parametertype = "int"> Eliminar desde el sitio web donde> 0 y id = #{id} </elelelelEk> <update id = "actualizar" parametertype = "sitio web" actualizar el sitio web name = #{name {name} </update> <select id = "Query" Parametertype = "int" resultmap = "Websiters"> seleccione Sitio web.id SiteId, Sitio web.name Sitename, Visitor.id VisitorId, Visitor.name VisitOnname, sitio web.status Sitestatus, sitio web.CreateTime SitecreatEtime desde el sitio web en el sitio web en el sitio web. Sitio web.id =#{id} < /select> <resultmap type = "sitio web" id = "sitios web"> <id columna = "siteId" propiedad = "id" /> <resultado columna = "Sitename" Property = "name" /> <resultado columna = "siteStatus" Property = "status" /> <result column = "siteCreateTime" Property = "createtime" /> <asociación propiedad = "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor "Visitor" Visitor ". resultMap="visitorRs" /> </resultMap> <resultMap type="Visitor" id="visitorRs"> <id column="visitorId" property="id" /> <result column="visitorName" property="name" /> </resultMap> <select id="getList" resultMap="websiteByVisitorIdRs"> <include refid="getListSql" /> </select> </mapper>De lo que principalmente hablamos hoy es la búsqueda. Ahora queremos consultar el sitio web y eliminar la información del visitante correspondiente. ¿Cómo hacerlo? Puede consultar la consulta en la configuración y escribir el SQL para la consulta de la tabla de enlaces.
Lo principal a tener en cuenta aquí es que las dos propiedades de ID y nombre en la entidad del sitio web y la entidad de visitas son las mismas. Por lo tanto, para evitar los errores de mapeo, enumere los resultados de la consulta correspondientes con alias diferentes, para que pueda evitarse cuando se une.
¿Qué obtendría si lo configuro como lo siguiente?
<Select id = "Query" Parametertype = "int" resultmap = "Websiters"> Seleccionar sitio web.id, sitio web.name Sitename, Visitor.id, Visitor.ame VisitOnname, sitio web.status Sitestatus, sitio web.CreatEtime SitEcreateTime desde el sitio web Inner para visitar en el sitio web.visitorid = visitor.id donde el sitio web.status> 0 y las veces y la hora del sitio web. Website.id=#{id}</select><resultMap type="Website" id="websiteRs"> <id column="id" property="id" /> <result column="siteName" property="name" /> <result column="siteStatus" property="status" /> <result column="siteCreateTime" property="createTime" /> <association property="visitor" javaType="Visitor" resultMap = "Visitorrs" /> < /resultMap> <resultmap type = "Visitor" id = "Visitorrs"> <id columna = "id" propiedad = "id" /> <resultado columna = "visitOnname" Property = "name" /> < /resultmap> ¿Notó que la identificación del visitante también se ha convertido en 2. De hecho, mapea la ID del sitio web de forma predeterminada, porque el resultado de la consulta de la declaración SQL se ha convertido en 2. Algunas personas pueden preguntar por qué no es 4, porque coincide con la primera por defecto. Si cambia las ubicaciones de Sitio web.id y visit.id, encontrará que el resultado ha cambiado mágicamente nuevamente.
Por lo tanto, debe dar un alias para evitar esta situación, por lo que descubrirá que en realidad solo hay una verdad, que es la siguiente:
Puede ver que el método de procesamiento de múltiples Tabas ResultMap es el mismo que el de las tablas individuales. No es más que enumerar el nombre del atributo Javabean. Puede ver que hay otro resultado de resultados en la recepción en el nodo <ResultMap> del sitio web. Representa la entidad que necesita ser mapeada por la entidad de visita. Puede usar el siguiente método para hacer asociaciones.
<Propiedad de asociación = "Visitante" Javatype = "Visitor" resultMap = "Visitorrs" />
El visitante es el nombre de campo de visita en la entidad del sitio web. El nombre debe ser consistente. De lo contrario, se lanzará una excepción de que no hay getter para la propiedad llamada 'xxx' en la clase David.mybatis.model.website '. Esto se ha descrito en los capítulos anteriores. Por supuesto, si cree que está bien no anidar el mapas de resultados, la anidación también se debe al hecho de que esta configuración se puede usar en otro lugar, entonces se extraerá, lo cual también es una idea abstracta. Use la ID y el resultado en <resultadoMap> para encontrar las diferencias correspondientes del sitio web oficial: http://mybatis.github.io/mybatis-3/sqlmap-xml.html#result_maps
De esta manera, saldrá una consulta conjunta múltiple simple. Si hay tarifas comerciales de consultas más complejas, se realizarán algunas modificaciones en función de esto.
Lógica del efecto de paginación
De lo que queremos hablar es del problema de paginación que a menudo encontramos en un problema comercial. Al desarrollar proyectos web, a menudo usamos la pantalla de la lista. En general, utilizamos algunos controles de listas de uso común, como datos de datos (personalmente me siento muy bien), y los controles de la tabla encapsulada bajo UI fácil.
Idea: para lograr el efecto de la paginación en estos controles, generalmente pasamos 2 parámetros. El primero es representar el índice de la página actual (generalmente a partir de 0), el segundo es representar cuántos registros comerciales se muestran en la página actual, y luego pasar los parámetros correspondientes al método de lista <t> GetList (PagenateArgs Args). Al finalmente implementar la paginación en la base de datos, podemos usar la palabra clave LIMP (para MySQL) para la paginación. Si se trata de un servidor Oracle o SQL, todos tienen su propia función de Rownum para usar.
Para abordar las ideas anteriores, en primer lugar, necesitamos crear una nueva clase de entidad de parámetros de página llamada PageNateArgs en demo.mybatis.model como siempre, y una clase enum llamada SortDirectionEnum, que contiene el índice de página actual PageIndex, la página actual de visualización de registros de la página PageSize, y el atributo de PAGESTART indica qué elemento comenzar. (pageStart = PageIndex*PageSize) Debido a que el uso de la palabra clave límite es representar [número de inicio de límite (no incluido), tomar algunos elementos], el campo de clasificación de OrderFieldStr, la dirección de clasificación de OrderDirectionstr, por lo que la creación específica es la siguiente:
Paquete David.Mybatis.Model;
/ * * Clase de entidad de parámetros de paginación */clase public Pagenateargs {private int pageIndex; Página privada int; privado int pagestart; orden de cadena privadafieldStr; orden de cadena privadaDirectionstr; Public PagenAteargs () {// TODO Auto Generado Constructor Stub} public PagenateArgs (int PageIndex, int PageSize, String OrderFieldStr, String OrderDirectionsTr) {this.PageIndex = PageIndex; this.pagesize = PageSize; this.OrderFieldStr = OrderFieldStr; this.OrderDirectionsTr = OrderDirectionsTr; pagStart = PageIndex * PageSize; } public int getPageIndex () {return PageIndex; } public int getPaGeStart () {return pageStart; } public int getPageSize () {return PageSize; } public String OrderFieldStr () {return ordenfieldStr; } public String getOrderDirectionsTr () {return ordendirectionstr; }} paquete David.mybatis.model;/ * * Sort enum */public enum sortDirectionEnum {/ * * ascendente */asc,/ * * descendente */desc}Después de completar los pasos anteriores, continuamos agregando una lista pública de método <Scisitor> GetListBypagenate (PagenateArgs Args) a la clase de interfaz IVISITOROPERATERATION. En los capítulos anteriores, en realidad ya tenemos el método GetList. Esta paginación es en realidad solo un pequeño cambio basado en esto. Después de cambiar la clase de interfaz ivisitoreperación, es el siguiente:
paquete David.mybatis.Demo; import java.util.list; import david.mybatis.model.pagenateargs; import david.mybatis.model.visitor; import david.mybatis.model.visitorwithrn; interfaz de interfaz público /** Agregar visitante*/ public int add (visitante visitante); /** Eliminar visitante*/ public int delete (int id); /** Actualizar visitante*/ public int actualización (visitante visitante); /** Consulta visitante*/ consulta de visitante público (int id); / * * Lista de consultas */ Public List <Sisitor> getList (); / * * Lista de consultas de paginación */ Lista pública <Scisitor> GetListByPagenate (PagenateArgs Args); }
A continuación, tenemos que comenzar a cambiar nuestro archivo de configuración visitormapper.xml, agregue un nuevo ID de nodo y tipo de parámetro para configurarlo de acuerdo con los capítulos anteriores. La nueva identificación agregada aquí es GetListByPagenate. Después de la configuración, lo siguiente
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace = "David.mybatis.Demo.IVISITEROPERATION"> <!-UseGeneratedKeys = "True" significa si usar una secuencia de crecimiento propio, KeyProperty = "ID" especifica qué columna es la columna de Reflejo de autocuración, ParametType = "Visitante" especifica el tipo correspondiente en la definición de la definición en la definición de Ivisitore parametertype = "visitante" useGeneratedKeys = "true" keyproperty = "id"> insertar en visitante (nombre, correo electrónico, status, createTime) valores ( #{name}, #{}, #{status}, #{createTime}) </inserto> <deselete id = "delete" parámeterType = "int" </elelete> <update id = "update" parametertype = "visitante"> actualizar el set de visitante name =#{name}, correo electrónico =#{correo electrónico}, status =#{status} Where id =#{id} y status> 0; </update> <select id = "Query" ParameterType = "int" resultType = "Visitor"> select id, nombre, correo electrónico, estado, createTime de visitante donde id =#{id} y status> 0 orden por id </select> <select id = "Basicquery" parametType = "int" resultype = "visitante"> select * de visitante de Visitor Where Id =#{ {{Id} y stater by Id " <select id = "getList" resultMap = "visitorrs"> <include refid = "getListsql"/> </elect> <sql id = "getListsql"> Seleccionar * de Visitor Where Status> 0 </sql> <!- La siguiente es una nueva parte para la paginación. El ordenbySQL se extrae, por ejemplo, reutilizando más tarde-> <resultmap type = "visitor" id = "visitorrs"> <id columna = "id" propiedad = "id" /> <resultado columna = "name" propiedad = "name" /> <resultado columna = "correaje" propiedad = "correo electrónico" /> <resultado columna = "estado" propiedad = "status" /> <result columna = "createTime" Property = "createTime" /dulte " id = "getListByPagenate" parametertype = "pagenateArgs" resultType = "visitante"> seleccionar * de (<incluido refid = "getListsql" /> <include refid = "OrderBySql" />) t <!- #{} significa salida parametrizada, $} significa que la salida directa no funciona en las operaciones de escape, transfiera a sí mismo-> <if test test PageSize> -1 "> Limit #{PageStart}, #{Pagesize} </if> </ectele> <sql id =" ordenbysql "> orden por $ {orderfieldstr} $ {OrderDirectionstr} </sql> </mapper>Encontrará configuraciones similares en la figura a continuación. Los atributos de campo aquí son consistentes con los nombres de atributos en la clase de parámetros PagenatEargs.
<if test = "PageStart> -1 y PageSize> -1"> Limit #{PAGESTART}, #{PAGESIZE} </if>Cree un método de prueba en la clase Demorun:
/** Parámetros de paginación*/public static void QueryVisitorListWithPagenate (int PageIndex, int PageSize, String Orderfield, String Orderdire) {Pagenateargs args = new PageNateArgs (PageIndex, PageSize, Orderfield, OrderDire); Sqlsession session = mybatisutils.getSqlSession (); Ivisitoreperation voperation = session.getMapper (ivisitoreperation.class); Lista <Sisitor> Visitantes = voperation.getListByPagenate (args); para (visitante visitante: visitantes) {system.out.println (visitante); } Mybatisutils.clossessession (sesión); Mybatisutils.showMessages (crud_enum.list, visitores.size ());}DemOrun.QueryVisitorListWithPagenate (0, 100, "id", sortDirectionenum.Desc.ToString ());
Después de ejecutar, los resultados de la prueba se ordenan en orden inverso en IDS. Hay 14 registros en la tabla de visitantes.
Supongamos que tomamos 5 piezas en la página 2 y ejecutamos las siguientes 6-10 piezas de datos, así que simplemente pase los parámetros.
DemOrun.QueryVisitorListWithPagenate (1, 5, "id", sortDirectionenum.Desc.ToString ());
Los resultados son los siguientes:
Esta es una lógica de paginación que he implementado por mí mismo ~^0^. Lo que debe tener en cuenta aquí es que no he hecho ningún juicio en el campo Orderfieldstr aquí. Teóricamente, es necesario lidiar con él para evitar que se pasen los nombres de columnas incorrectos. Sin embargo, ahora debería haber encapsulación preparada en Internet, para que también pueda ir a Google. Aquí hay solo una forma de demostrar cómo usar mybatis Paging.
Después de completar esto, debido a que es MySQL, no tiene su propia ID de secuencia Rownum en el resultado de la consulta. Por lo tanto, puede no ser obvio al verificar los datos de la prueba. Si no tiene que darse prisa, podemos hacerlo usted mismo para compensar la comida y la ropa y transformar el método anterior. Aquí crearé una entidad de visitante completamente idéntica en el paquete modelo y traeré una identificación de Rownum adicional devuelta por la persistencia del parámetro Rownum, de la siguiente manera:
Paquete David.mybatis.Model; import java.text.simpledateFormat; import java.util.date; public class Visitorwithrn {private int id; nombre de cadena privada; correo electrónico de cadena privada; estado privado int; Fecha privada CreateTime; Private int Rownum; public VisitorWithrn () {// TODO Auto Generado Constructor Stub CreateTime = new Date (); } public Visitorwithrn (nombre de cadena, correo electrónico de cadena) {this.name = name; this.email = correo electrónico; this.setStatus (1); this.createTime = new Date (); } public int getId () {return id; } public void setName (nombre de cadena) {this.name = name; } public String getName () {nombre de retorno; } public void setEmail (correo electrónico de cadena) {this.email = correo electrónico; } public String getEmail () {return email; } fecha pública getCreateTime () {return CreateTime; } public int getStatus () {Estado de retorno; } public void setstatus (int status) {this.status = status; } public int getRownum () {return Rownum; } public void setRownum (int Rownum) {this.Rownum = ROWNUM; } @Override public String toString () {// TODO Auto Generado Método STUB return String.format ("{Rownum: %D, id: %D, Nombre: %S, CreateTime: %S}", ROWNUM, ID, Name, New SimpleFormat ("YYYY-MM-DD HH: MM: SS"). Format (CreateTime); }}En ivisitoreperation, cree un nuevo método llamado Lista pública <SisitorWithrn> GetListByPagenateWithrn (PagenateArgs Args). Del mismo modo, necesitamos configurar el nodo y el script <ecteled> correspondiente en VisisMapper. La única diferencia aquí es que necesitamos modificar el script SQL, de la siguiente manera:
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace = "David.mybatis.Demo.IVISITEROPERATION"> <!-UseGeneratedKeys = "True" significa si usar una secuencia de crecimiento propio, KeyProperty = "ID" especifica qué columna es la columna de Reflejo de autocuración, ParametType = "Visitante" especifica el tipo correspondiente en la definición de la definición en la definición de Ivisitore parametertype = "visitante" useGeneratedKeys = "true" keyproperty = "id"> insertar en visitante (nombre, correo electrónico, status, createTime) valores ( #{name}, #{}, #{status}, #{createTime}) </inserto> <deselete id = "delete" parámeterType = "int" </elelete> <update id = "update" parametertype = "visitante"> actualizar el set de visitante name =#{name}, correo electrónico =#{correo electrónico}, status =#{status} Where id =#{id} y status> 0; </update> <select id = "Query" ParameterType = "int" resultType = "Visitor"> select id, nombre, correo electrónico, estado, createTime de visitante donde id =#{id} y status> 0 orden por id </select> <select id = "Basicquery" parametType = "int" resultype = "visitante"> select * de visitante de Visitor Where Id =#{ {{Id} y stater by Id " <select id = "getList" resultMap = "visitorrs"> <include refid = "getListsql" /> </seling> <sql id = "getListsql"> select * de visitante donde el estado> 0 </sql> <resultMap type = "Visitor" ID = "VisitorRs"> <Id columna = "Id" Propiedad = "ID" /> <Result COLUMNEM = "Nombre" Nombre "Nombre" Nombre " /" Nombre " /" Nombre " /" Nombre " /" Resultado ". columna = "correo electrónico" propiedad = "correo electrónico" /> <resultado columna = "status" propiedad = "status" /> <resultado column = "createTime" Property = "CreateTime" /> </ resultmap> <select id = "getListBypagenate Refid = "OrderBysql"/>) t <!- #{} Salida parametrizada de medias, $ {} significa que la salida directa no realiza ninguna operación de escape, transfiéralas a ti mismo-> <if test = "Pagestart> -1 y Pagesize> -1"> Límite #{PAGESTART}, #{Pagesize} </if> </select> <!-Refine para los dos ejemplos de los dos. id = "OrderBySql"> orden por $ {OrderFieldStr} $ {OrderDirectionsTr} </sql> <!-Cómo escribir scripts sql con Rownum-> <resultmap type = "visiterwithrn" id = "visitorwithrnrs"> <Id columna = "id" propiedad = "id" propiedad = "correo electrónico" /> <resultado columna = "status" propiedad = "status" /> <resultado columna = "createTime" Property = "CreateTime" /> <resultado columna = "ROWNUM" Propiedad = "ROWNUM" /> < /resultMap> <select ID = "getListByPagenateWithrn" Resultado = "VisitorwithrnrnrnRnrs"> <!- #{{{{{{{{{{{{}}, salido de los medios {}} {} {} {} {} de los medios {} de los medios {}. no realiza ninguna operación de escape, transfiéralas tú mismo-> Seleccione T.Rownum, T.ID, T.Name, T.Email, T.Status, T.CreateTime desde (<include refid = "getListsqlContainSrn" /> <incluido refid = "OrderBySql" />) t <si test = "PagStart> -1 y pagesizeize> -1" "" #{pageSize} </if> </select> <sql id = "getListsqlContainsRn"> seleccione @Rownum: = @Rownum+1 Rownum, resultado.id, resultado.name, resultado.email, resultado.status, resultado.createTime de (select @Rownum: = 0, visitante. Lo siguiente que queda es agregar el método de prueba en Demorun justo ahora, para que no pegaré el mapa aquí. Después de la finalización, puede ver que los datos de 6 a 10 años se convertirán en el siguiente