MyBatis-----4.实现关联表查询

前面几节都是单表查询,但是实际中一定会用到多表关联查询,本节将介绍关联表查询的实现

1.一对一关联

1.1创建数据表和添加数据

CREATE TABLE teacher(
    t_id INT PRIMARY KEY AUTO_INCREMENT, 
    t_name VARCHAR(20)
);
CREATE TABLE class(
    c_id INT PRIMARY KEY AUTO_INCREMENT, 
    c_name VARCHAR(20), 
    teacher_id INT
);
ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);    

INSERT INTO teacher(t_name) VALUES('teacher1');
INSERT INTO teacher(t_name) VALUES('teacher2');

INSERT INTO class(c_name, teacher_id) VALUES('class_a', 1);
INSERT INTO class(c_name, teacher_id) VALUES('class_b', 2);

创建教师表和班级表,一个班级对应一个教师,这是一对一关联

1.2定义实体类

public class Teacher {
    private int id;          
    private String name;    
    //get,set方法        
}
public class Classes {
    private int id;            
    private String name;
   private Teacher teacher; //teacher对象
//get,set方法 }

1.3 定义 sql 映射文件 ClassMapper.xml

 方式一:直接联表查询
  嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集封装联表查询的数据(去除重复的数据) select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
  <select id="getClass" parameterType="int" resultMap="Class">
      select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
  </select>
  <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
  <resultMap type="com.zhiyou.zyl.bean.Classes" id="Class">
       <id property="id" column="c_id"/>
       <result property="name" column="c_name"/>
       <association property="teacher" javaType="com.zhiyou.zyl.bean.Teacher">
           <id property="id" column="t_id"/>
           <result property="name" column="t_name"/>
       </association>
   </resultMap>

  <association>用来连接表,其属性如下:  

  • property:对象属性的名称
  • javaType:对象属性的类型
  • column:所对应的外键字段名称
  • select:使用另一个查询封装的结果
方式二:多次查询:将查询的结果作为另一个查询的条件
   SELECT * FROM class WHERE c_id=1;  //teacher_id=1
   SELECT * FROM teacher WHERE t_id=1;//使用上面得到的teacher_id
   <select id="getClass2" parameterType="int" resultMap="Class2">
       select * from class where c_id=#{id}
    </select>
      <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
    <resultMap type="com.zhiyou.zyl.bean.Classes" id="Class2">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" select="getTeacher"/>
    </resultMap>
    
    <select id="getTeacher" parameterType="int" resultType="com.zhiyou.zyl.bean.Teacher">
         SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
    </select>

1.4在conf.xml文件中注册classMapper.xml

<mappers>
        <!-- 注册classMapper.xml文件-->
        <mapper resource="com/zhiyou/zyl/mapper/classMapper.xml"/>
</mappers>

1.5定义class操作接口

package com.zhiyou.zyl.dao;
import com.zhiyou.zyl.bean.Classes;

public interface ClassesDao {
    /**
     * 查询
     * @return
     */
    public Classes getClass(int id);    
}

1.6测试

class ClassesTest {
    static SqlSession session =null;
    static ClassesDao cd;    
    @BeforeAll
    static void setUpBeforeClass() throws Exception {
        String resource = "conf.xml";
        //加载 mybatis 的配置文件(它也加载关联的映射文件)
        Reader reader = Resources.getResourceAsReader(resource);
        //构建 sqlSession 的工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //创建能执行映射文件中 sql 的 sqlSession
        session = sessionFactory.openSession();
        
        cd=session.getMapper(ClassesDao.class);
    }
    @AfterAll
    static void tearDownAfterClass() throws Exception {
        //提交
        session.commit();
    }
    @Test
    void testSelectById() {
        Classes classes=cd.getClass(1);
        System.out.println(classes.getStudent());
        System.out.println(classes);
    }

}

2.一对多关联

2.1创建数据表和插入数据

CREATE TABLE student(
    s_id INT PRIMARY KEY AUTO_INCREMENT, 
    s_name VARCHAR(20), 
    class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('student_A', 1);
INSERT INTO student(s_name, class_id) VALUES('student_B', 1);
INSERT INTO student(s_name, class_id) VALUES('student_C', 1);
INSERT INTO student(s_name, class_id) VALUES('student_D', 2);
INSERT INTO student(s_name, class_id) VALUES('student_E', 2);
INSERT INTO student(s_name, class_id) VALUES('student_F', 2);

这里一个班级具有多个学生,这就是一对多关联

2.2定义实体类

  创建student实体类

public class Student {
    private int sid;
    private String sname;
        //set,get方法
}

  在Classes实体类中添加List<Student>  student 属性

  

 2.3 修改sql映射文件classMapper.xml

方式一: 嵌套结果: 使用嵌套结果映射来处理重复的联合结果的子集
SELECT * FROM class c, teacher t,student s WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND c.c_id=1
   <select id="getClass" parameterType="int" resultMap="Class">
         select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
    </select>
    <resultMap type="com.zhiyou.zyl.bean.Classes" id="Class">
         <id property="id" column="c_id"/>
         <result property="name" column="c_name"/>
         <association property="teacher" column="teacher_id" javaType="com.zhiyou.zyl.bean.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
         </association>
         <!-- ofType指定students集合中的对象类型 -->
        <collection property="students" ofType="com.zhiyou.zyl.bean.Student">
             <id property="id" column="s_id"/>
             <result property="name" column="s_name"/>
        </collection>    
 </resultMap>

  使用collection标签实现对集合属性的映射

方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型

    SELECT * FROM class WHERE c_id=1;
    SELECT * FROM teacher WHERE t_id=1   //1 是上一个查询得到的teacher_id的值
    SELECT * FROM student WHERE class_id=1  //1是第一个查询得到的c_id字段的值
 <select id="getClass2" parameterType="int" resultMap="Class2">
        select * from class where c_id=#{id}
      </select>
      <resultMap type="com.zhiyou.zyl.bean.Classes" id="Class2">
        <id property="id" column="c_id"/>
         <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" javaType="com.zhiyou.zyl.bean.Teacher" select="getTeacher2"></association>
         <collection property="students" ofType="com.zhiyou.zyl.bean.Student" column="c_id" select="getStudent"></collection>
      </resultMap>
      
      <select id="getTeacher2" parameterType="int" resultType="com.zhiyou.zyl.bean.Teacher">
         SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
      </select>
      
      <select id="getStudent" parameterType="int" resultType="com.zhiyou.zyl.bean.Student">
        SELECT s_id id, s_name name FROM student WHERE class_id=#{id}
      </select>

2.4测试结果

Classes [cid=1, cname=bj_a, tid=1, teacher=Teacher [tid=1, tname=LS1], 
student=[Student [sid=1, sname=xs_A], Student [sid=2, sname=xs_B], Student [sid=3, sname=xs_C]]]


猜你喜欢

转载自www.cnblogs.com/zyl187110/p/11442683.html