2个实体:订单、商品,一个订单可以包含多种商品,同时一种商品可以属于多个订单,即多对多。

商品表goods_tb:

订单表order_tb:

no是订单编号,user_id与用户表的id关联。

需要新建一张中间表order_item_tb,引入2个“多”的主键作为外键,把这2个“多”联系起来:

purchase_amount是该种商品的购买数量。


使用嵌套结果

(一)编写pojo类

package com.chy.pojo;

public class Goods {
private Integer id; //商品id
private String goodsName; //商品名称
private float goodsPrice; //商品单价
private Integer purchaseAmount; //购买数量 public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getGoodsName() {
return goodsName;
} public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
} public float getGoodsPrice() {
return goodsPrice;
} public void setGoodsPrice(float goodsPrice) {
this.goodsPrice = goodsPrice;
} public Integer getPurchaseAmount() {
return purchaseAmount;
} public void setPurchaseAmount(Integer purchaseAmount) {
this.purchaseAmount = purchaseAmount;
} @Override
public String toString() {
return "Goods{" +
"id=" + id +
", goodsName='" + goodsName + '\'' +
", goodsPrice=" + goodsPrice +
", purchaseAmount=" + purchaseAmount +
'}';
}
}
package com.chy.pojo;

import java.util.List;

public class Order {
private Integer no;
private Integer userId;
private List<Goods> goodsList; //包含的商品 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 List<Goods> getGoodsList() {
return goodsList;
} public void setGoodsList(List<Goods> goodsList) {
this.goodsList = goodsList;
} @Override
public String toString() {
return "Order{" +
"no=" + no +
", userId=" + userId +
", goodsList=" + goodsList +
'}';
}
}

在哪个pojo中使用List来关联其他实体,需要根据业务需求来确定。

(二)编写Mapper接口、映射文件

package com.chy.mapper;

import com.chy.pojo.Order;

public interface OrderMapper {
//根据orderId查询订单信息
public Order queryOrderByOrderNo(Integer orderNo);
}
<?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="queryOrderByOrderNo" parameterType="integer" resultMap="orderResultWithGoods">
SELECT order_tb.*,goods_tb.*,order_item_tb.purchase_amount
FROM order_tb,goods_tb,order_item_tb
WHERE order_tb.no=#{no} AND order_item_tb.order_no=order_tb.no AND goods_tb.id=order_item_tb.goods_id
</select>
<resultMap id="orderResultWithGoods" type="order">
<id property="no" column="no"/>
<result property="userId" column="user_id"/>
<collection property="goodsList" ofType="goods">
<id property="id" column="id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPrice" column="goods_price"/>
<result property="purchaseAmount" column="purchase_amount"/>
</collection>
</resultMap>
</mapper>

三表联合查询,sql语句很长,如果觉得表名、字段名不好写,可以用as设置表名、字段名的别名。

不是每个pojo类都要写对应的Mapper接口、映射文件,写哪些,看业务需求。

(三)使用

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.OrderMapper;
import com.chy.pojo.Order;
import com.chy.utils.MyBatisUtils;
import org.apache.ibatis.session.*; public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
Order order = mapper.queryOrderByOrderNo(1);
System.out.println(order);
sqlSession.close();
}
}

结果:

Order{no=1, userId=1, goodsList=[Goods{id=1, goodsName='抽纸', goodsPrice=6.5, purchaseAmount=1}, Goods{id=2, goodsName='中华', goodsPrice=80.0, purchaseAmount=2}]}

mybatis让开发人员专注于数据库的设计、sql语句的编写,而不需要花费过多精力在jdbc的底层操作上。


使用嵌套查询

与嵌套结果大体相同,不同的只有第二步:

(二)编写双方的Mapper接口、映射文件

package com.chy.mapper;

import com.chy.pojo.Order;

public interface OrderMapper {
//根据orderId查询订单信息
public Order queryOrderByOrderNo(Integer orderNo);
}
<?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="queryOrderByOrderNo" parameterType="integer" resultMap="orderResultWithGoods">
SELECT * FROM order_tb WHERE no=#{no}
</select>
<resultMap id="orderResultWithGoods" type="order">
<id property="no" column="no"/>
<result property="userId" column="user_id"/>
<collection property="goodsList" select="com.chy.mapper.GoodsMapper.queryGoodsByGoodsId" column="no" ofType="goods" />
</resultMap>
</mapper>
package com.chy.mapper;

import com.chy.pojo.Goods;
import java.util.List; public interface GoodsMapper {
public List<Goods> queryGoodsByGoodsId(Integer goodsId);
}
<?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.GoodsMapper">
<select id="queryGoodsByGoodsId" parameterType="integer" resultMap="goodsMapper">
SELECT * FROM goods_tb WHERE id IN (
SELECT goods_id FROM order_item_tb WHERE order_no=#{no}
)
</select>
<resultMap id="goodsMapper" type="goods">
<id property="id" column="id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPrice" column="goods_price"/>
</resultMap>
</mapper>

子查询的常见写法:in(查中间表)。

此处配置了resultMap,因为表的字段名和pojo类的成员变量名不一致,需要手动配置。

我为了图方便,把每种商品的购买数量写在了Goods类中,如果要映射purchaseAmount,可以这样写:

<?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.GoodsMapper">
<select id="queryGoodsByGoodsId" parameterType="integer" resultMap="goodsMapper">
SELECT goods_tb.*,order_item_tb.purchase_amount FROM goods_tb,order_item_tb WHERE goods_tb.id IN (
SELECT goods_id FROM order_item_tb WHERE order_no=#{no}
) AND order_item_tb.order_no=#{no}
</select>
<resultMap id="goodsMapper" type="goods">
<id property="id" column="id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPrice" column="goods_price"/>
<result property="purchaseAmount" column="purchase_amount"/>
</resultMap>
</mapper>

注意

如果关联对象的表的字段和pojo类的成员变量不一致,·比如表字段是goods_price,成员变量是goodsPrice,这需要手动配置关联对象的映射。

嵌套结果是在<association> | <collection>中配置,嵌套查询是在子查询的mapper中使用resultMap进行配置。

MyBatis 关联查询的实现:多对多的更多相关文章

  1. Mybatis关联查询之一对多和多对一XML配置详解

    平时在开发过程中dao.bean和XML文件都是自动生成的,很少写XML的配置关系,今天记录一下mybatis的关联查询中的多对一和一对多的情况. 首先是有两张表(学生表Student和老师Teach ...

  2. Mybatis关联查询之二

    Mybatis关联查询之多对多 多对多 一.entity实体类 public class Student { private Integer stuid; private String stuname ...

  3. mybatis关联查询基础----高级映射

    本文链接地址:mybatis关联查询基础----高级映射(一对一,一对多,多对多) 前言: 今日在工作中遇到了一个一对多分页查询的问题,主表一条记录对应关联表四条记录,关联分页查询后每页只显示三条记录 ...

  4. Mybatis关联查询和数据库不一致问题分析与解决

    Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...

  5. MyBatis基础:MyBatis关联查询(4)

    1. MyBatis关联查询简介 MyBatis中级联分为3中:association.collection及discriminator. ◊ association:一对一关联 ◊ collecti ...

  6. MyBatis关联查询,一对多关联查询

    实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...

  7. mybatis 关联查询实现一对多

    场景:最近接到一个项目是查询管理人集合  同时每一个管理人还存在多个出资人   要查询一个管理人列表  每个管理人又包含了出资人列表 采用mybatis关联查询实现返回数据. 实现方式: 1 .在实体 ...

  8. MyBatis关联查询、多条件查询

    MyBatis关联查询.多条件查询 1.一对一查询 任务需求; 根据班级的信息查询出教师的相关信息 1.数据库表的设计 班级表: 教师表: 2.实体类的设计 班级表: public class Cla ...

  9. MyBatis关联查询和懒加载错误

    MyBatis关联查询和懒加载错误 今天在写项目时遇到了个BUG.先说一下背景,前端请求更新生产订单状态,后端从前端接收到生产订单ID进行查询,然后就有问题了. 先看控制台报错: org.apache ...

  10. mybatis关联查询,一对一,一对多

    注:这篇文章的代码有部分删减,不能直接使用,不过关键代码都存在  应用场景: 想用mybatis做关联查询,并且把查询出的数据自动组装成对象可以使用关联查询. 1.一对一实现 例如:一部小说,属于一个 ...

随机推荐

  1. sizeof strlen 求char*字符串的长度

    sizeof只是求变量所占的字节数,sizeof(char *) = 4字节: strlen(char*) 可以得到整个字符串的长度. 如果是数组vec,那么使用sizeof就可以得到整个数组的所占的 ...

  2. 0105 springMVC开发基础

    背景 已经明确了MVC的思想和SpringMVC的基本流程,下面就都具体的mvc开发细节知识了. @RequestMapping springMVC核心流程中,启动阶段会把注解@RequeestMap ...

  3. Unity 脚本中的update,fixedupdate,lateupdate

    先放着 有功儿夫再来整理 https://www.cnblogs.com/fly-100/p/3777731.html https://www.cnblogs.com/hont/p/5184802.h ...

  4. FC 与 FB 与 OB 的区别,时间标记冲突与一致性检查 有详细的步骤

    关键字1 组织块的程序是由用户自己编写. 关键字2 时间标记冲突与一致性检查 有详细的步骤. 关键字3 FC 与 FB 与 OB 的区别?   (一)功能 功能块 区别 ? FB 和FC均为 用户编写 ...

  5. 20190108PLC学习心得

    应该是数据类型不对 F1查看了帮助文件以后 ,看到 LD应该是用指针类型的数据 改正以后 LD0下的红线消失了 .       绿色 代表没有给 符号 定义 地址     假设 我现在给 符号 字节数 ...

  6. bmp

    function GetNumberBuffer(cZi: string; cwidth, cheight: Integer; FontName: string; bold, italic: Bool ...

  7. C#数据库查询和操作大全

    一:C#数据库查询之数据库连接代码: SqlConnectionobjSqlConnection=newSqlConnection("server=127.0.0.1;uid=sa;pwd= ...

  8. tkinter中控件menu的两种组织方法

    tkinter中,菜单控件组织方法有两种,使用中常出现混淆,为明晰各个正确用法,特整理撰写此博文.菜单控件的组织实际上是通过一个“母菜单”和“子菜单”构成,“母菜单”一方面与master连接(即与依附 ...

  9. 配置mysql时报错

    配置mysql时无法启动此程序,因为计算机丢失MSVCR100.dll. 去https://cn.dll-files.com/下载相应的版本 复制MSVCR100.dll 粘贴到下面 32位系统: 复 ...

  10. Inheritance and the prototype chain 继承和 原型 链

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain Inherita ...