注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

╰此情可待成追忆

当没有阳光时,我自己便是阳光,当没有快乐时,我自己便是快乐

 
 
 

日志

 
 

一步步学Mybatis-实现多表联合查询(4)  

2014-07-16 22:32:19|  分类: MyBatis+iBatis |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://www.blogjava.net/davidjefiny/archive/2013/12/24/407985.html


上一章节中我们已经完成了对单表的CRUD操作,接下来今天这一讲讲述的是关于Mybatis在多表查询时候的应用,毕竟实际业务中也是多表的联合查询比较多嘛~

还记得最一开始我们新建过一张Website表吗,在那张表里有个VisitorId字段,表示访问者访问过哪些网站,现在我们先按照上一张中的要求把关于Website的JavaBean实体先建立出来。

还是在david.mybatis.model包下面新建一个Website类,用来持久化数据之用,重写下相应toString()方法,方便测试程序之用。

一步步学Mybatis-实现多表联合查询(4) - ╰此情可待成追忆 - ╰此情可待成追忆
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下面分别新建相应的操作接口:


一步步学Mybatis-实现多表联合查询(4) - ╰此情可待成追忆 - ╰此情可待成追忆
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();
    
}

在mapper文件夹下新建WebsiteMapper.xml映射文件,分别参照上一张所说的把增删改查的单表操作配置分别放进去,这样你可以建造一点测试数据。如下

一步步学Mybatis-实现多表联合查询(4) - ╰此情可待成追忆 - ╰此情可待成追忆
<?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>

这里今天主要说的就是那个查,现在我们想要查询网站的同时分别把相应的访问者信息一起拿出来,怎么做呢,大家可以参照配置中的query,写下联表查询的SQL,

这里主要要注意的是,Website实体与Visit的实体里面Id与Name这2个属性都是一样的,所以为了避免映射出现出错现象,把相应的查询结果列起上不一样的别名,这样绑定的时候就可以避免

假如我想下面一样配置会得到什么呢?

一步步学Mybatis-实现多表联合查询(4) - ╰此情可待成追忆 - ╰此情可待成追忆
<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的位置,相互换下就会发现结果又神奇的变了

所以需要起个别名避免这种情况,这样你就会发现真相其实只有一个就是下面的:

大 家可以看到其实多表处理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^

  评论这张
 
阅读(608)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017