zoukankan      html  css  js  c++  java
  • Java -- MyBatis学习笔记13、联合查询(二)

    1、多对一关联

    就是某一张表的多条数据、对应另一张表的一条数据,比如多个学生对应一个班级。

    1.1、提出需求

    以学生表和班级表为例、查询学生信息,并查询对应的班级,关系为多对一。

    • 表字段以及对应关系

    1.2、创建实体类

    学生表存放班级id,在实体类中取而代之的就是班级实体类类型,一个班级下有多名学生,所以、在班级实体类中必须有一个集合类型属性,集合里边类型为学生类型、将查询到的学生学生映射到该集合当中。

    • 学生实体类
    public class Student {
        private int id;
        private String stu_name;
        private int stu_age;
        private String address;
        private Classes classes;
        //getter and setter...
    }
    
    • 班级实体类
    public class Classes {
        private int id;
        private String class_name;
        //一个班级对应多名学生,使用集合、存放学生信息
        private List<Student> students;
        //getter and setter...
    }
    
    • 定义Dao层接口
    public interface StudentDao {
        List<Student> selectStudents();
    }
    
    • mapper映射文件
    <mapper namespace="com.rg.dao.StudentDao">
        <!--
            方式一:直接联合查询、然后给实体类中每个属性赋值
        -->
        <select id="selectStudents" resultMap="student_class_map">
            select s.*, sc.id, sc.class_name
            from student s
                     inner join student_class sc on s.s_id = sc.id
        </select>
        <resultMap id="student_class_map" type="com.rg.bean.Student">
            <id property="id" column="id"/>
            <result property="stu_name" column="stu_name"/>
            <result property="stu_age" column="stu_age"/>
            <result property="address" column="address"/>
            <!--
                通过association标签、将关联查询到的班级信息,存放到classes属性当中
            -->
            <association property="classes" column="s_id" javaType="com.rg.bean.Classes">
                <id property="id" column="id"/>
                <result property="class_name" column="class_name"/>
            </association>
        </resultMap>
    
        <!--
            方式二:通过执行另外一个SQL映射语句来返回预期的复杂类型
        -->
        <select id="selectStudents" resultMap="student_map">
            select id, stu_name, stu_age, address, s_id
            from student
        </select>
        <resultMap id="student_map" type="com.rg.bean.Student">
            <id property="id" column="id"/>
            <result property="stu_name" column="stu_name"/>
            <result property="stu_age" column="stu_age"/>
            <result property="address" column="address"/>
            <!--关联另一条sql语句,将s_id传入、将查询到的结果映射到classes属性当中-->
            <association property="classes" select="selectClasses" column="s_id"/>
        </resultMap>
        <!--根据学生表的班级id,查询对应的班级-->
        <select id="selectClasses" resultType="com.rg.bean.Classes">
            select id,class_name from student_class where id = #{id}
        </select>
    </mapper>
    
    • 测试
    @Test
    public void test02() {
        List<Student> students = studentDao.selectStudents();
        for (Student student : students) {
            System.out.println(student);
        }
    }
    
    • 查询结果
    Student{id=14, stu_name='小王', stu_age=15, address='河南', classes=Classes{id=1, class_name='软件2021班', students=null}}
    Student{id=15, stu_name='小李', stu_age=13, address='河南', classes=Classes{id=2, class_name='软件2022班', students=null}}
    Student{id=16, stu_name='小赵', stu_age=14, address='上海', classes=Classes{id=1, class_name='软件2021班', students=null}}
    

    其实多对一就相当于多个一对一,每次查询到一条学生信息,就根据学生信息中的班级id关联到班级表、查询到对应的班级信息。

    2、一对多关联

    在mybatis中进行一对多关联要使用到一个集合标签,因为每次查询到一条数据,就要关联到另一张表中的多条数据,也就是说、查询到一条班级信息,就要拿着这条数据的id,到学生表中查对应的学生信息,将查到的这些学生对象,逐条添加集合当中。

    2.1、提出需求

    根据班级id,查询班级信息并查到学生表中对应的所有学生信息。

    • mapper映射文件
    <mapper namespace="com.rg.dao.StudentDao">
        <!--
            方式一:直接两表联合查询、将结果通过resultMap映射到实体类
        -->
        <select id="selectClasses" resultMap="classes_student_map">
            select c.*, s.stu_name
            from student_class c
                     inner join student s on c.id = s.s_id
            where c.id = #{id}
        </select>
        <resultMap id="classes_student_map" type="com.rg.bean.Classes">
            <id property="id" column="id"/>
            <result property="class_name" column="class_name"/>
            <!--
                   students为集合类型、所以通过collection标签进行遍历映射
                   collection标签是集合标签,它与association关联标签几乎是一样的
            -->
            <collection property="students" ofType="com.rg.bean.Student">
                <result property="stu_name" column="stu_name"/>
            </collection>
            <!--
                在MyBatis框架中,JavaType和ofType都是用来指定对象类型的。
                JavaType和ofType的区别在于:JavaType用来指定POJO中属性的类型。
                ofType指定的是映射到List集合中POJO的类型。
            -->
        </resultMap>
    
        <!--
            方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
        -->
        <select id="selectClasses" resultMap="classes_student_map">
            select id,class_name from student_class where id = #{id}
        </select>
        <resultMap id="classes_student_map" type="com.rg.bean.Classes">
            <id property="id" column="id"/>
            <result property="class_name" column="class_name"/>
            <!--
                通过select属性、指定要执行的sql语句
            -->
            <collection property="students" column="id" select="selectStudents" ofType="com.rg.bean.Student"/>
        </resultMap>
        <select id="selectStudents" resultType="com.rg.bean.Student">
            select stu_name from student where s_id = #{id}
        </select>
    
        <!--
            方式三:直接两表联合查询、将结果通过resultMap映射到实体类,使用resultMap嵌套
        -->
        <select id="selectClasses" resultMap="classes_student_map">
            select c.*, s.stu_name,s.id as sid
            from student_class c
                     inner join student s on c.id = s.s_id
            where c.id = #{id}
        </select>
        <resultMap id="classes_student_map" type="com.rg.bean.Classes">
            <id property="id" column="id"/>
            <result property="class_name" column="class_name"/>
            <!--
                再通过resultMap属性、在外边定义resultMap标签、进行映射赋值
            -->
            <collection property="students" resultMap="classes_map"/>
        </resultMap>
        <!--
            这里一定要注意,如果两张表的字段重名的话一定要定义别名。
            如student_classes表的主键是id,student表中的主键也是id,那么
            在当前resultMap中给id赋值,有可能会将班级的id值赋给了学生的id
            所以在两表联合查询时候要根据需要定义别名,如下:
            将student表的id定义别名为sid,将sid和Student实体类中的id赋值
            如果不这样,赋的值就有可能是student_class表的id值
        -->
        <resultMap id="classes_map" type="com.rg.bean.Student">
            <!--这个sid是student表的id值-->
            <id property="id" column="sid"/>
            <result property="stu_name" column="stu_name"/>
        </resultMap>
    </mapper>
    
    • 结果
    软件2021班
    该班级有如下学生:
    Student{id=14, stu_name='小王', stu_age=0, address='null', classes=null}
    Student{id=16, stu_name='小赵', stu_age=0, address='null', classes=null}
    
  • 相关阅读:
    如何解决flash跑到层上面的问题?How to resolve the div layer appear over the top of flash?
    WSDL
    Java 实现解压缩文件
    Eclipse 插件TFS 注册码
    JNLP
    SOAP
    检测客户端是否安装了JWS Java Web Start
    Java打包JRE于exe中方法
    Java解压文件代码(相当于你在目录中选中压缩文件 右键解压)
    Java代码实现利用google实现多语言翻译案例
  • 原文地址:https://www.cnblogs.com/dcy521/p/15092387.html
Copyright © 2011-2022 走看看