java,mybatis 一对多级联查询,怎么给多的一方添加条件啊???

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java,mybatis 一对多级联查询,怎么给多的一方添加条件啊???相关的知识,希望对你有一定的参考价值。

比如 Teacher和 Student, 查询teacher 级联查询出学生,但是又不是查询所有的学生,
比如 查询 teacher: name= 张三 , student: age>18 , 这个怎么做到啊 ,是级联查询

把你的条件添加到select语句后面,然后传下去,例如:

<!-- 旅行社详情 -->
<resultMap type="com.demo.teacher"   id="teacherMap">
    <id property="teacherId" column="teacher_id"/>
    <result property="teacherName" column="teacher_name"/>
    <!--注意下面这个声明,只有column-->
    <result column="age"/>
    <collection property="student" column="teacherId=teacher_id,age=age" ofType="java.util.Map"  select="studentMap">
        <id property="studentId" column="student_id" />
        <result property="studentName" column="student_name"/>
        <result property="studentAge" column="student_age"/>
    </collection>
</resultMap>

<!--主-->
<select id="getTeacher" parameterType="java.util.Map" resultMap="teacherMap">
    select 
        teacher_id,
        teacher_name,
        #age as age <!--把你的参数这样写-->
    from 
        teachers
    where
        teacher_name = '大西瓜'
</select>

<!--从-->
<select id="studentMap" parameterType="java.util.Map" resultType="java.util.Map">
    select 
        student_id,
        student_name,
        student_age
    from 
        students
    where
        teacher_id = #teacherId
    and
        age > #age <!--这两个参数是resultMap中column指定的key-->
</select>
<!--mybatis的一对多级联查询多方的参数只能是一方的column,所以你要想办法把你的参数做成column-->

参考技术A <resultMap type="com.xx.xx.Teacher" id="ResultMap">
    <id column="teacherId" property="teacher_id" jdbcType="BIGINT" />
    <result column="teacherName" property="teacher_name" jdbcType="VARCHAR" />
    <association property="studentList" column="teacher_id"
   select="com.xxxx.selectStudentByTeacherId"></association>
</resultMap>

<resultMap type="com.xx.xx.Student" id="StudentResultMap">
    <id column="teacherId" property="teacher_id" jdbcType="BIGINT" />
    <result column="teacherName" property="teacher_name" jdbcType="VARCHAR" />
    <association property="studentList" column="teacher_id"
   select="com.xxxx.selectStudentByTeacherId"></association>
</resultMap>

<select id="selectTeacherList" parameterMap="java.util.Map" resultMap="ResultMap">
 select * from teacher where teacher_name like  CONCAT(CONCAT('%',
#teacherName),'%')
</select>

<select id="selectTeacherList" parameterType="java.lang.Long" resultMap="StudentResultMap">
 select * from student where teacher_id = #teacherId
</select>

public class Teacher
    private Long teacherId;
    private String teacherName;
    private List<Student> studentList;
    //get and set method


public class Student
    private Long studentId;
    private String studentName;
    //get and set method

这样 会查出来 这样的结果JSON

[
"teacherId":"1",
"teacherName":"张三",
"studentList":[
               "studentName":"a学生",
               "studentName":"b学生"
               ]
 ,
"teacherId":"2",
"teacherName":"张四",
"studentList":[
               "studentName":"c学生",
               "studentName":"d学生"
               ]
 ]
 
 一般这样集联查询的多

追问

谢谢啊,你的这个写法,还是没有过滤掉部分的学生啊 , 假如 Teacher 张三 关联30个学生, select * from student where teacher_id = #teacherId 这个不就查询出30个学生了吗,但是我只想要 查询出 age>18的学生 , 我不知道 怎么把这个 age带到sql去,

MyBatis-记录


文章目录Java Java

MyBatis一对多关联查询

  1. 在 MyBatis 中,通过 <resultMap>元素的子元素 <collection> 处理一对多级联关系,collection 可以将关联查询的多条记录映射到一个list集合属性中。

    <collection property="orderList"
            ofType="net.biancheng.po.Order" column="id"
            select="net.biancheng.mapper.OrderMapper.selectOrderById" />
    
  2. <collection>元素中通常使用以下属性:

    1. property:指定映射到实体类的对象属性。
    2. column:指定表中对应的字段(即查询返回的列名)。
    3. javaType:指定映射到实体对象属性的类型。
    4. select:指定引入嵌套查询的子 SQL 语句,该属性用于关联映射中的嵌套查询。
  3. 一对对关联查询可采用以下两种方式:

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

MyBatis一对多关联查询样例

  1. 创建持久化类 User 和 Order

    package net.biancheng.po;
    import java.util.List;
    public class User {
        private int id;
        private String name;
        private String pwd;
        private List<Order> orderList;
        /*省略setter和getter方法*/
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", orderList=" + orderList + "]";
        }
    }
    
  2. Order 类代码

    package net.biancheng.po;
    public class Order {
        private int id;
        private int ordernum;
        /*省略setter和getter方法*/
        @Override
        public String toString() {
            return "Order [id=" + id + ", ordernum=" + ordernum + "]";
        }
    }
    

分步查询

  1. OrderMapper 类代码

    public List<Order> selectOrderById(int id);
    
  2. OrderMapper.xml 中相应的映射 SQL 语句

    <!-- 根据id查询订单信息 -->
    <select id="selectOrderById" resultType="net.biancheng.po.Order"
        parameterType="Integer">
        SELECT * FROM `order` where userId=#{id}
    </select>
    
  3. UserMapper 类代码

    public User selectUserOrderById1(int id);
    
  4. UserMapper.xml 中相应的映射 SQL 语句

<!-- 一对多 根据id查询用户及其关联的订单信息:级联查询的第一种方法(分步查询) -->
<resultMap type="net.biancheng.po.User" id="userAndOrder1">
    <id property="id" column="id" />
    <result property="name" column="name" />
    <result property="pwd" column="pwd" />
    <!-- 一对多级联查询,ofType表示集合中的元素类型,将id传递给selectOrderById -->
    <collection property="orderList"
        ofType="net.biancheng.po.Order" column="id"
        select="net.biancheng.mapper.OrderMapper.selectOrderById" />
</resultMap>
<select id="selectUserOrderById1" parameterType="Integer"
    resultMap="userAndOrder1">
    select * from user where id=#{id}
</select>

测试类:

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

单步查询

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

    package net.biancheng.po;
    public class Order {
        private int oId;
        private int ordernum;
        /*省略setter和getter方法*/
        @Override
        public String toString() {
            return "Order [id=" + oId+ ", ordernum=" + ordernum + "]";
        }
    }
    
  2. UserMapper 类

    public User selectUserOrderById2(int id);
    
  3. UserMapper.xml 中相关映射 SQL

    <!-- 一对多 根据id查询用户及其关联的订单信息:级联查询的第二种方法(单步查询) -->
    <resultMap type="net.biancheng.po.User" id="userAndOrder2">
        <id property="id" column="id" />
        <result property="name" column="name" />
        <result property="pwd" column="pwd" />
        <!-- 一对多级联查询,ofType表示集合中的元素类型 -->
        <collection property="orderList"
            ofType="net.biancheng.po.Order">
            <id property="oId" column="oId" />
            <result property="ordernum" column="ordernum" />
        </collection>
    </resultMap>
    <select id="selectUserOrderById2" parameterType="Integer"
        resultMap="userAndOrder2">
        SELECT u.*,o.id as oId,o.ordernum FROM `user` u,`order` o
        WHERE
        u.id=o.`userId` AND u.id=#{id}
    </select>
    
  4. 测试类

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

MyBatis 多对多关联查询

  1. 实际应用中,由于多对多的关系比较复杂,会增加理解和关联的复杂度,所以应用较少
  2. MyBatis 没有实现多对多级联,推荐通过两个一对多级联替换多对多级联,以降低关系的复杂度,简化程序。
  3. 创建持久化类
    1. Order 类代码
      package net.biancheng.po;
      import java.util.List;
      public class Order {
          private int oid;
          private int ordernum;
          private List<Product> products;
          /*省略setter和getter方法*/
          @Override
          public String toString() {
              return "Order [id=" + oid + ", ordernum=" + ordernum + ", products=" + products + "]";
          }
      }
      
    2. Product 类
      package net.biancheng.po;
      import java.util.List;
      public class Product {
          private int pid;
          private String name;
          private Double price;
          // 多对多中的一个一对多
          private List<Order> orders;
          /*省略setter和getter方法*/
          @Override
          public String toString() {
              return "Product [id=" + pid + ", name=" + name + ", price=" + price + "]";
          }
      }
      
  4. 创建接口和映射文件
    1. OrderMapper 接口代码

      package net.biancheng.mapper;
      import java.util.List;
      import net.biancheng.po.Order;
      public interface OrderMapper {
          public List<Order> selectAllOrdersAndProducts();
      }
      
    2. OrderMapper.xml

      <?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="net.biancheng.mapper.OrderMapper">
          <resultMap type="net.biancheng.po.Order" id="orderMap">
              <id property="oid" column="oid" />
              <result property="ordernum" column="ordernum" />
              <collection property="products"
                  ofType="net.biancheng.po.Product">
                  <id property="pid" column="pid" />
                  <result property="name" column="name" />
                  <result property="price" column="price" />
              </collection>
          </resultMap>
          <select id="selectAllOrdersAndProducts" parameterType="Integer"
              resultMap="orderMap">
              SELECT o.oid,o.`ordernum`,p.`pid`,p.`name`,p.`price` FROM
              `order` o
              INNER JOIN orders_detail od ON o.oid=od.`orderId`
              INNER JOIN
              product p
              ON p.pid = od.`productId`
          </select>
      </mapper>
      
  5. 测试类代码
package net.biancheng.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 net.biancheng.mapper.OrderMapper;
import net.biancheng.po.Order;
public class Test {
    public static void main(String[] args) throws IOException {
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        SqlSession ss = ssf.openSession();
        List<Order> orderList = ss.getMapper(OrderMapper.class).selectAllOrdersAndProducts();
        for (Order or : orderList) {
            System.out.println(or);
        }
    }
}

以上是关于java,mybatis 一对多级联查询,怎么给多的一方添加条件啊???的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis一对多级联查询

MyBatis一对一级联查询

MyBatis-记录

MyBatis多对多级联查询

mybatis多对多级联查询

mybatis怎么一对多查询语句