MyBatis 关联查询的实现:一对多
有2个实体:用户、订单,一个用户可以拥有多个订单,同时这多个订单属于一个用户,即一对多。
user_tb:

order_tb:

在“多”的一方(order)添加“一”的一方(user)的主键(user_id)作为外键。
使用嵌套结果
(1)给2个实体都编写pojo类,需要在“一”的一方写个List来关联“多”的一方
package com.chy.pojo;
public class Order {
private Integer no;
private Integer userId;
private Integer goodsId;
private Integer goodsAmount;
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getGoodsId() {
return goodsId;
}
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public Integer getGoodsAmount() {
return goodsAmount;
}
public void setGoodsAmount(Integer goodsAmount) {
this.goodsAmount = goodsAmount;
}
@Override
public String toString() {
return "Order{" +
"no=" + no +
", userId=" + userId +
", goodsId=" + goodsId +
", goodsAmount=" + goodsAmount +
'}';
}
}
package com.chy.pojo;
import java.util.List;
public class User {
private Integer id;
private String username;
private String password;
private String tel;
private String address;
private List<Order> orderList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", tel='" + tel + '\'' +
", address='" + address + '\'' +
", orderList=" + orderList +
'}';
}
}
toString()只是为了方便测试、调试,后期可以去掉。
(2)给“一”的一方写Mapper接口、xml映射文件
package com.chy.mapper;
import com.chy.pojo.User;
public interface UserMapper {
public User queryUserById(Integer id);
}
<?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.chy.mapper.UserMapper">
<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
SELECT user_tb.*,order_tb.* FROM user_tb,order_tb WHERE user_tb.id=#{id} AND order_tb.user_id=user_tb.id
</select>
<resultMap id="userResultWithOrder" type="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="tel" column="tel"/>
<result property="address" column="address"/>
<collection property="orderList" ofType="order">
<id property="no" column="no"/>
<result property="userId" column="user_id" />
<result property="goodsId" column="goods_id" />
<result property="goodsAmount" column="goods_amount" />
</collection>
</resultMap>
</mapper>
因为关联的是集合(List),所以用<collection>。
- property指定表示关联对象的成员变量名
- ofType指定返回的数据类型,注意不是list。
- 子元素<id>、<result>配置关联对象的映射。
所谓关联查询,是查询结果中同时包含双方(2张表)的多个字段,
如果只查询一张表的字段,比如说只查询某个用户的订单,不查询此用户本身的信息,直接根据外键user_id查order_tb表,不需要查user_tb,不必使用关联查询,写个OrderMapper接口、OrderMapper.xml就ok。
(3)使用
package com.chy.utils; 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 java.io.IOException;
import java.io.InputStream; public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory; static {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
} public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
package com.chy.test; import com.chy.mapper.UserMapper;
import com.chy.pojo.User;
import com.chy.utils.MyBatisUtils;
import org.apache.ibatis.session.*; public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
sqlSession.close();
}
}
使用嵌套查询
与嵌套结果大体相同,不同的只有第二步:
(二)给双方都编写Mapper接口、映射文件
package com.chy.mapper;
import com.chy.pojo.Order;
public interface OrderMapper {
//根据orderId查询订单信息
public Order queryOrderByUserId(Integer userId);
}
<?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.chy.mapper.OrderMapper">
<select id="queryOrderByUserId" parameterType="integer" resultMap="orderMap">
SELECT * FROM order_tb WHERE user_id=#{id}
</select>
<resultMap id="orderMap" type="order">
<id property="no" column="no"/>
<result property="userId" column="user_id"/>
<result property="goodsId" column="goods_id"/>
<result property="goodsAmount" column="goods_amount"/>
</resultMap>
</mapper>
package com.chy.mapper;
import com.chy.pojo.User;
public interface UserMapper {
public User queryUserById(Integer id);
}
<?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.chy.mapper.UserMapper">
<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
SELECT * FROM user_tb WHERE id=#{id}
</select>
<resultMap id="userResultWithOrder" type="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="tel" column="tel"/>
<result property="address" column="address"/>
<collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
</resultMap>
</mapper>
column指定向子查询传递的参数是当前表的哪一列。
<resultMap>中的映射问题
我在<resultMap>中使用了子元素<id>、<result>配置了所有的表字段——pojo类属性之间的映射,
其实只要表字段、pojo类属性的名称一致,就不必配置,比如
<resultMap id="userResultWithOrder" type="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="tel" column="tel"/>
<result property="address" column="address"/>
<collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
</resultMap>
红色部分完全可以省略,因为默认的映射就是pojo类属性、表字段名称一致。
如果部分不一致,只需配置不一致的部分,比如只有用户id的不一致:
<resultMap id="userResultWithOrder" type="user">
<id property="id" column="user_id"/>
<collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
</resultMap>
MyBatis 关联查询的实现:一对多的更多相关文章
- MyBatis关联查询,一对多关联查询
实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...
- mybatis 关联查询实现一对多
场景:最近接到一个项目是查询管理人集合 同时每一个管理人还存在多个出资人 要查询一个管理人列表 每个管理人又包含了出资人列表 采用mybatis关联查询实现返回数据. 实现方式: 1 .在实体 ...
- MyBatis基础:MyBatis关联查询(4)
1. MyBatis关联查询简介 MyBatis中级联分为3中:association.collection及discriminator. ◊ association:一对一关联 ◊ collecti ...
- MyBatis关联查询、多条件查询
MyBatis关联查询.多条件查询 1.一对一查询 任务需求; 根据班级的信息查询出教师的相关信息 1.数据库表的设计 班级表: 教师表: 2.实体类的设计 班级表: public class Cla ...
- mybatis关联查询基础----高级映射
本文链接地址:mybatis关联查询基础----高级映射(一对一,一对多,多对多) 前言: 今日在工作中遇到了一个一对多分页查询的问题,主表一条记录对应关联表四条记录,关联分页查询后每页只显示三条记录 ...
- Mybatis关联查询和数据库不一致问题分析与解决
Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...
- Mybatis关联查询之二
Mybatis关联查询之多对多 多对多 一.entity实体类 public class Student { private Integer stuid; private String stuname ...
- MyBatis关联查询和懒加载错误
MyBatis关联查询和懒加载错误 今天在写项目时遇到了个BUG.先说一下背景,前端请求更新生产订单状态,后端从前端接收到生产订单ID进行查询,然后就有问题了. 先看控制台报错: org.apache ...
- mybatis关联查询,一对一,一对多
注:这篇文章的代码有部分删减,不能直接使用,不过关键代码都存在 应用场景: 想用mybatis做关联查询,并且把查询出的数据自动组装成对象可以使用关联查询. 1.一对一实现 例如:一部小说,属于一个 ...
随机推荐
- 安装oracle客户端后,怎样设置电脑的环境变量?
安装配置参考: http://www.haodaima.net/art/2854001 设置环境变量(修改PATH和TNS_ADMIN环境变量): 对于NLS_LANG环境变量, 最好设置成和数据库端 ...
- k-近邻算法的优缺点及拓展思考
//2019.08.03晚#k-近邻算法的拓展思考与总结1.k-近邻算法是一种非常典型的分类监督学习算法,它可以解决多分类的问题:另外,它的整体思想简单,效果强大.它也可以用来解决回归问题,使用的库函 ...
- 题目:给定一数组 例如:a = [1,2,3,5,2,1] 现用户提供一个数字 请返回用户所提供的数字的所有下标
def test(ary): ds = {} for i in range(len(ary)): if ds.get(ary[i]): ds[ary[i]].append(i) else: ds[ar ...
- 弱点扫描-openvas初始化
OPENVAS: NESSUS项目分支:商业版的扫描器 管理目标系统的漏洞 免费开源 Kali 默认安装但是未配置个启动 安装 创建证书 同步弱点数据库 创建客户端证书 重建数据库 备份数据库 启动服 ...
- Redis原理详解
Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...
- generator 和 yield
yield 的使用 generator 生成器 yield 可以使生成器返回多次 我习惯于从表象推测,不喜欢官方文档,写的字都认识,结果变成句子之后,就一句都看不懂 所以先举一个例子来看一下这个东西怎 ...
- vue打包部署(含2.0)
到这里vue的所有平时使用的知识点都写完了 先补充一下vue2.x的安装 ## 全局脚手架 npm install vue/cli -g ## 查看版本 vue --version ## 新建项目 v ...
- sourcetree的安装
参考博文: SourceTree安装教程和GitLab配置详解 关于Atlassian无法注册的问题 SourceTree跳过Atlassian账号,免登陆,跳过初始设置 sourcetree跳过注册 ...
- python2.7编译安装升级python3并安装Scrapy
一.安装python3 1.wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz 2.编译安装,在编译安装前需要构建编译环境,安装 ...
- Consul 简介及集群安装
简介 Consul是基于GO语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册.服务发现和配置管理的功能. Consul的功能都很实用,其中包括:服务注册/发现.健康检查.Key/Value ...