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_timeView Codedatetime 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, ‘宣武區‘)
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_codeView 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_codeView 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(一)一對一,一對多,多對一