mybatis学习(八)——resultMap之association&&collection解析
一、resultMap的使用
resultMap 也是定义返回值类型,返回值为用户自定义的类型,可用于解决JavaBean中的属性名和数据库中的列名不一致的情况
之前对于JavaBean中属性名和数据库中的列名不一致的情况,通过有两种办法,1、通过在sql中使用别名 2、如果正好符合驼峰命名,需要在settings中配置,现在可以通过resultMap来解决
hotelMapper.xml
<?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="com.pjf.mybatis.dao.HotelMapper">
<!-- resultMap定义
type:javaBean的全类名,
id为该resultMap的唯一标识 -->
<resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
<!--id 指定主键的封装规则
column:数据库中列名
property:javaBean的属性名 -->
<id column="id" property="id" jdbcType="INTEGER" />
<!--result 指定非主键的封装规则
column:数据库中列名
property:javaBean的属性名 -->
<result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
<result column="hotel_address" property="hotelAddress"
jdbcType="VARCHAR" />
<result column="price" property="price" jdbcType="INTEGER" />
</resultMap> <!-- resultMap使用 -->
<select id="getHotel" resultMap="myHotel">
select * from hotel
where
id=#{id}
</select>
</mapper>
二、association的使用
association和collection都是用来关联另一个表的数据,区别就是用来关联对象的封装的,而collection是用来关联集合封装的,
举个例子,比如通过查询酒店,查出该酒店的城市,是一个城市对应一个酒店,用association
而查询一个城市的酒店,是一对多的,用collection,下面来具体实现下这个例子。
1、环境准备
修改hotel.java代码,增加一种类成员变量City,通过查询酒店,直接查出他所在的城市
package com.pjf.mybatis.po;
public class Hotel {
private int id;
private String hotelName;
private String hotelAddress;
private int price;
private City city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getHotelName() {
return hotelName;
}
public void setHotelName(String hotelName) {
this.hotelName = hotelName;
}
public String getHotelAddress() {
return hotelAddress;
}
public void setHotelAddress(String hotelAddress) {
this.hotelAddress = hotelAddress;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
@Override
public String toString() {
return "Hotel [id=" + id + ", hotelName=" + hotelName + ", hotelAddress=" + hotelAddress + ", price=" + price
+ "]";
}
}
增加城市类 City.java
package com.pjf.mybatis.po;
public class City {
private int cityCode;
private String cityName;
public int getCityCode() {
return cityCode;
}
public void setCityCode(int cityCode) {
this.cityCode = cityCode;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
@Override
public String toString() {
return "City [cityCode=" + cityCode + ", cityName=" + cityName + "]";
}
}
还有数据库的修改,hotel表中增加一列city_code,新增一个city表,
hotel表

city表

hotelMapper接口不变
package com.pjf.mybatis.dao;
import com.pjf.mybatis.po.Hotel;
public interface HotelMapper {
public Hotel getHotel(Integer i);
}
2、association的使用
通过association来关联city表,使用规则如下
hotelMapper.xml
<?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="com.pjf.mybatis.dao.HotelMapper">
<!-- resultMap定义 type:javaBean的全类名, id为该resultMap的唯一标识 -->
<resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
<!--id 指定主键的封装规则 column:数据库中列名 property:javaBean的属性名 -->
<id column="id" property="id" jdbcType="INTEGER" />
<!--result 指定非主键的封装规则 column:数据库中列名 property:javaBean的属性名 -->
<result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
<result column="hotel_address" property="hotelAddress"
jdbcType="VARCHAR" />
<result column="price" property="price" jdbcType="INTEGER" /> <!--association 关联的表
property 指被关联的类成员变量
javaType 指被关联的类成员变量的全类名 -->
<association property="city" javaType="com.pjf.mybatis.po.City">
<id column="city_code" property="cityCode" jdbcType="INTEGER"/>
<result column="city_name" property="cityName" jdbcType="VARCHAR"/>
</association>
</resultMap> <!-- resultMap使用 -->
<select id="getHotel" resultMap="myHotel">
select
h.id,h.hotel_name,h.hotel_address,h.price,c.city_code,c.city_name from
hotel h ,city c
where
h.city_code=c.city_code and h.id=#{id}
</select>
</mapper>
测试类:
package com.pjf.mybatis; import java.io.IOException;
import java.io.InputStream;
import java.util.Map; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test; import com.pjf.mybatis.dao.HotelMapper;
import com.pjf.mybatis.po.Hotel; public class TestHotel { public SqlSessionFactory sqlSessionFactory() throws IOException {
// mybatis的配置文件
String resource = "mybatis_config.xml";
// 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
InputStream is = Resources.getResourceAsStream(resource);
// 构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
return sessionFactory;
} // 查
@Test
public void getHotel() throws IOException { SqlSessionFactory sessionFactory = sqlSessionFactory();
SqlSession session = sessionFactory.openSession();
HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
System.out.println(hotelMapper.getClass());
Hotel hotel = hotelMapper.getHotel(1004);
// 打印酒店
System.out.println(hotel);
// 打印城市
System.out.println(hotel.getCity());
session.close();
}
}
这时候就可以看到结果了

3、association的分步查询的使用
三、collection的使用
实例:查询某个城市的全部酒店
修改city类
package com.pjf.mybatis.po;
import java.util.List;
public class City {
private int cityCode;
private String cityName;
private List<Hotel> hotel;
public List<Hotel> getHotel() {
return hotel;
}
public void setHotel(List<Hotel> hotel) {
this.hotel = hotel;
}
public int getCityCode() {
return cityCode;
}
public void setCityCode(int cityCode) {
this.cityCode = cityCode;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
@Override
public String toString() {
return "City [cityCode=" + cityCode + ", cityName=" + cityName + "]";
}
}
修改hotelMapper接口(可以重新定义一个接口和mapper.xml文件)
package com.pjf.mybatis.dao;
import com.pjf.mybatis.po.City;
public interface HotelMapper {
public City getCityHotel(Integer i);
}
hotelMapper.xml文件
<?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="com.pjf.mybatis.dao.HotelMapper">
<resultMap type="com.pjf.mybatis.po.City" id="cityHotel">
<id column="city_code" property="cityCode"/>
<result column="city_name" property="cityName"/>
<!--collection被关联的集合
ofType被关联集合元素的全类名
-->
<collection property="hotel" ofType="com.pjf.mybatis.po.Hotel">
<id column="id" property="id"/>
<result column="hotel_name" property="hotelName"/>
<result column="hotel_address" property="hotelAddress"/>
<result column="price" property="price"/>
</collection>
</resultMap> <select id="getCityHotel" resultMap="cityHotel">
SELECT c.city_code,c.city_name ,h.id,h.hotel_name,h.hotel_address,h.price
FROM city c LEFT JOIN hotel h ON c.city_code=h.city_code
WHERE c.city_code=#{cityCode}
</select>
</mapper>
测试类
package com.pjf.mybatis; import java.io.IOException;
import java.io.InputStream;
import java.util.Map; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test; import com.pjf.mybatis.dao.HotelMapper;
import com.pjf.mybatis.po.City;
import com.pjf.mybatis.po.Hotel; public class TestHotel { public SqlSessionFactory sqlSessionFactory() throws IOException {
// mybatis的配置文件
String resource = "mybatis_config.xml";
// 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
InputStream is = Resources.getResourceAsStream(resource);
// 构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
return sessionFactory;
} // 查
@Test
public void getHotel() throws IOException { SqlSessionFactory sessionFactory = sqlSessionFactory();
SqlSession session = sessionFactory.openSession();
HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
System.out.println(hotelMapper.getClass());
City city = hotelMapper.getCityHotel(1);
// 打印城市
System.out.println(city);
// 打印酒店
for (Hotel hotel : city.getHotel()) {
System.out.println(hotel);
}
session.close();
}
}
查看结果

mybatis学习(八)——resultMap之association&&collection解析的更多相关文章
- mybatis学习 十三 resultMap标签 一对一
1 .<resultMap>标签 写在mapper.xml中,由程序员控制SQL查询结果与实体类的映射关系. 在写<select>标签中,有一个resultType属性,此时s ...
- Mybatis学习笔记-ResultMap结果集映射
解决属性名与字段名不一致的问题 新建项目 --> 测试实体类字段不一致的情况 数据库字段:id,name,pwd 实体类属性:id,name,password 输出结果 User{id=1, n ...
- mybatis学习八 事物
1.事物的定义: 是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源. 2,事物的特性: ...
- Mybatis学习笔记导航
Mybatis小白快速入门 简介 本人是一个Java学习者,最近才开始在博客园上分享自己的学习经验,同时帮助那些想要学习的uu们,相关学习视频在小破站的狂神说,狂神真的是我学习到现在觉得最GAN的老师 ...
- MyBatis之ResultMap的association和collection标签详解
一.前言 MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子. 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样. 如果能有一种数据库映射模式, ...
- mybatis collection解析以及和association的区别
1.collection标签 说到mybatis的collection标签,我们肯定不陌生,可以通过它解决一对多的映射问题,举个例子一个用户对应多个系统权限,通过对用户表和权限表的关联查询我们可以得到 ...
- 解决 Mybatis 元素类型为 "resultMap" 的内容必须匹配 "(constructor?,id*,result*,association*,collection*,discriminat
在配置 mybatis mapper.xml文件时, 一不小心就会报如下类似的异常: Caused by: org.springframework.beans.factory.BeanCreation ...
- mybatis项目启动报错 The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collection*,discriminator?)".
启动项目报错 2018-02-26 17:09:51,535 ERROR [org.springframework.web.context.ContextLoader] - Context initi ...
- MyBatis学习 之 二、SQL语句映射文件(1)resultMap
目录(?)[-] 二SQL语句映射文件1resultMap resultMap idresult constructor association联合 使用select实现联合 使用resultMap实 ...
随机推荐
- [论文理解] Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks 简介 Faster R-CNN是很经典的t ...
- 一些常用的HTML标签
由于本人目前没有系统学习,日常碰见哪个有用就记下来. pre标签 可定义预格式化的文本,在pre元素中的文本会保留空格和换行符.比如我们展示源代码的时候,只要放一个pre标签,然后把代码直接复制.粘贴 ...
- 数据库连接池 dbcp与c3p0的使用区别
众所周知,无论现在是B/S或者是C/S应用中,都免不了要和数据库打交道.在与数据库交 互过程中,往往需要大量的连接.对于一个大型应用来说,往往需要应对数以千万级的用户连接请求,如果高效相应用户请求,对 ...
- 使用vs2013打开VS2015的工程文件的解决方案(适用于大多数vs低版本打开高版本)
前言:重装系统前我使用的是vs2015(有点装*),由于使用2015实在在班上太另类了, 导致我想在其他同学的vs下看一看我写的代码都无法达成! 而且最关键的是交作业的时候,老师的2013也没有办法打 ...
- VueJS坎坷之路222--vue cli 3.0引入静态文件
前两天准备搭建一个vue小项目,当引入jquery脚本的时候一直找不到引入的文件: 在网上搜了好多vue添加静态文件的方法,发现大多数方法都是创建一个与文件夹src同等级的文件夹static存放引入的 ...
- Python学习记录4(语句)
赋值语句 序列解包 条件语句 语句块 布尔变量 条件执行和if语句 条件运算符 循环 while语句 for循环 迭代工具 跳出循环 break continue while truebreak语句 ...
- Unity学习之路——C#相关
1.C#数组数组定义 int[] number; float[] score; string[] names;动态初始化,借助new运算符为数组元素分配空间int[] Array = new int[ ...
- 【数学 BSGS】bzoj2242: [SDOI2011]计算器
数论的板子集合…… Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最 ...
- python--字符编码理解
一.字符编码简史: 美国:1963年 ASCII (包含127个字符 占1个字节) 中国:1980年 GB2312 (收录7445个汉字,包括6763个汉字和682个其它符号) 1993年 GB13 ...
- python入门:while循环里面True和False的作用,真和假
#!/usr/bin/env python # -*- coding:utf-8 -*- #while循环里面True和False的作用,真和假 """ n1等于真(Tr ...