1. 程式人生 > 實用技巧 >MyBatis一對多SQL查詢

MyBatis一對多SQL查詢

1、一對多的概念

例如:一個老師有多個學生!

對於老師而言,就是一對多關係

2、搭建環境

  1. 編寫實體類

    public class Teacher {
        private Integer id;
        private String name;
        // 一個老師擁有多個學生,一對多
        private List<Student> students;
        // 構造器
        // toString
        // getter and setter
    }
    
    public class Student {
        private Integer id;
        private String name;
        private Integer tid;
        // 構造器
        // toString
        // getter and setter
    }
    
  2. 編寫實體類對應的mapper介面

    public interface StudentMapper {
    }
    
    public interface TeacherMapper {
    }
    
  3. 編寫mapper介面對應的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="com.jh.mapper.TeacherMapper">
    
    </mapper>
    
  4. 測試環境是否成功

    public class TeacherMapperTest {
        @Test
        public void getTeacher() {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = teacherMapper.getTeacher(1);
            System.out.println(teacher);
            sqlSession.close();
        }
    }
    

3、按照結果巢狀處理

獲取指定老師下的所有學生及老師資訊

思路:

  • 從學生表和老師表中查出學生id,學生姓名,老師姓名
  • 對查詢出來的操作做結果集對映
    1. 集合使用collection標籤
    2. JavaType和ofType都是用來指定物件型別的
    3. JavaType是用來指定pojo中屬性的型別
    4. ofType指定的是對映到list集合屬性中pojo的型別

具體實現:

  1. 編寫mapper介面方法

    public interface TeacherMapper {
        Teacher getTeacher(@Param("tid") int id);
    }
    
  2. 編寫xml

    <select id="getTeacher" resultMap="TeacherStudent">
        select t.id tid, t.name tname, s.id sid, s.name sname
        from mybatis.teacher t,
             mybatis.student s
        where s.tid = t.id
          and t.id = #{tid}
    </select>
    
    <resultMap id="TeacherStudent" type="com.jh.domain.Teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="com.jh.domain.Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
    
  3. 測試

    @Test
    public void getTeacher() {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = teacherMapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }
    
  4. 測試結果

    Teacher{id=1, name='廖老師', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小紅', tid=1}, Student{id=3, name='小張', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
    

4、按照查詢巢狀處理

使用子查詢方式查詢

  1. 編寫mapper介面方法

    public interface TeacherMapper {
        Teacher getTeacher(@Param("tid") int id);
    }
    
  2. 編寫xml

    <select id="getTeacher" resultMap="TeacherStudent">
        select * from mybatis.teacher where id = #{tid};
    </select>
    
    <resultMap id="TeacherStudent" type="com.jh.domain.Teacher">
        <!--column是一對多的外來鍵 , 寫的是一的主鍵的列名-->
        <collection property="students" javaType="ArrayList" ofType="com.jh.domain.Student" select="getStudent" column="id"/>
    </resultMap>
    
    <select id="getStudent" resultType="com.jh.domain.Student">
        select * from mybatis.student where tid = #{tid}
    </select>
    
  3. 測試結果

    Teacher{id=null, name='廖老師', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小紅', tid=1}, Student{id=3, name='小張', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
    

小結

  1. 關聯-association【多對一】
  2. 集合-collection【一對多 】
  3. association是用於一對一和多對一,而collection是用於一對多的關係
  4. JavaType和ofType都是用來指定物件型別的
    1. JavaType是用來指定pojo中屬性的型別
    2. ofType指定的是對映到list集合屬性中pojo的型別,泛型中的約束型別!

注意點

  1. 保證SQL的可讀性,儘量通俗易懂
  2. 根據實際要求,儘量編寫效能更高的SQL語句
  3. 注意屬性名和欄位不一致的問題
  4. 注意一對多和多對一 中:欄位和屬性對應的問題
  5. 建議使用Log4j,通過日誌來檢視自己的錯誤