一步步學Mybatis-實現多表聯合查詢(4)

  上一章節中咱們已經完成了對單表的CRUD操做,接下來今天這一講講述的是關於Mybatis在多表查詢時候的應用,畢竟實際業務中也是多表的聯合查詢比較多嘛~html

還記得最一開始咱們新建過一張Website表嗎,在那張表裏有個VisitorId字段,表示訪問者訪問過哪些網站,如今咱們先按照上一張中的要求把關於Website的JavaBean實體先創建出來。java

仍是在david.mybatis.model包下面新建一個Website類,用來持久化數據之用,重寫下相應toString()方法,方便測試程序之用。git

package david.mybatis.model;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Website {
    private int id;
    private String name;
    private int visitorId;
    private int status;
    private Date createTime;
    private Visitor visitor;

    public Website() {
        // TODO Auto-generated constructor stub
        createTime = new Date();
        visitor = new Visitor();
    }

    public Website(String name, int visitorId) {
        this.name = name;
        this.visitorId = visitorId;
        visitor = new Visitor();
        status = 1;
        createTime = new Date();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Visitor getVisitor() {
        return visitor;
    }

    public void setVisitor(Visitor visitor) {
        this.visitor = visitor;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Date 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();
        return 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").format(createTime)));
        if (visitor != null)
            sb.append(String.format("Visitor=> %s", visitor.toString()));
        return sb.toString();
    }
}
Website實體類

在david.mybatis.demo下面分別新建相應的操做接口:github

package david.mybatis.demo;

import java.util.List;
import david.mybatis.model.Website;

public interface IWebsiteOperation {
    
    public int add(Website website);
    
    public int delete(int id);
    
    public int update(Website website);
    
    public Website query(int id);
    
    public List<Website> getList();
    
}
Website操做接口

在mapper文件夾下新建WebsiteMapper.xml映射文件,分別參照上一張所說的把增刪改查的單表操做配置分別放進去,這樣你能夠建造一點測試數據。以下web

<?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.mybatis.demo.IWebsiteOperation">
    <sql id="getListSql">
        select id,
        name, VisitorId, status, createTime from Website
        where status>0
    </sql>
    <insert id="add" parameterType="Website" useGeneratedKeys="true"
        keyProperty="Id">
        insert into Website (Name, VisitorId, Status, CreateTime)
        values (#{name}, #{visitorId}, #{status}, #{createTime})
    </insert>
    <delete id="delete" parameterType="int">
        delete from website where
        status>0 and id = #{id}
    </delete>
    <update id="update" parameterType="Website">
        update website set
        name=#{name} where status>0 and id=#{id}
    </update>
    <select id="query" parameterType="int" resultMap="websiteRs">
        select
        Website.id siteId, Website.name siteName, Visitor.Id visitorId,
        Visitor.name visitorName,
        Website.status siteStatus, Website.createtime
        siteCreateTime from Website
        inner join Visitor on Website.visitorid =
        Visitor.id where Website.status>0 and
        Website.id=#{id}
    </select>
    <resultMap type="Website" id="websiteRs">
        <id column="siteId" 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 column="visitorId" property="id" />
        <result column="visitorName" property="name" />
    </resultMap>
    <select id="getList" resultMap="websiteByVisitorIdRs">
    <include refid="getListSql" />
    </select>    
</mapper>
WebsiteMapper配置

這裏今天主要說的就是那個查,如今咱們想要查詢網站的同時分別把相應的訪問者信息一塊兒拿出來,怎麼作呢,你們能夠參照配置中的query,寫下聯表查詢的SQL,sql

這裏主要要注意的是,Website實體與Visit的實體裏面Id與Name這2個屬性都是同樣的,因此爲了不映射出現出錯現象,把相應的查詢結果列起上不同的別名,這樣綁定的時候就能夠避免mybatis

假如我像下面同樣配置會獲得什麼呢?app

<select id="query" parameterType="int" resultMap="websiteRs">
    select
    Website.id, Website.name siteName, Visitor.Id,
    Visitor.name visitorName,
    Website.status siteStatus, Website.createtime
    siteCreateTime from Website
    inner join Visitor on Website.visitorid =
    Visitor.id where Website.status>0 and
    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 column="id" property="id" />
    <result column="visitorName" property="name" />
</resultMap>
可能引發錯誤的配置

有木有發覺,Visitor的Id也變成2了,這個其實它默認映射了Website的ID,由於SQL語句查詢出來的結果2個ID都是變成2了,有人會問爲何不是4呢,由於他默認匹配第一個若是你把Website.Id與Visit.Id的位置,相互換下就會發現結果又神奇的變了ide

因此須要起個別名避免這種狀況,這樣你就會發現真相其實只有一個就是下面的:測試

你們能夠看到其實多表處理resultMap的方式和單表是一致的,也無非是吧列明與Javabean屬性名成對應上去,能夠看到在Website的<resultMap>節點裏面前臺另一個resultMap,他就是表明Visit實體所須要映射的實體,可使用如下方式進行關聯

<association property="visitor" javaType="Visitor" resultMap="visitorRs" />

其中的visitor就是Website實體中的visit字段名,必須保證名稱一致,不然就會拋出There is no getter for property named 'XXX' in 'class david.mybatis.model.Website'的異常,這在上幾章已經講述了,固然若是你以爲不用嵌套resultMap也行,嵌套也是出於其餘地方能夠還要用到這個配置那就提煉出來的過程,也是抽象出來的一種思想。具體使用<resultMap>中的ID與Result能夠從官網查找相應區別說明:http://mybatis.github.io/mybatis-3/sqlmap-xml.html#Result_Maps

這樣,一個簡單的多表聯合查詢就出來啦~,若是還有更加複雜的查詢業務費是在這個基礎上些許的變通修改。

這章就到此爲止啦,下一章會繼續跟講下,如何弄一個簡單的Mybatis下的分頁效果~^0^

相關文章
相關標籤/搜索