• MyBatis一对多关联查询


    MyBatis 中,通过 元素的子元素 处理一对多级联关系,collection 可以将关联查询的多条记录映射到一个 list 集合属性中。示例代码如下

    1. <collection property="orderList"
    2. ofType="net.cc.po.Order" column="id"
    3. select="net.cc.mapper.OrderMapper.selectOrderById" />

    元素中通常使用以下属性。

    • property:指定映射到实体类的对象属性。
    • column:指定表中对应的字段(即查询返回的列名)。
    • javaType:指定映射到实体对象属性的类型。
    • select:指定引入嵌套查询的子 SQL 语句,该属性用于关联映射中的嵌套查询。


    一对多关联查询可采用以下两种方式:

    • 分步查询,通过两次或多次查询,为一对多关系的实体 Bean 赋值
    • 单步查询,通过关联查询实现

    示例

    以用户和订单为例讲解一对多关联查询(实现“根据 id 查询用户及其关联的订单信息”的功能)的处理过程。

    1)创建数据表

    需要两张数据表,一张是用户表 user,一张是订单表 order,这两张表具有一对多的级联关系,创建过程省略。

    创建持久化类

    创建持久化类 User 和 Order,代码分别如下

    1. //User 类
    2. public class User {
    3. private int id;
    4. private String name;
    5. private String pwd;
    6. private List orderList;
    7. /*省略setter和getter方法*/
    8. @Override
    9. public String toString() {
    10. return "User [id=" + id + ", name=" + name + ", orderList=" + orderList + "]";
    11. }
    12. }
    13. //Order 类
    14. public class Order {
    15. private int id;
    16. private int ordernum;
    17. /*省略setter和getter方法*/
    18. @Override
    19. public String toString() {
    20. return "Order [id=" + id + ", ordernum=" + ordernum + "]";
    21. }
    22. }

    分步查询

    OrderMapper 类代码如下

    public List selectOrderById(int id);

    OrderMapper.xml 中相应的映射 SQL 语句

    1. <select id="selectOrderById" resultType="net.cc.po.Order"
    2. parameterType="Integer">
    3. SELECT * FROM `order` where userId=#{id}
    4. select>

    UserMapper 类

    public User selectUserOrderById1(int id);
    

     UserMapper.xml 中相应的映射 SQL 语句

    1. <resultMap type="net.cc.po.User" id="userAndOrder1">
    2. <id property="id" column="id" />
    3. <result property="name" column="name" />
    4. <result property="pwd" column="pwd" />
    5. <collection property="orderList"
    6. ofType="net.cc.po.Order" column="id"
    7. select="net.cc.mapper.OrderMapper.selectOrderById" />
    8. resultMap>
    9. <select id="selectUserOrderById1" parameterType="Integer"
    10. resultMap="userAndOrder1">
    11. select * from user where id=#{id}
    12. select>

    测试:

    1. public class Test {
    2. public static void main(String[] args) throws IOException {
    3. InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
    4. SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
    5. SqlSession ss = ssf.openSession();
    6. User us = ss.getMapper(UserMapper.class).selectUserOrderById1(1);
    7. System.out.println(us);
    8. }
    9. }

    运行结果:

    DEBUG [main] - ==>  Preparing: select * from user where id=?
    DEBUG [main] - ==> Parameters: 1(Integer)
    DEBUG [main] - ====>  Preparing: SELECT * FROM `order` where userId=?
    DEBUG [main] - ====> Parameters: 1(Integer)
    DEBUG [main] - <====      Total: 2
    DEBUG [main] - <==      Total: 1
    User [id=1, name=测试1, orderList=[Order [id=0, ordernum=20200107], Order [id=0, ordernum=20200645]]]

    单步查询

    该种方式实现一对多关联查询需要修改 Order 持久化类,因为 Order 中的 id 不能和 User 中的 id 重复

    1. public class Order {
    2. private int oId;
    3. private int ordernum;
    4. /*省略setter和getter方法*/
    5. @Override
    6. public String toString() {
    7. return "Order [id=" + oId+ ", ordernum=" + ordernum + "]";
    8. }
    9. }

    UserMapper.xml 中相关映射 SQL 语句如下

    1. <resultMap type="net.cc.po.User" id="userAndOrder2">
    2. <id property="id" column="id" />
    3. <result property="name" column="name" />
    4. <result property="pwd" column="pwd" />
    5. <collection property="orderList"
    6. ofType="net.cc.po.Order">
    7. <id property="oId" column="oId" />
    8. <result property="ordernum" column="ordernum" />
    9. collection>
    10. resultMap>
    11. <select id="selectUserOrderById2" parameterType="Integer"
    12. resultMap="userAndOrder2">
    13. SELECT u.*,o.id as oId,o.ordernum FROM `user` u,`order` o
    14. WHERE
    15. u.id=o.`userId` AND u.id=#{id}
    16. select>

    测试:

    1. public class Test {
    2. public static void main(String[] args) throws IOException {
    3. InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
    4. SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
    5. SqlSession ss = ssf.openSession();
    6. User us = ss.getMapper(UserMapper.class).selectUserOrderById2(1);
    7. System.out.println(us);
    8. }
    9. }

    DEBUG [main] - ==>  Preparing: SELECT u.*,o.id as oId,o.ordernum FROM `user` u,`order` o WHERE u.id=o.`userId` AND u.id=?
    DEBUG [main] - ==> Parameters: 1(Integer)
    DEBUG [main] - <==      Total: 2
    User [id=1, name=测试1, orderList=[Order [id=1, ordernum=20200107], Order [id=4, ordernum=20200645]]]

  • 相关阅读:
    6-7抽象的应用场景
    解决cardano 交易“1.344798 Not enough funds for ”问题
    LabVIEW挖坑指南
    SpringBoot接入GrayLog(分布式日志组件)
    LeetCode2109:向字符串添加空格
    【组成原理-处理器】数据通路
    第23天中视频伙伴计划通过!分享本人心得,希望能帮到路上的你
    小谈设计模式(22)—单例模式
    Spring中的循环依赖的解决办法
    GP与LP的区别,有限责任、无限责任、无限连带责任
  • 原文地址:https://blog.csdn.net/qq_43079001/article/details/133710425