Mybatis之关联查询

Mybatis–关联查询

当查询内容涉及到具有关联关系的多个表时,就需要使用关联联查。根据表与表间的关联关系的不同,关联查询分为四种:

  • 一对一关联查询
  • 一对多关联查询
  • 多对一关联查询
  • 多对多关联查询
一、一对一关联查询

一对多关联查询是指,在查询一对象的时候,同时将其所关联的一个对象也都查询出来。

例:一张身份证卡只对应一个人

        一个人只对应一张身份证

1.定义实体

Card:

public class Card {
    private int cardId;
    private String cardCode;
    private int perId;

    //一对一关系定义模型对象
    private Person person;
}

Person:

public class Person {
    private int perId;
    private String perName;

    private Card card;
}

2.定义数据库:

card表

person表

3.定义dao接口

public interface OneToOneDao {
    //根据人员编号获取人员信息以及卡号信息
    Card queryCardByPerId(int perId);
    Person queryPerByCardId(int cardId);
}

4.测试类:

public class TestDao {
    SqlSessionFactory sqlSessionFactory = BuilderSessionFactory.getSqlSessionFactory();
    SqlSession sqlSession = sqlSessionFactory.openSession(true);



    @Test
    public void cardAndPerson() { 
        OneToOneDao oneToOneDao = sqlSession.getMapper(OneToOneDao.class);
        System.out.println(oneToOneDao.queryCardByPerId(1000));
    }
}

5.写映射文件

<mapper namespace="com.mybatisTest.dao.OneToOneDao">
    <select id="queryCardByPerId" parameterType="int" resultMap="cardandperson">
        select * from card c
        join person p
        on c.perid = p.perid
        where c.perid = #{perid}
    </select>

    <select id="queryPerByCardId" parameterType="int" resultMap="personandcard">
        select * from  person p
        join card c
        on c.perid = p.perid
        where p.perid = #{perid}
    </select>


    <resultMap id="cardandperson" type="Card">
        <id column="cardid" property="cardId"></id>
        <result column="cardcode" property="cardCode"></result>
        <result column="perid" property="perId"></result>
        <!--one-to-one映射对象模型-->
        <association property="person" javaType="Person">
            <id column="perid" property="perId"></id>
            <result column="pername" property="perName"></result>
        </association>
    </resultMap>

    <resultMap id="personandcard" type="Person">
        <id column="perid" property="perId"></id>
        <result column="pername" property="perName"></result>

        <!--one-to-one映射对象模型-->
        <association property="card" javaType="Card">
            <id column="cardid" property="cardId"></id>
            <result column="cardcode" property="cardCode"></result>
            <result column="perid" property="perId"></result>
        </association>
    </resultMap>


</mapper>

注意,此时即使字段名与属性名相同,在中也要写出他们的映射关系。因为框架是依据封装对象的。

在映射文件中使用标签体现出两个实体对象间的关联关系。其两个属性的意义为:

  • property:关联的属性名,就是将用户对象关联到Order的那个属性
  • javaType: 属性的类型

二、一对多关联查询

一对多关联查询是指,在查询一对象的时候,同时将其所关联的多放对象也都查询出来。

例:班级和间的一对多关系

若定义的是双向关联,即双方的属性中均有对方的对象作为作用域属性出现

Classes:

public class Classes {
    private int classId;

    private String classCode;

    List<Student> students;
}

Student:

public class Student {
    private int stuId;

    private String stuName;

    private String stuSex;

    private String stuAge;

    private int classId;

    private Classes classes;
}

2.定义数据库:

calsses表:

student表:

3.定义dao接口

public interface OneToManyDao {
    Classes queryClassByStudent(int stuId);
    List<Student> queryStudentByClass(int classId);
}

4.测试类:

 @Test
    public void classandstu(){
        OneToManyDao oneToManyDao = sqlSession.getMapper(OneToManyDao.class);

        System.out.println(oneToManyDao.queryClassByStudent(1000));
    }

    @Test
    public void sutandClasses(){
        OneToManyDao oneToManyDao = sqlSession.getMapper(OneToManyDao.class);

        System.out.println(oneToManyDao.queryStudentByClass(1000));
    }

5.写映射文件

<mapper namespace="com.mybatisTest.dao.OneToManyDao">

    <select id="queryClassByStudent" resultMap="classandstu" parameterType="int">
        select * from classes c
        join student s
        on c.classid = s.classid
        where s.stuid = #{stuId}
    </select>

    <select id="queryStudentByClass" parameterType="int" resultMap="stuandclass" >
        select * from student s
        join  classes c
        on c.classid = s.classid
        where c.classid = #{classId}
    </select>

    <resultMap id="stuandclass" type="Student">
        <id  column="stuid" property="stuId"/>
        <result  column="stuname" property="stuName"/>
        <result  column="stusex" property="stuSex"/>
        <result  column="stuage" property="stuAge"/>
        <collection property="classes" ofType="Classes">
            <id column="classid" property="classId"></id>
            <result column="classcode" property="classCode"></result>
        </collection>
    </resultMap>

    <resultMap id="classandstu" type="Classes">
        <id column="classid" property="classId"></id>
        <result column="classcode" property="classCode"></result>

        <!--one-to-many映射集合对象模型-->
        <collection property="students" ofType="Student"  >
            <id  column="stuid" property="stuId"/>
            <result  column="stuname" property="stuName"/>
            <result  column="stusex" property="stuSex"/>
            <result  column="stuage" property="stuAge"/>
        </collection>
    </resultMap>
</mapper>
  • collection:对关联查询到的多条记录映射到集合对象中
  • property:将查询到的多条记录映射到User类的那个属性中
  • ofType: 指明集合中的元素的类型
三、多对一关联查询

这里的多对一关联查询是指,在查询多方对象的时候,同时将其所关联的一方对象也查询出来。

由于查询多方对象时也是一个一个查询,所以多对一关联查询,其实就是一对一关联查询。即一对一关联查询的实现方式与多对一的实现方式是相同的。

例如:学生Student和班级classes的关系 

代码在一对多关联查询中,此次省略。。。。。。

四、多对多关联查询

多对多关联关系,例如一个学生可以选多门课程,而一门课程可以由多个学生选择。多对多关系,其实是由两个互反的一对多关系组成。一般情况下,多对多关系都会通过一个中间表来建立,例如选课表

思路可按照 双向一对多来

1.定义实体:

在定义双向关联

Course:

public class Course {
    private int courId;
    private String courName;

    List<Student> students;
}

Student:

public class Student {
    private int stuId;

    private String stuName;

    private String stuSex;

    private String stuAge;

    private int classId;

    private List<Course> courses;
}

  2.定义数据库

在多对多的关系时定义数据库,需要用到中间表来关联两个表

student_course表

course表

student表

3.定义dao接口

public interface ManyToManyDao {
    List<Course> queryCoursesAndStudentsByStudentId(int stuId);

    List<Student> queryStudentsAndCoursesByCourseId(int i);
}

4.测试类:

    @Test
    public void classesandstus(){
        ManyToManyDao manyToManyDao = sqlSession.getMapper(ManyToManyDao.class);
        System.out.println(manyToManyDao.queryCoursesAndStudentsByStudentId(1000));
    }

    @Test
    public void studentandclass(){
        ManyToManyDao manyToManyDao = sqlSession.getMapper(ManyToManyDao.class);
        System.out.println(manyToManyDao.queryStudentsAndCoursesByCourseId(1000));
    }

5.写映射文件

<mapper namespace="com.mybatisTest.dao.ManyToManyDao">

    <select id="queryCoursesAndStudentsByStudentId" resultMap="courseandstudent" parameterType="int">
        SELECT * FROM course c
        join student_course sc
        on sc.courid = c.courid
        join student s
        on s.stuid = sc.stuid
        where s.stuid = #{stuId}
    </select>

    <select id="queryStudentsAndCoursesByCourseId" parameterType="int" resultMap="studentandcourse">
        SELECT * FROM  student s
        join student_course sc
        on  s.stuid = sc.stuid
        join course c
        on sc.courid = c.courid
        where c.courid = #{courId}
    </select>

    <resultMap id="courseandstudent" type="Course">
        <id property="courId" column="courid"></id>
        <result column="courname" property="courName"></result>
        <collection property="students" ofType="Student">
            <id  column="stuid" property="stuId"/>
            <result  column="stuname" property="stuName"/>
            <result  column="stusex" property="stuSex"/>
            <result  column="stuage" property="stuAge"/>
        </collection>
    </resultMap>

    <resultMap id="studentandcourse" type="Student">
        <id  column="stuid" property="stuId"/>
        <result  column="stuname" property="stuName"/>
        <result  column="stusex" property="stuSex"/>
        <result  column="stuage" property="stuAge"/>
        <collection property="courses" ofType="Course">
            <id property="courId" column="courid"></id>
            <result column="courname" property="courName"></result>
        </collection>
    </resultMap>
</mapper>

总结
mybatis全局配置文件中通过mapUnderscoreToCamelCase可以开启sql中的字段和javabean中的骆驼命名法的字段进行自动映射

掌握resultMap元素常见的用法

一对一关联查询使用resultMap->association元素(2种方式)

一对多查询使用resultMap->collection元素(2种方式)

resultMap中使用id元素主要在复杂的关联查询中可以提升效率,可以通过这个来判断记录的唯一性,如果没有这个,需要通过所有的result相关的列才能判断记录的唯一性

建议
实体类中最好只定义一些和单表字段关联的属性,不要掺杂着其他对象的引用。

  • 26
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值