mybatis一对一,一对多,多对一

Posted yyyyy-1988

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis一对一,一对多,多对一相关的知识,希望对你有一定的参考价值。

给出一个城市对应行政区域的业务场景,如天津市有南开区、红桥区,这样城市对应区是一对多,相反区对应城市是多对一,下面给出简单的数据库设计

技术分享图片
-- 城市表
drop table if exists city;
create table city (
city_code tinyint(4) not null comment 城市代码 天津:1,北京:2,
city_name varchar(10) not null comment 城市名称 天津,北京,
create_time datetime not null default now() comment 创建时间,
modify_time datetime not null default now() comment 修改时间,
primary key (city_code)
) engine=innodb default charset=utf8 comment=城市表;

-- 行政区域表
drop table if exists area;
create table area (
id int(10) not null auto_increment comment 主键,
city_code tinyint(4) not null comment 城市代码 天津:1,北京:2,
area_code tinyint(4) unique not null comment 区域代码 南开区:1,朝阳区:2,
area_name varchar(10) not null comment 区域名称 南开区,朝阳区,
create_time datetime not null default now() comment 创建时间,
modify_time datetime not null default now() comment 修改时间,
primary key (id)
) engine=innodb default charset=utf8 comment=行政区域表;

-- sql init:
insert ignore into city (city_code, city_name) values (1, 天津市),(2, 北京市)
insert ignore into area (city_code, area_code, area_name) values (1, 1, 南开区),(1, 2, 和平区),(1, 3, 河西区),(2, 4, 朝阳区),(2, 5, 宣武区)
View Code

1.一对多:

一对多的话其实通常我们想要的结果是一个实体bean中含有多个另外实体bean的即(带有一个list属性),这个场景中我们应该返回两条数据(一条天津的一条北京的),先来看下一对多情况在数据库执行的情况:

技术分享图片
select t1.city_code, t1.city_name, t2.area_code, t2.area_name from city t1
left join area t2 on t1.city_code = t2.city_code
View Code

技术分享图片

很明显,数据库中返回5个对象不是我们想要的结果,但是相同的sql在mybatis中执行,会得到我们想要的结果

技术分享图片
<resultMap id="City" type="cn.yyyyy.example.entity.City">
    <id column="city_code" jdbcType="INTEGER" property="cityCode" />
    <result column="city_name" jdbcType="VARCHAR" property="cityName" />
    <collection property="areaList" resultMap="Area" />
</resultMap>

<resultMap id="Area" type="cn.yyyyy.example.entity.Area">
    <id column="area_code" jdbcType="INTEGER" property="areaCode" />
    <result column="area_name" jdbcType="VARCHAR" property="areaName" />
</resultMap>

<select id="listCity" resultMap="City">
    select t1.city_code, t1.city_name, t2.area_code, t2.area_name from city t1
    left join area t2 on t1.city_code = t2.city_code
</select>
View Code

得出结果:

[City{cityCode=1, cityName=‘天津市‘, areaList=[Area{areaCode=1, areaName=‘南开区‘, cityCode=null}, Area{areaCode=2, areaName=‘和平区‘, cityCode=null}, Area{areaCode=3, areaName=‘河西区‘, cityCode=null}]}, City{cityCode=2, cityName=‘北京市‘, areaList=[Area{areaCode=4, areaName=‘朝阳区‘, cityCode=null}, Area{areaCode=5, areaName=‘宣武区‘, cityCode=null}]}]

给出相关实体bean代码:

技术分享图片
package cn.yyyyy.example.entity;

import java.util.List;

public class City {

    private Integer cityCode;

    private String cityName;

    private List<Area> areaList;

    public Integer getCityCode() {
        return cityCode;
    }

    public void setCityCode(Integer cityCode) {
        this.cityCode = cityCode;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public List<Area> getAreaList() {
        return areaList;
    }

    public void setAreaList(List<Area> areaList) {
        this.areaList = areaList;
    }

    @Override
    public String toString() {
        return "City{" +
                "cityCode=" + cityCode +
                ", cityName=‘" + cityName + ‘‘‘ +
                ", areaList=" + areaList +
                ‘}‘;
    }
}
View Code
技术分享图片
package cn.yyyyy.example.entity;

public class Area {

    private Integer areaCode;

    private String areaName;

    private Integer cityCode;

    public Integer getAreaCode() {
        return areaCode;
    }

    public void setAreaCode(Integer areaCode) {
        this.areaCode = areaCode;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public Integer getCityCode() {
        return cityCode;
    }

    public void setCityCode(Integer cityCode) {
        this.cityCode = cityCode;
    }

    @Override
    public String toString() {
        return "Area{" +
                "areaCode=" + areaCode +
                ", areaName=‘" + areaName + ‘‘‘ +
                ", cityCode=" + cityCode +
                ‘}‘;
    }
}
View Code

 2.多对一,一对一

之所以把一对一归到多对一是因为可以把一对一看做多对一的一种特例,还是现在数据库中看下结果:

技术分享图片
select t1.area_code, t1.area_name, t2.city_code, t2.city_name from area t1 left join city t2 on t1.city_code = t2.city_code
View Code

技术分享图片

技术分享图片
<resultMap id="City" type="cn.yyyyy.example.entity.City">
    <id column="city_code" jdbcType="INTEGER" property="cityCode" />
    <result column="city_name" jdbcType="VARCHAR" property="cityName" />
</resultMap>

<resultMap id="Area" type="cn.yyyyy.example.entity.Area">
    <id column="area_code" jdbcType="INTEGER" property="areaCode" />
    <result column="area_name" jdbcType="VARCHAR" property="areaName" />
    <association property="city" resultMap="City" />
</resultMap>
<select id="listArea" resultMap="Area">
    select t1.area_code, t1.area_name, t2.city_code, t2.city_name from area t1
    left join city t2 on t1.city_code = t2.city_code
</select>
View Code

结果:[Area{areaCode=1, areaName=‘南开区‘, cityCode=null, city=City{cityCode=1, cityName=‘天津市‘, areaList=null}}, Area{areaCode=2, areaName=‘和平区‘, cityCode=null, city=City{cityCode=1, cityName=‘天津市‘, areaList=null}}, Area{areaCode=3, areaName=‘河西区‘, cityCode=null, city=City{cityCode=1, cityName=‘天津市‘, areaList=null}}, Area{areaCode=4, areaName=‘朝阳区‘, cityCode=null, city=City{cityCode=2, cityName=‘北京市‘, areaList=null}}, Area{areaCode=5, areaName=‘宣武区‘, cityCode=null, city=City{cityCode=2, cityName=‘北京市‘, areaList=null}}]

实体bean代码:

技术分享图片
package cn.yyyyy.example.entity;

public class Area {

    private Integer areaCode;

    private String areaName;

    private Integer cityCode;

    private City city;

    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    public Integer getAreaCode() {
        return areaCode;
    }

    public void setAreaCode(Integer areaCode) {
        this.areaCode = areaCode;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public Integer getCityCode() {
        return cityCode;
    }

    public void setCityCode(Integer cityCode) {
        this.cityCode = cityCode;
    }

    @Override
    public String toString() {
        return "Area{" +
                "areaCode=" + areaCode +
                ", areaName=‘" + areaName + ‘‘‘ +
                ", cityCode=" + cityCode +
                ", city=" + city +
                ‘}‘;
    }
}
View Code
技术分享图片
package cn.yyyyy.example.entity;

import java.util.List;

public class City {

    private Integer cityCode;

    private String cityName;

    private List<Area> areaList;

    public Integer getCityCode() {
        return cityCode;
    }

    public void setCityCode(Integer cityCode) {
        this.cityCode = cityCode;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public List<Area> getAreaList() {
        return areaList;
    }

    public void setAreaList(List<Area> areaList) {
        this.areaList = areaList;
    }

    @Override
    public String toString() {
        return "City{" +
                "cityCode=" + cityCode +
                ", cityName=‘" + cityName + ‘‘‘ +
                ", areaList=" + areaList +
                ‘}‘;
    }
}
View Code

 3.tips

(1)重写toString方法可以使用json形式,这样在实体bean追加属性的时候可以不用再修改toString方法,这里用到的是fastJson,给出maven坐标:

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
技术分享图片
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
View Code

(2)打印sql,使用logback,在配置中加入

<logger name="cn.yyyyy.example.dao" level="DEBUG" />

2019-01-10 09:43:22.622 [] DEBUG cn.yyyyy.example.dao.CityDao.listArea - ==> Preparing: select t1.area_code, t1.area_name, t2.city_code, t2.city_name from area t1 left join city t2 on t1.city_code = t2.city_code
2019-01-10 09:43:22.651 [] DEBUG cn.yyyyy.example.dao.CityDao.listArea - ==> Parameters:
2019-01-10 09:43:22.668 [] DEBUG cn.yyyyy.example.dao.CityDao.listArea - <== Total: 5



以上是关于mybatis一对一,一对多,多对一的主要内容,如果未能解决你的问题,请参考以下文章

mybatis 一对一 一对多 多对多

MyBatis一对多,多对一,多对多

Mybatis: 一对多,多对一

Mybatis 高级映射,一对一,一对多,多对多映射

mybatis一对一,一对多,多对一

MyBatis 详解(一对一,一对多,多对多)