Implementar consulta conjunta de várias mesa
Ou crie uma nova classe de site no pacote David.mybatis.model para persistir dados e reescrever o método ToString () correspondente para facilitar o uso de programas de teste.
pacote David.mybatis.model; importar java.text.simpledateFormat; importar java.util.date; site de classe pública {private int id; nome de string privado; Private Int VisitorId; status privado int; data privada createTime; Visitante de Visitante Privado; public site () {// TODO Construtor Geralated Stub CreateTime = new Date (); visitante = novo visitante (); } site público (nome da string, int visitorID) {this.name = name; this.visitorId = visitorID; visitante = novo visitante (); status = 1; createTime = new Date (); } public int getId () {return id; } public void setId (int id) {this.id = id; } visitante público getVisitor () {return visitante; } public void SetVisitor (visitante visitante) {this.visitor = visitante; } public string getName () {return name; } public void setName (nome da string) {this.name = name; } public int getStatus () {retornar status; } public void setStatus (status int) {this.status = status; } public data getCreateTime () {return createTime; } public void setCreateTime (data createTime) {this.createTime = createTime; } public int getVisitorId () {int id = 0; if (visitante == null) id = visitorID; else id = visitor.getId (); ID de retorno; } public void setVisitorId (int visitorID) {this.visitorId = visitorID; } @Override public string tostring () {stringbuilder sb = new stringbuilder (string.format ("site => {id: %d, nome: %s, createTime: %s}/r/n", id, nome, novo simpledEformat ("yyyyy-mm-dd hh: mm: ss"). if (visitante! = null) sb.append (string.format ("visitante => %s", visitor.toString ())); return sb.toString (); }}Crie as interfaces de operação correspondentes em David.mybatis.demo:
pacote David.mybatis.demo; importar java.util.list; importar David.mybatis.model.website; interface pública IWebSitePeration {public int Add (site do site); public int Delete (int id); public int update (site do site); consulta pública no site (int id); Lista pública <Beetry> getList (); }Crie um novo arquivo de mapeamento do WebSiteMapper.xml na pasta Mapper e consulte o anterior para adicionar, excluir, modificar e verificar a configuração de operação de tabela única, para que você possa criar alguns dados de teste. do seguinte modo
<? xml versão = "1.0" coding = "utf-8"?> <! namespace = "David.mybatis.demo.iwebsiteoperation"> <sql id = "getListsql"> selecione ID, nome, visitante, status, createTime do site em que status> 0 </sql> <insert id = "add" parameterpe = "" "useGenertKeys =" True " CreateTime) valores ( #{name}, #{visitorId}, #{status}, #{createTime}) </insert> <delete id = "delete" parameterType = "int"> excluir do site onde status> 0 e id = #{id} </delete> <update ID = "atualização" "" id =#{id} </update> <select id = "query" parametertype = "int" resultmap = "websiters"> selecione sites.id siteId, site.name sitename, visitor.id visitorid, visitor.name visitorName, site no site sityestatus, website. Site.status> 0 e site.id =#{id} < /select> <resultado Property = "Visitante" Javatype = "Visitor" ResultMap = "Visitorrs" /> < /ResultMap> <ResultMap type = "Visitor" id = "Visitorrs"> <id column = "visitorId" Property = "ID" /> <Result Column = "Visitorname" Result = "Nome" /> < /ResultMap> refid = "getListsql"/> </leclect> </palpper>O que falamos principalmente hoje é a pesquisa. Agora queremos consultar o site e retirar as informações de visitantes correspondentes juntos. Como fazer isso? Você pode consultar a consulta na configuração e anotar o SQL para a consulta da tabela de links.
O principal a ser observado aqui é que as duas propriedades de ID e nome na entidade do site e na entidade de visita são iguais. Portanto, para evitar erros de mapeamento, liste os resultados de consulta correspondentes com um alias diferentes, para que possa ser evitado ao vincular.
O que eu conseguiria se eu configure -o como o seguinte?
<select id = "query" parameterType = "int" resultmap = "websiters"> selecione sites.id, site.name sitename, visitor.id, visitante.name visitorname, sites.status sitestatus, site.createTime sitecreateTime do site inner Junk Site.id =#{id} < /select> <resultado javatype = "visitante" resultMap = "visitORRS" /> < /resultMap> <resultMap type = "visitante" id = "visitorrs"> <id column = "id" propriedade = "id" /> <resultado colun = "visitorname" propriedade = "name" /> < /resultado> Você percebeu que o ID do visitante também se tornou 2. De fato, ele mapeia o ID do site por padrão, porque o resultado da consulta de declaração SQL se tornou 2. Algumas pessoas podem perguntar por que não é 4, porque corresponde ao primeiro por padrão. Se você mudar os locais do site.id e visit.id, descobrirá que o resultado mudou magicamente novamente.
Portanto, você precisa dar um pseudônimo para evitar essa situação, para descobrir que na verdade existe apenas uma verdade, que é a seguinte:
Você pode ver que o método de Processamento Multi-Table ResultMap é o mesmo que o de tabelas únicas. Não é nada mais do que listar o nome do atributo Javabean. Você pode ver que existe outro resultMap na recepção no nó <s ResultMap> do site. Representa a entidade que precisa ser mapeada pela entidade da visita. Você pode usar o seguinte método para fazer associações.
<Association Property = "Visitor" Javatype = "Visitor" ResultMap = "Visitorrs" />
O visitante é o nome do campo de visita na entidade do site. O nome deve ser consistente. Caso contrário, uma exceção de não há getter para propriedade denominada 'xxx' na classe 'David.mybatis.model.website' será lançada. Isso foi descrito nos capítulos anteriores. Obviamente, se você acha que não há problema em não aninhar o mapa de resultados, o ninho também se deve ao fato de que essa configuração pode ser usada em outros lugares, será extraída, o que também é uma idéia abstrata. Use o ID e resulte em <sultmap> para encontrar as diferenças correspondentes do site oficial: http://mybatis.github.io/mybatis-3/sqlmap-xml.html#result_maps
Dessa forma, uma consulta articular simples de várias mesas será lançada. Se houver taxas de negócios de consulta mais complexas, algumas modificações serão feitas com base nisso.
Lógica do efeito da paginação
O que queremos falar é sobre o problema da paginação que frequentemente encontramos em um problema de negócios. Ao desenvolver projetos da Web, geralmente usamos a exibição da lista. Geralmente, usamos alguns controles de lista comumente usados, como Datatables (eu pessoalmente me sinto muito bem) e os controles de tabela encapsulados sob a interface do usuário fácil.
Ideia: Para alcançar o efeito da paginação nesses controles, geralmente passamos 2 parâmetros. O primeiro é representar o índice da página atual (geralmente a partir de 0), o segundo é representar quantos registros de negócios são exibidos na página atual e depois passar os parâmetros correspondentes para a lista <t> getList (Pagenateargs args). Ao finalmente implementar a paginação no banco de dados, podemos usar a palavra -chave limitada (para MySQL) para pagar. Se for um Oracle ou SQL Server, todos eles têm sua própria função Rownum a ser usada.
Para abordar as idéias acima, antes de tudo, precisamos criar uma nova classe de entidade de parâmetros de página chamada Pagenateargs sob Demo.mybatis.model como sempre, e uma classe Enum chamada SortDirectionEnum, que contém o item de página atual, a página atual, a página atual exibe os registros de negócios PageSize e o Pagestart Attribute indicados para o início. (Pagestart = PageIndex*PageSize) porque o uso da palavra -chave limitada é representar [o número de inicialização do limite (não incluído), pegue alguns itens], o campo de classificação do Orderfieldstr, direção do OrderDirectionstr, a criação específica é a seguinte:
pacote David.mybatis.model;
/ * * Classe de entidade de parâmetro de paginação */classe pública pagenateargs {private int PageIndex; private int PageSize; privado int pagestart; Private String Orderfieldstr; Private String OrderDirectionstr; public pagenateargs () {// TODO Construtor Auto-Gerado Stub} public Pagenateargs (int PageIndex, int PageSize, String Orderfieldstr, String OrderDirectionStr) {this.pageIndex = PageIndex; 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 pagageSize; } public string orderfieldstr () {return orderfieldstr; } public String getOrderDirectionStr () {return OrderDirectionStr; }} pacote David.mybatis.model;/ * * Sort Enum */public Enum SortDirectionEnum {/ * * Ascendente */ASC,/ * * descendente */desc}Depois de concluir as etapas acima, continuamos a adicionar uma lista pública de método <visitante> getListbypagenate (Pagenateargs args) à classe IVISITOPERATION Interface. Nos capítulos anteriores, na verdade já temos o método getList. Essa paginação é realmente apenas uma pequena mudança com base nisso. Depois que a classe IVISITOPERAPRIONEFUND é alterada, é a seguinte:
pacote David.mybatis.demo; importar java.util.list; importar David.mybatis.model.pagenateargs; importar David.mybatis.model.visitor; importação de David.mybatis.model.VisitorWhrn; /** Adicionar visitante*/ public int add (visitante visitante); /** Excluir visitante*/ public int excluir (int id); /** Atualizar visitante*/ public int update (visitante visitante); /** Consulta visitante*/ consulta de visitante público (int id); / * * Lista de consultas */ Lista pública <visitante> getList (); / * * Lista de consultas de paginação */ Lista pública <Misitor> getListBypagEnate (Pagenateargs args); }
Em seguida, temos que começar a alterar nosso arquivo de configuração do VisitorMApper.xml, adicione um novo ID do nó e o tipo de parâmetro para configurá -lo de acordo com os capítulos anteriores. O novo ID adicionado aqui é GetListBypagenate. Após a configuração, o seguinte
<? xml versão = "1.0" coding = "utf-8"?> <! namesace = "David.mybatis.demo.ivisitorOperation"> <!-usegeneratedkeys = "true" significa se deve usar uma sequência de auto-crescimento, keyproperty = "id" especifica qual coluna é a coluna de auto-crescimento, o parameterType "" especifica o tipo de admissão " ParameterType = "Visitante" UseGeneratedKeys = "true" keyProperty = "Id"> Inserir no visitante (nome, email, status, createTime) valores ( #{name}, #{email}, #{status}, #{createTime}) </insert> <delete id = "deLete" parâmetro}, parâmetro {CreateTime}) </insert> <Delete ID = "delate") #{id} </delete> <update id = "update" parametertype = "visitante"> atualize o conjunto de visitantes =#{name}, email =#{email}, status =#{status} onde id =#{id} e status> 0; </update> <select id = "visitante"> selecione ID, nome, email, status, createTime do visitante onde id =#{id} e status> 0 Ordem por id </select> <select Id "BasicQuery" Parameter = "Int" ResultType = "Disitor"> "> </select> <select id = "getList" resultmap = "visitorrs"> <incluir refid = "getListsql"/> </leclect> <sql id = "getListsql"> selecione * do visitante onde status> 0 </sql> <!- o seguinte é uma nova peça para a paginação. The orderBySql is extracted for example reuse later-> <resultMap type="Visitor" id="visitorRs"> <id column="Id" property="id" /> <result column="Name" property="name" /> <result column="Email" property="email" /> <result column="Status" property="status" /> <result column="CreateTime" property="createTime" /> </resultMap> <select id = "getListbypagEnato" parameterType = "pagenateargs" resultype = "visitante"> selecione * de (<incluir refid = "getListsql"/> <incluir refid = "orderbysql"/> t <!- #{} significa que a saída da parametrizada, $ {{{{{{} {} {{} {{} {) test = "Pagestart> -1 e Pagesize> -1"> Limit #{Pagestart}, #{Pagesize} </if> </select> <sql id = "orderbysql"> encomendar por $ {orderfieldstr} $ {orderdirectionStr} </sql> <///Mapper>Você encontrará configurações semelhantes na figura abaixo. Os atributos de campo aqui são todos consistentes com os nomes de atributos na classe Pagenateargs parameter.
<if test = "pagestart> -1 e paageSize> -1"> limite #{pagestart}, #{Pagesize} </if>Crie um método de teste na classe Demorun:
/** Parâmetros de paginação*/public static void QueryVisitorListWithPagEnate (int PageIndex, int PageSize, String Orderfield, String OrderDire) {Pagenateargs args = novo Pagenateargs (PageIndex, PageSize, OrderField, OrderDire); Sessão de sqlSession = mybatisutils.getSqlSession (); VoPeation IVISITOPERATION = SESSÃO.GETMAPPER (IVISITOPERATION.CLASS); Lista <Tisitor> visitantes = Voperation.getListbypagenate (args); para (visitante visitante: visitantes) {System.out.println (visitante); } Mybatisutils.closSession (sessão); Mybatisutils.showmessages (crud_enum.list, visitores.size ());}Demorun.QueryVisitorListWithPagEnate (0, 100, "ID", SortDirectionEnum.Desc.toString ());
Após a execução, os resultados do teste são classificados em ordem inversa nos IDs. Existem 14 registros na tabela de visitantes.
Suponha que pegamos 5 peças na página 2 e executamos os seguintes 6 a 10 dados, então passe os parâmetros.
Demorun.QueryVisitorListWithPagEnate (1, 5, "ID", SortDirectionEnum.Desc.toString ());
Os resultados são os seguintes:
Esta é uma lógica de paginação que implementei sozinho ~^0^. O que você precisa observar aqui é que eu não fiz nenhum julgamento no campo Orderfieldstr aqui. Teoricamente, é necessário lidar com isso para impedir que os nomes de colunas errados sejam aprovados. No entanto, deve haver encapsulamento pronto na Internet agora, para que você também possa ir ao Google. Aqui está apenas uma maneira de demonstrar como usar o Mybatis Paging.
Depois de concluir isso, porque é o MySQL, ele não possui seu próprio ID de sequência de Rownum no resultado da consulta. Portanto, pode não ser óbvio ao verificar os dados do teste. Se você não precisar se apressar, podemos fazer isso para compensar comida e roupas e transformar o método acima. Aqui, criarei uma entidade visitante completamente idêntica no pacote de modelos e trarei um ID de rotação adicional retornado pela persistência do parâmetro rownum, como segue:
pacote David.mybatis.model; importar java.text.simpledateFormat; importar java.util.date; classe pública visitationwithrn {private int id; nome de string privado; e -mail privado de string; status privado int; data privada createTime; privado int rownum; public VisitorWithrn () {// TODO Construtor Auto-Gerado Stub CreateTime = new Date (); } public visitorWithrn (nome da string, string email) {this.name = name; this.Email = email; this.setStatus (1); this.createTime = new Date (); } public int getId () {return id; } public void setName (nome da string) {this.name = name; } public string getName () {return name; } public void setEmail (string email) {this.email = email; } public String getEmail () {retornar email; } public data getCreateTime () {return createTime; } public int getStatus () {retornar status; } public void setStatus (status int) {this.status = status; } public int getRownum () {return rownum; } public void setRownum (int rownum) {this.rownum = rownum; } @Override public String toString() { // TODO Auto-generated method stub return String.format("{Rownum: %d, Id: %d, Name: %s, CreateTime: %s}", rownum, id, name, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createTime)); }}Na ivisitorOPeration, crie um novo método chamado Public List <visitorwithrn> getListbypagenateWithrn (Pagenateargs args). Da mesma forma, precisamos configurar o nó e o script e scripts correspondentes no VisitormPerpper. A única diferença aqui é que precisamos modificar o script SQL, como segue:
<? xml versão = "1.0" coding = "utf-8"?> <! namesace = "David.mybatis.demo.ivisitorOperation"> <!-usegeneratedkeys = "true" significa se deve usar uma sequência de auto-crescimento, keyproperty = "id" especifica qual coluna é a coluna de auto-crescimento, o parameterType "" especifica o tipo de admissão " ParameterType = "Visitante" UseGeneratedKeys = "true" keyProperty = "Id"> Inserir no visitante (nome, email, status, createTime) valores ( #{name}, #{email}, #{status}, #{createTime}) </insert> <delete id = "deLete" parâmetro}, parâmetro {CreateTime}) </insert> <Delete ID = "delate") #{id} </delete> <update id = "update" parametertype = "visitante"> atualize o conjunto de visitantes =#{name}, email =#{email}, status =#{status} onde id =#{id} e status> 0; </update> <select id = "visitante"> selecione ID, nome, email, status, createTime do visitante onde id =#{id} e status> 0 Ordem por id </select> <select Id "BasicQuery" Parameter = "Int" ResultType = "Disitor"> "> < /select> <select id = "getList" resultmap = "visitorrs"> <incluir refid = "getListsql" /> < /select> <sql id = "getListsql"> selecione * do visitante onde status> 0 < /sql> <resultado <resultado column = "email" property = "email" /> <resultado column = "status" property = "status" /> <resultado column = "createTime" property = "createTime" /> < /resultMap> <select id = "getListbypagenate" parameterType = "pagenateargs" resultType = "visitor"> refID = "OrderBySQL"/>) t <!- #{} significa saída parametrizada, $ {} significa que a saída direta não executa nenhuma operação de fuga, transfira você mesmo-> <se test = "pagestart> -1 e Pagesize> -1"> limite #{pagestart}, {{Pagesize} </se> id = "Orderbysql"> encomendar por $ {Orderfieldstr} $ {OrderDirectionStr} < /sql> <!-Como escrever scripts sql com rownum-> <resultMap type = "VisitorWithrn" id = "visitorWithRNS"> <id column = "iditorwrn" ") column = "email" propriedade = "email" /> <resultado column = "status" property = "status" /> <resultado colun = "createTime" propriedade = "createTime" /> <resultado column = "rownum" propriedade = "rOWNUM" /> < /ResultMap> <select Id = "getListbypagenatewithrn" Result = " Saída, $ {} significa que a saída direta não executa operações de fuga, transfira você mesmo-> selecione T.Rownum, T.ID, T.Name, T.Email, T.Status, T.CreateTime de (<Incluir refid = "getListsqlcontainsrn" /> <Incluir Refid = "OrderBysql" />) #{Pagestart}, #{Pagesize} </if> </select> <sql id = "getListsqlcontainsrn"> selecione @rownum: = @rownum+1 rownum, result.id, result.name, resultado.Email, resultado.status, resultado.creatETime de (select @ </sql> </mapper> A próxima coisa que resta é adicionar o método de teste em Demorun agora, para que não coloque o mapa aqui. Após a conclusão, você pode ver que os 6 a 10 dados agora se tornarão os seguintes