MyBatis一对多查询

在《MyBatis》框架中如何进行处理一对多查询操作。

  例如:一个用户可以有多个订单,一个订单只属于一个用户。

 

在操作过程中有两种方法:级联查询和分步查询(这里用的是分步查询)

  分布查询是通过两次或者多次查询出结果。

 

在操作过程中需要用到<resultMap>元素的子元素<association>处理一对多查询

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

实例:

   1 <association property=”user” 2 select=”com.it.mappers.UserMapper.findOrdersAndUserTwo” 3 column=”user_id”/> 

 

示例:

 

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

1、创建数据库:

  两张表:User(用户)、Orders(订单)

  SQL语句:

CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` int(25) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `userId` (`user_id`),
  CONSTRAINT `order_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
insert  into `order`(`id`,`ordernum`,`user_id`) values (1,1000011,1),(2,1000012,2),(3,1000011,3),(4,1000012,1);
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
 `address` varchar(20),
PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; insert into `user`(`id`,`name`) values (1,'张三'),(2,'李四'),(3,'王五'),(4,'赵六');

2、创建持久化类

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

package com.it.pojo;

import java.util.List;

public class User {
    private Integer id;
    private String username;
    private String address;
    private List<Orders> ordersList;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", ordersList=" + ordersList +
                '}';
    }

//省略getter、setter
    
}

 

package com.it.pojo;


public class Orders {
    private Integer id;
    private String number;
    private Integer user_id;

    @Override
    public String toString() {
        return "Orders{" +
                "id=" + id +
                ", number='" + number + '\'' +
                ", user_id=" + user_id +
                ", user=" + user +
                '}';
    }

//省略getter和setter

}

 

分步查询

UserMapper接口代码如下:

import com.it.pojo.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {
    //一对多分布查询One
    List<User> findUserAndOrdersStepOne(@Param("id")Integer id);
}

 

UserMapper.xml中相映射sql语句如下:

 <!--一对多分布查询第一步-->
    <select id="findUserAndOrdersStepOne" resultMap="userAndOrdersResultMap">
        select * from tb_user where id = #{id}
    </select>
    <resultMap id="userAndOrdersResultMap" type="User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="address" property="address"/>
        <association property="ordersList"
                     select="com.it.mappers.OrderMapper.findUserAndOrdersTwo"
                     column="id"/>
    </resultMap>

 

OrdersMapper接口代码如下:

import com.it.pojo.Orders;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface OrderMapper {
//    <!--一对多分布查询第二步-->
    List<Orders> findUserAndOrdersTwo(@Param("uid")Integer user_id);
}

 

UOrdersMapper.xml中相映射sql语句如下:

 <!--一对多分布查询第二步-->
    <select id="findUserAndOrdersTwo" resultType="Orders">
        select * from tb_orders where user_id = #{uid}
    </select>

 

测试代码如下:

@org.junit.Test
    public void test(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = mapper.findUserAndOrdersStepOne(1);
        System.out.println(list);
        sqlSession.close();
    }

 

运行结果如下:

DEBUG 04-10 18:27:00,165 ==>  Preparing: select * from tb_user where id = ?(BaseJdbcLogger.java :137) 
DEBUG 04-10 18:27:00,191 ==> Parameters: 1(Integer)(BaseJdbcLogger.java :137) 
DEBUG 04-10 18:27:00,208 ====>  Preparing: select * from tb_orders where user_id = ?(BaseJdbcLogger.java :137) 
DEBUG 04-10 18:27:00,209 ====> Parameters: 1(Integer)(BaseJdbcLogger.java :137) 
DEBUG 04-10 18:27:00,210 <====      Total: 2(BaseJdbcLogger.java :137) 
DEBUG 04-10 18:27:00,212 <==      Total: 1(BaseJdbcLogger.java :137) 
[User{id=1, username='小明', address='北京', ordersList=[Orders{id=1, number='1000011', user_id=1, user=null}, Orders{id=2, number='1000012', user_id=1, user=null}]}]


Process finished with exit code 0

 

 

以下是我私下画的一个草图:

 

 

Tags: