다중 테이블 조인트 쿼리를 구현하십시오
또는 David.myBatis.Model 패키지 아래에 새 웹 사이트 클래스를 작성하여 데이터를 지속하고 해당 TOSTRING () 메소드를 다시 작성하여 테스트 프로그램의 사용을 용이하게합니다.
package david.mybatis.model; import java.text.simpledateformat; import java.util.date; public class 웹 사이트 {private int id; 개인 문자열 이름; 개인 int visitorid; 개인 int 상태; 개인 날짜 CreateTime; 개인 방문자 방문자; 공개 웹 사이트 () {// todo 자동 생성 생성자 스터브 CreateTime = new Date (); 방문자 = 새 Visitor (); } 공개 웹 사이트 (문자열 이름, int visitorid) {this.name = name; this.visitorid = visitorid; 방문자 = 새 Visitor (); 상태 = 1; CreateTime = 새 날짜 (); } public int getId () {return id; } public void setid (int id) {this.id = id; } 공개 방문자 getVisitor () {반환 방문자; } public void setvisitor (방문자 방문자) {this.visitor = 방문자; } public String getName () {return name; } public void setName (문자열 이름) {this.name = 이름; } public int getStatus () {return status; } public void setstatus (int status) {this.status = 상태; } 공개 날짜 getCreateTime () {return createTime; } public void setCreateTime (Date CreateTime) {this.createTime = createTime; } public int getvisitorid () {int id = 0; if (visitor == null) id = visitorid; else id = visitor.getId (); 반환 ID; } public void setvisitorid (int visitorid) {this.visitorid = visitorid; } @override public String toString () {StringBuilder sb = new StringBuilder (String.format ( "website => {id : %d, name : %s, createTime : %s}/r/n", id, name, new simpledateformat ( "yyyy-mm-dd hh : mm : ss"))) if (visitater! = null) sb.append (string.format ( "visitor => %s", visititor.toString ()); 반환 sb.toString (); }}david.mybatis.demo에서 해당 조작 인터페이스를 만듭니다.
package david.mybatis.demo; import java.util.list; import david.mybatis.model.website; public interface iwebsiteoperation {public int add (웹 사이트 웹 사이트); 공개 int 삭제 (int id); 공개 int 업데이트 (웹 사이트 웹 사이트); 공개 웹 사이트 쿼리 (int id); 공개 목록 <boogl> getList (); }Mapper 폴더에서 새 WebSitemapper.xml 매핑 파일을 작성하고 이전 테이블 작업 파일을 참조하여 단일 테이블 작업 구성을 추가, 삭제, 수정 및 확인하여 일부 테스트 데이터를 빌드 할 수 있도록하십시오. 다음과 같이
<? xml version = "1.0"alcoding = "utf-8"?> <! doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <<<<<<<<<<<< << <<< << << <<iwedbatis. <sql id = "getListsql"> id, name, visitorid, status, status, createTime status> 0 </sql> <insert id = "add"parametertype = "website"usegeneratedkeys = "true"keyproperty = "id"> 웹 사이트 삽입 (name, visitorid, status, createMe) 값 ( #{visitid}, #{vistime} #{status}, #{createTime}) </insert> <delete id = "delete"parametertype = "int"> 웹 사이트에서 삭제 된 상태> 0 및 id = #{id} </delete> <업데이트 "update"update set set name = {name} <selop} </id = #<} parametertype = "int"resultmap = "websiters"> select webly.id site.id, website.name siteName, visiter.id visitorid, visitor.name visitorname, website.status sitestatus, weffore.visitorid = visititor.id visititor.id}} 0에서 inner visititor의 inner visititor에서 sitecreatetime inner inner inner inner =}#} type = "website"id = "webiters"> id column = "siteId"property = "id" /> <result column = "siteName"property = "name" /> <result column = "sitestatus"property = "status" /> <결과 열 = "siteCreateTime"propert = "createTime" /> <Association Property = "visitor"visitors "visitorrs" "visitors" " <resultmap type = "Visitor"id = "visititorrs"> <id column = "visitorid"property = "id" /> <result column = "visisorname"property = "name" /> < /resultmap> <select id = "getList"resultMap = "wefforeByvisitorIdrs"> refid = "getListSql" /> < /mapper>오늘 우리가 주로 이야기하는 것은 검색입니다. 이제 우리는 웹 사이트를 쿼리하고 해당 방문자 정보를 함께 꺼내고 싶습니다. 어떻게해야합니까? 구성의 쿼리를 참조하고 링크 테이블 쿼리의 SQL을 기록 할 수 있습니다.
여기서 주목해야 할 것은 웹 사이트 엔티티와 방문 엔티티의 ID와 이름의 두 속성이 동일하다는 것입니다. 따라서 매핑 오류를 피하려면 해당 쿼리 결과를 다른 별칭으로 나열하여 바인딩 할 때 피할 수 있습니다.
다음과 같이 구성하면 무엇을 얻을 수 있습니까?
<query "parametertype ="int "resultmap ="websiters "> website.id, website.name siteName, visiter.id, visitor.name visitorname, weffore.status sitestatus, wefit.createTime sitior.id visitor.id .Status.id. website.id =#{id} < /select> <resultmap type = "website"id = "websiters"> <id councle = "id"속성 = "id"속성 = "id" /> <result column = "siteName"property = "name" /> <result column = "sitestatus"속성 = "status" /> <result column = "siteecreatetime ="createTime " /> resultmap = "visititorrs" /> < /resultmap> <resultmap type = "visitor"id = "visititorrs"> <id column = "id"property = "id" /> <result column = "visisorname"property = "name" /< /resultmap> 방문자의 ID도 2가되었음을 알았습니까? 실제로 SQL 문 쿼리의 결과가 2가 되었기 때문에 웹 사이트 ID를 기본적으로 매핑합니다. 일부 사람들은 기본적으로 첫 번째와 일치하기 때문에 4가 아닌 이유를 물어볼 수 있습니다. Website.id 및 visit.id의 위치를 전환하면 결과가 마술처럼 다시 변경되었음을 알 수 있습니다.
따라서이 상황을 피하기 위해 별칭을 주어야하므로 실제로는 하나의 진실 만 있다는 것을 알게 될 것입니다.
멀티 테이블 처리 결과 맵의 방법이 단일 테이블의 방법과 동일하다는 것을 알 수 있습니다. Javabean 속성의 이름을 나열하는 것 이상입니다. 웹 사이트의 <resultmap> 노드에 프론트 데스크에 또 다른 결과 맵이 있음을 알 수 있습니다. 방문 엔티티에 의해 맵핑되어야하는 엔티티를 나타냅니다. 다음 방법을 사용하여 연결을 만들 수 있습니다.
<Association Property = "방문자"javatype = "방문자"resultMap = "Visitorrs" />
방문자는 웹 사이트 엔티티의 방문 필드 이름입니다. 이름은 일관성이 있어야합니다. 그렇지 않으면, '클래스 david.mybatis.model.website'에서 'xxx'라는 속성에 대한 getter가 없습니다. 이것은 이전 장에서 설명되었습니다. 물론, 결과 맵을 중첩하지 않는 것이 좋다고 생각되면, 네스트링은이 구성이 다른 곳에서 사용될 수 있다는 사실에 의한 것입니다. 그러면 추상적 인 아이디어이기도합니다. id를 사용하여 <resultmap>을 사용하여 공식 웹 사이트에서 해당 차이를 찾으십시오 : http://mybatis.github.io/mybatis-3/sqlmap-xml.html#result_maps
이런 식으로 간단한 멀티 테이블 조인트 쿼리가 나옵니다. 더 복잡한 쿼리 비즈니스 비용이있는 경우이를 기반으로 일부 수정이 이루어집니다.
페이지 매김 효과 논리
우리가 이야기하고 싶은 것은 비즈니스 문제에서 종종 발생하는 페이지 매김 문제입니다. 웹 프로젝트를 개발할 때는 종종 목록 디스플레이를 사용합니다. 일반적으로 우리는 DataTables (개인적으로 매우 기분이 좋음)와 같은 일반적으로 사용되는 목록 컨트롤 및 Easy UI에서 캡슐화 된 테이블 컨트롤을 사용합니다.
아이디어 : 이러한 컨트롤에서 페이징의 효과를 달성하기 위해 일반적으로 2 개의 매개 변수를 전달합니다. 첫 번째는 현재 페이지의 인덱스 (일반적으로 0부터 시작)를 나타내는 것입니다. 두 번째는 현재 페이지에 얼마나 많은 비즈니스 레코드를 표시 한 다음 해당 매개 변수를 List <T> getList (pagEnateArgs Args) 메소드로 전달하는 것입니다. 데이터베이스에서 마지막으로 페이징을 구현할 때 페이징에는 한계 키워드 (MySQL)를 사용할 수 있습니다. Oracle 또는 SQL 서버 인 경우 모두 사용할 수있는 고유 한 기능이 있습니다.
위의 아이디어를 다루기 위해서는 무엇보다도 Demo.mybatis.model 아래에서 pagenateargs라는 새 페이지 매개 변수 엔티티 클래스를 만들어야합니다. (pagestart = pageindex*pagesize) 한계 키워드의 사용법은 [제한 시작 번호 (포함되지 않음), 몇 가지 항목을 가져 가기], OrderFieldSt 정렬 필드, OrderDipectionst 정렬 방향을 나타 내기 때문에 다음과 같습니다.
패키지 david.mybatis.model;
/ * * Pagination 매개 변수 엔티티 클래스 */public class pagenateargs {private int pageindex; Private int Pagesize; 개인 int pagestart; 개인 문자열 ORDERFIELDSTR; 개인 문자열 orderdirectionstr; public pagenateargs () {// todo 자동 생성 생성자 스텁} public pagenateargs (int pageindex, int pageize, string orderfieldstr, String orderdirectionst) {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 pagesize; } public String orderfieldstr () {return orderfieldstr; } public String getOrderDirectiontr () {return orderDirectionStr; }} 패키지 david.mybatis.Model;/ * * Sort enum */public enum sortDirectionEnum {/ * * 오름차순 */asc,/ * * 하강 */desc}위의 단계를 완료 한 후에는 IVisitorOperation 인터페이스 클래스에 메소드 공개 목록 <Sisitor> getListBypagenate (pagenateargs args)를 계속 추가합니다. 이전 장에서는 실제로 GetList 메소드가 이미 있습니다. 이 페이지 매김은 실제로 이것을 기반으로 약간의 변화입니다. ivisitoroperation 인터페이스 클래스가 변경된 후 다음과 같습니다.
package david.mybatis.demo; import java.util.list; import david.mybatis.model.pagenateargs; import david.mybatis.model.visitor; import david.mybatis.model.visitorwithrn; public interface ivisitoroperation { /** Basic Query* / public vesitor (int id); /** 방문자 추가*/ public int add (방문자 방문자); /** 방문자 삭제*/ public int delete (int id); /** 업데이트 방문자*/ public int update (방문자 방문자); /** 쿼리 방문자*/ 공개 방문자 쿼리 (int id); / * * 쿼리 목록 */ public list <visitor> getList (); / * * Pagination Query List */ public list <visitor> getListBypagenate (pagenateargs args); }다음으로 visitormapper.xml 구성 파일을 변경하기 시작해야합니다. 이전 장에 따라 구성하기 위해 새 <select> 노드 ID 및 매개 변수 유형을 추가하십시오. 여기에 추가 된 새로운 ID는 getListByPagenate입니다. 구성 후 다음은 다음과 같습니다
<? xml version = "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.dmo.dmo. useGeneratedKeys = "true"는 자체 성장 시퀀스를 사용하는지 여부를 의미합니다. keyProperty = "id"는 어떤 열이자가 성장 열인 열을 지정합니다. ParameterType = "방문자"는 ivisitorOperation interface 클래스에서 정의에 전달 된 해당 유형을 지정합니다. id = "insud" "keyProper" 방문자 (이름, 이메일, 상태, CreateTime) 값 ( #{name}, #{email}, #{atritains}, #{createTime}) </insert> <delete id = "delete"parametertype = "int"> visitater from where where where and id = #{id} <update id = "vist"> #{name}, email =#{email}, status =#{status} 여기서 id =#{id} 및 상태> 0; </update> <select id = "query"parametertype = "int"resulttype = "visitor"> id =#{id} 및 id =#{id} 및 status </select> <select id = "basicquery"parametertype = "int"resulttype = "visitator"에서 id =#{id}#}##########{idect * select </select id = id = id = "rectations </select </select </select </select <lect <rectatient" </select> <select> <선택 id = "getList"resultMap = "visitorrs"> <refid = "getListSql"/> </select> <sql id = "getListSql"> select *에서 status> 0 </sql> <!- 다음은 Pagination의 새로운 부분입니다. OrderBySQL은 예를 들어 나중에 재사용됩니다-> <resultmap type = "visitater"id = "visitorrs"> <id councle = "id column ="id "property ="id " /> <result column ="name "property ="name " /> <result column ="email "propert ="email " /> <result column ="status " /> <result imap"propertime ""createtime ""createTime ""createTime " id = "getListByPagenate"ParameterType = "pagEnateArgs"resultType = "Visitor"> select * from (<refid = "getListSql" /> <order refid = "orderBysql" />) t <!- #{{{{{{{{{{{include refid = "orderbysql" />) t <! 및 pagesize> -1 "> limit #{pagestart}, #{pagesize} </if> </select> <sql id ="orderbysql "> order by $ {orderfieldst} $ {orderdirectionst} </sql> </mapper>아래 그림에서 유사한 구성이 있습니다. 여기의 필드 속성은 모두 pagenateargs 매개 변수 클래스의 속성 이름과 일치합니다.
<test = "pagestart> -1 및 pagesize> -1"> limit #{pagestart}, #{pagesize} </if>Demorun 클래스에서 테스트 방법을 만듭니다.
/** Pagination 매개 변수*/public static void QueryVisitorListwithPagenate (int pageIndex, int pagesize, String Orderfield, String OrderDire) {pagenateArgs args = new pagenateargs (pageIndex, pageSize, OrderField, OrderDire); sqlsession 세션 = mybatisutils.getSqlsession (); ivisitoroperation voperation = session.getMapper (ivisitorOperation.class); 목록 <visitor> 방문자 = voperation.getListBypagenate (args); for (방문자 방문자 : 방문자) {System.out.println (방문자); } mybatisutils.closesession (세션); mybatisutils.showmessages (crud_enum.list, visitors.size ());}demorun.queryvisitorlistwithpagenate (0, 100, "id", sortdirectionenum.desc.tostring ());
실행 후 테스트 결과는 ID에서 역 순서로 정렬됩니다. 방문자 테이블에는 14 개의 레코드가 있습니다.
2 페이지에서 5 개를 가져 와서 다음 6-10 개의 데이터를 실행한다고 가정 해 봅시다. 따라서 매개 변수를 전달하십시오.
demorun.queryvisitorlistwithpagenate (1, 5, "id", sortdirectionenum.desc.tostring ());
결과는 다음과 같습니다.
이것은 내가 직접 구현 한 페이징 논리입니다 ~^0^. 여기서 주목해야 할 것은 여기에서 Orderfieldstr 필드에 대한 판단을하지 않았다는 것입니다. 이론적으로, 잘못된 열 이름이 전달되는 것을 방지하기 위해 처리해야합니다. 그러나 지금 인터넷에 기성품 캡슐화가 있어야하므로 Google로 이동할 수도 있습니다. 다음은 mybatis 페이징을 사용하는 방법을 보여주는 방법입니다.
이 작업을 완료 한 후 MySQL이기 때문에 쿼리 결과에 고유 한 rownum 시퀀스 ID가 없습니다. 따라서 테스트 데이터를 확인할 때는 분명하지 않을 수 있습니다. 서두르지 않아도되면 음식과 의복을 보충하고 위의 방법을 변형시키기 위해 직접 할 수 있습니다. 여기서는 모델 패키지에있는 엔티티에서 완전히 동일한 방문자를 만들고 다음과 같이 rownum 매개 변수의 지속성에 의해 반환 된 추가 rownum id를 가져올 것입니다.
package david.mybatis.model; import java.text.simpledateformat; import java.util.date; public class visitorwithrn {private int id; 개인 문자열 이름; 개인 문자열 이메일; 개인 int 상태; 개인 날짜 CreateTime; 개인 int rownum; public visitorwithrn () {// todo 자동 생성 생성자 스터브 createTime = new Date (); } public visitorwithrn (문자열 이름, 문자열 이메일) {this.name = 이름; this.email = 이메일; this.setstatus (1); this.createTime = 새 날짜 (); } public int getId () {return id; } public void setName (문자열 이름) {this.name = 이름; } public String getName () {return name; } public void seteMail (문자열 이메일) {this.email = 이메일; } public String getEmail () {반환 이메일; } 공개 날짜 getCreateTime () {return createTime; } public int getStatus () {return status; } public void setstatus (int status) {this.status = 상태; } public int getRownum () {return rownum; } public void setrownum (int rownum) {this.rownum = rownum; } @override public String toString () {// todo 자동 생성 메소드 스터브 리턴 Return.format ( "{rownum : %d, id : %d, name : %s, createTime : %s}", Rownum, id, name, new simpledateformat ( "yyyy-mm-dd hh : mm : ss")); }}ivisitorOperation에서 공개 목록 <visitorwithrn> getListBypagenatewithrn (pagenateargs args)이라는 새로운 방법을 만듭니다. 마찬가지로 VisitorMapper에서 해당 <select> 노드 및 스크립트를 구성해야합니다. 여기서 유일한 차이점은 다음과 같이 SQL 스크립트를 수정해야한다는 것입니다.
<? xml version = "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.dmo.dmo. useGeneratedKeys = "true"는 자체 성장 시퀀스를 사용하는지 여부를 의미합니다. keyProperty = "id"는 어떤 열이자가 성장 열인 열을 지정합니다. ParameterType = "방문자"는 ivisitorOperation interface 클래스에서 정의에 전달 된 해당 유형을 지정합니다. id = "insud" "keyProper" 방문자 (이름, 이메일, 상태, CreateTime) 값 ( #{name}, #{email}, #{atritains}, #{createTime}) </insert> <delete id = "delete"parametertype = "int"> visitater where where where and id = #{id} <upchange id = "vist"> #{name}, email =#{email}, status =#{status} 여기서 id =#{id} 및 상태> 0; </update> <select id = "query"parametertype = "int"resulttype = "visitor"> id =#{id} 및 id =#{id} 및 status </select> <select id = "basicquery"parametertype = "int"resulttype = "visitator"에서 id =#{id}#}##########{idect * select </select id = id = id = "rectations </select </select </select </select <lect <rectatient" < /select> <select> <getList "resultmap ="visitorrs "> <refid ="getListSql " /< /select> <sql id ="getListSql "> select * where where where where where where where> 0 < /sql> <resultmap type ="vistor "id ="visitorrs "> id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id"id "id" <result column = "이메일"속성 = "이메일" /> <결과 열 = "상태"속성 = "상태" /> <결과 열 = "CreateTime"Property = "CreateTime" /< /resultMap> <select id = "getListByPagenate"ParameterType = "pagenateargs"resulttype = "visititor"> wrome (<innude refid = ""getlistsql 포함 refid = "orderbysql"/>) t <!- #{}는 매개 변수화 된 출력을 의미합니다. $ {}는 직접 출력이 탈출 작업을 수행하지 않음을 의미합니다. 직접 출력을 직접 전송합니다-> <test = "pagestart> -1 및 pagesize> -1"> 제한 #{pagestart}, #{{{{{pagesize} </sect> <! <sq in <sql retples to the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the share retples </share. id = "orderbysql"> order by $ {orderfieldstr} $ {orderdipelstr} < /sql> <!-rownum을 사용하여 SQL 스크립트를 작성하는 방법-> <resultmap type = "visitorwithrn"id = "visitiorwithrnrs"> id column = "id"id "id rendat ="reencation = ""vest embel ""visitiorwithrn "id = 속성 = "이메일" /> <result column = "status"속성 = "상태" /> <result column = "createTime"property = "createTime" /> <결과 열 = "rownum"property = "rownum" /> < /resultmap> <select id = "getListBypagEnateWithrn"resultMap = "visititorswithrnrs">} seat} some} someparized in glop} some {} seart,} 출력은 탈출 작업을 수행하지 않고 직접 전송하지 않습니다-> t.rownum, t.id, t.name, t.email, t.status, t.createtime from (<include refid = "getListSqlContainsrn" /> <include refid = "OrderBysql" />) t < "pagestart> -1, pagestize> -1" " #{pagestart} #{pagesize} </if> </select> <sql id = "getListsqlContainsrn"> 선택 @Rownum : = @rownum+1 rownum, result.id, result.name, result.email, result.status, result.createTime from (Visitor) 다음으로 남은 것은 지금 Demorun 아래에서 테스트 방법을 추가하는 것입니다. 그래서 나는 여기에지도를 붙이지 않을 것입니다. 완료된 후에는 지금 6-10 개의 데이터가 다음과 같이 될 것임을 알 수 있습니다.