Mybatis之多表查询

目录

一、简介

1、使用嵌套查询:

[2、使用多个 SQL 语句:](#2、使用多个 SQL 语句:)

3、使用关联查询:

4、使用自定义映射查询:

二、业务场景

三、示例

1、一对一查询

2、一对多查询


一、简介

MyBatis 是一个优秀的持久层框架,它提供了强大的支持来执行数据库操作,包括多表查询。多表查询是指从多个数据库表中检索数据的过程,这在实际的应用中非常常见。MyBatis 提供了多种方法来执行多表查询,以下是一些常见的技术和方法:

1、使用嵌套查询:

这是最基本的多表查询方法,通过在 SQL 语句中嵌套子查询来联合多个表的数据。例如,你可以在 SELECT 语句中使用子查询来从一个表中获取数据,然后再将其用于主查询中。这种方法在某些简单情况下是有效的,但对于复杂的多表查询可能会变得冗长和难以维护。

2、使用多个 SQL 语句

在 MyBatis 中,你可以编写多个独立的 SQL 语句,每个语句都从一个表中检索数据,然后在 Java 代码中将这些数据组合起来。这通常需要在 Java 代码中手动执行每个查询并进行数据处理,但对于一些复杂的多表查询情况可能更加灵活。

3、使用关联查询:

MyBatis 支持使用关联查询来执行多表查询,特别是在映射文件中配置了表之间的关联关系。通过在 Mapper XML 文件中配置 associationcollection 来表示表之间的关联关系,MyBatis 可以自动根据关系从多个表中检索数据并构造结果对象。

4、使用自定义映射查询

有时候,多表查询的结果可能不适合于一个实体类,这时你可以使用自定义映射查询来将结果映射到一个 Map 或者其他自定义的数据结构中,以适应查询的需要。

二、业务场景

模拟的业务场景为订单与用户的关系,可以是一对一、一对多。

比如,一个用户有多个订单,一个订单只有一个用户。

还有就是用户与角色的关系,多个用户拥有多个角色,一个角色可以被多个用户拥有,一个用户可以拥有多个角色。

三、示例

1、一对一查询

案例:查询所有订单信息,关联查询下单用户信息。 注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

数据库:

对应的SQL语句:

select o.id,o.ordername,o.ordercount,s.studentname,s.address from orders o,student s where o.student_id = s.id

用户表student

java 复制代码
public class Student {
    private int id;
    private String studentName;
    private String gender;
    private String address;
    private String email;
    private String remark;
   

    public Student() {
    }

    public Student( String studentName, String gender, String address, String email, String remark) {

        this.studentName = studentName;
        this.gender = gender;
        this.address = address;
        this.email = email;
        this.remark = remark;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }


    }
}

订单表order

java 复制代码
public class Order {
    private int id;
    private String ordername;
    private int ordercount;
    private Student student;
   

  

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getOrdername() {
        return ordername;
    }

    public void setOrdername(String ordername) {
        this.ordername = ordername;
    }

    public int getOrdercount() {
        return ordercount;
    }

    public void setOrdercount(int ordercount) {
        this.ordercount = ordercount;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

StudentMapper.xml

java 复制代码
<?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.xinhua.mapper.StudentMapper">
   

    <!--查询出每个用户的信息和对应的所有订单-->
    <resultMap id="studentOrder" type="Student">
        <id column="id" property="id"></id>
        <result column="studentName" property="studentName"></result>
        <result column="gender" property="gender"></result>
        <result column="address" property="address"></result>
        <collection property="listOrder" ofType="com.xinhua.domain.Order">
            <id column="order_id" property="id"></id>
            <result column="ordername" property="ordername"></result>
            <result column="ordercount" property="ordercount"></result>
        </collection>
    </resultMap>
    <select id="findStudentOrderAll" resultMap="studentOrder">
        SELECT s.id,s.studentname,s.gender,s.address,o.id order_id,o.ordername,o.ordercount FROM student s LEFT JOIN Orders o ON s.id=o.student_id
    </select>
</mapper>

mapper接口类

java 复制代码
public interface StudentMapper {
   
    public List<Student> findStudentOrderAll();
}

测试类:

java 复制代码
public class TestDemo {
    SqlSessionFactory ssf = null;
    @Before
    public void creatFactory(){
        InputStream input = null;
        try {
            input = Resources.getResourceAsStream("SqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ssf = new SqlSessionFactoryBuilder().build(input);
    }

@Test
    public void testMapper10() {
        SqlSession sqlSession = ssf.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.findStudentOrderAll();
        for (Student student : students){
            System.out.println(student.getId()+","+student.getStudentName()+","+student.getGender()+","+student.getAddress());
            List<Order> listOrder = student.getListOrder();
            for (Order order : listOrder){
                System.out.println("   "+order.getOrdername()+","+order.getOrdercount());
            }
        }
    }

2、一对多查询

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

主查询表:订单表

关联查询表:用户表、订单明细表、商品表

订单表

用户表

商品表

订单明细表

对应的SQL语句:

复制代码
 SELECT
  orders.id o_id,
  orders.ordername,
  student.studentname,
  student.gender,
  orderdetail.id od_id,
  orderdetail.items_count,
  orderdetail.items_all_price ,
  items.id it_id,
  items.items_name,
  items.items_price
FROM ORDERs,student,orderdetail,items


WHERE orders.student_id = student.id
  AND orders.id = orderdetail.orders_id
  AND orderdetail.items_id = items.id

用户表

相比之前一对一,变化在student类多了一个List<Order> orderList

java 复制代码
public class Student {
    private int id;
    private String studentName;
    private String gender;
    private String address;
    private String email;
    private String remark;
    private List<Order> listOrder;

    public Student() {
    }

    public Student( String studentName, String gender, String address, String email, String remark) {

        this.studentName = studentName;
        this.gender = gender;
        this.address = address;
        this.email = email;
        this.remark = remark;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public List<Order> getListOrder() {
        return listOrder;
    }

    public void setListOrder(List<Order> listOrder) {
        this.listOrder = listOrder;
    }
}

Order

java 复制代码
public class Order {
    private int id;
    private String ordername;
    private int ordercount;
    private Student student;
   
    private List<OrderDetail> orderDetailList;

    public List<OrderDetail> getOrderDetailList() {
        return orderDetailList;
    }

    public void setOrderDetailList(List<OrderDetail> orderDetailList) {
        this.orderDetailList = orderDetailList;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getOrdername() {
        return ordername;
    }

    public void setOrdername(String ordername) {
        this.ordername = ordername;
    }

    public int getOrdercount() {
        return ordercount;
    }

    public void setOrdercount(int ordercount) {
        this.ordercount = ordercount;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

商品表items

java 复制代码
    private int id;
    private String items_name;
    private int items_price;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getItems_name() {
        return items_name;
    }

    public void setItems_name(String items_name) {
        this.items_name = items_name;
    }

    public int getItems_price() {
        return items_price;
    }

    public void setItems_price(int items_price) {
        this.items_price = items_price;
    }
}

订单明细表

java 复制代码
public class OrderDetail {
    private int id;
    private int items_count;
    private int items_all_price;
    private Order order;
    private List<Items> listItems;

    public List<Items> getListItems() {
        return listItems;
    }

    public void setListItems(List<Items> listItems) {
        this.listItems = listItems;
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getItems_count() {
        return items_count;
    }

    public void setItems_count(int items_count) {
        this.items_count = items_count;
    }

    public int getItems_all_price() {
        return items_all_price;
    }

    public void setItems_all_price(int items_all_price) {
        this.items_all_price = items_all_price;
    }
}

OrderMapper.xml

java 复制代码
<?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.xinhua.mapper.OrderMapper">
<resultMap id="orderStudentDetailItems" type="com.xinhua.domain.Order">
        <id column="o_id" property="id"></id>
        <result column="ordername" property="ordername"></result>
        <association property="student" javaType="Student">
            <result column="studentName" property="studentName"></result>
            <result column="gender" property="gender"></result>
        </association>
        <!-- 一对多关联映射 -->
        <collection property="orderDetailList" ofType="com.xinhua.domain.OrderDetail">
            <id column="od_id" property="id"></id>
            <result column="items_count" property="items_count"></result>
            <result column="items_all_price" property="items_all_price"></result>
            <collection property="listItems" ofType="com.xinhua.domain.Items">
                <id column="it_id" property="id"></id>
                <result column="items_name" property="items_name"></result>
                <result column="items_price" property="items_price"></result>
            </collection>
        </collection>
    </resultMap>
    <select id="findOrderStudentDetailItems" resultMap="orderStudentDetailItems">
        SELECT
		  orders.id o_id,
		  orders.ordername,
		  student.studentname,
		  student.gender,
		  orderdetail.id od_id,
		  orderdetail.items_count,
		  orderdetail.items_all_price ,
		  items.id it_id,
		  items.items_name,
		  items.items_price
		FROM ORDERs,student,orderdetail,items


		WHERE orders.student_id = student.id
		  AND orders.id = orderdetail.orders_id
		  AND orderdetail.items_id = items.id

    </select>
</mapper>

mapper接口类

java 复制代码
public interface OrderMapper {
 
    public List<Order> findOrderStudentDetailItems();
}

测试类:

java 复制代码
public class TestDemo {
    SqlSessionFactory ssf = null;
    @Before
    public void creatFactory(){
        InputStream input = null;
        try {
            input = Resources.getResourceAsStream("SqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ssf = new SqlSessionFactoryBuilder().build(input);
    }

    @Test
    public void testMapper11() {
        SqlSession sqlSession = ssf.openSession();
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        List<Order> orderList = mapper.findOrderStudentDetailItems();
        for (Order order : orderList){
            System.out.println(order.getId()+","+order.getOrdername()+","+order.getOrdercount()+","+order.getStudent().getStudentName());
            List<OrderDetail> orderDetailList = order.getOrderDetailList();
            for (OrderDetail orderDetail : orderDetailList){
                System.out.println("   "+orderDetail.getId()+","+orderDetail.getItems_count()+","+orderDetail.getItems_all_price());
                List<Items> list = orderDetail.getListItems();
                for (Items listItems : list){
                    System.out.println("        "+listItems.getId()+","+listItems.getItems_name()+","+listItems.getItems_price());
                }
            }
        }
    }
相关推荐
ZhengEnCi4 分钟前
J1B-为什么99%的人配置Java环境失败?大厂开发者5分钟搞定的JDK安装与环境配置完全指南
java
零雲7 分钟前
java面试:有了解过kafka架构吗,可以详细讲一讲吗
java·面试·kafka
一行•坚书13 分钟前
kafka服务端与客户端如何协作?生产者发送消息分区策略是什么?消费者组分区策略?集群与ACK机制?
java·后端·kafka
点心快奔跑27 分钟前
超详细Windows系统MySQL 安装教程
数据库·windows·mysql
serve the people28 分钟前
Prompt Composition with LangChain’s PipelinePromptTemplate
java·langchain·prompt
天天摸鱼的java工程师29 分钟前
干掉系统卡顿!Excel异步导出完整实战方案(百万数据也不慌)
java·后端
心随雨下38 分钟前
Java中将System.out内容写入Tomcat日志
java·开发语言·tomcat
超级苦力怕1 小时前
【超详细】Redis下载教程 (Win/Linux)
数据库
codervibe1 小时前
MySQL 命令行连接与企业级远程访问实践(含故障排查与安全策略)
数据库·后端
workflower1 小时前
测试套件缩减方法
数据库·单元测试·需求分析·个人开发·极限编程