您好,欢迎来到年旅网。
搜索
您的当前位置:首页MyBatis04-数据库记录与实体对应关系、resultMap、N+1查询方式

MyBatis04-数据库记录与实体对应关系、resultMap、N+1查询方式

来源:年旅网

一、数据表与java实体

在开发中,我们数据库常常包含多张表,每张表包含的记录也各不相同。
学生表(stuno,sname,classno)
班级表(classno,cname)
课程表(sid,sname)
选课表(stuno,sname)
我们会创建四个类分别表示学生表的记录、班级表的记录、课程表的记录和选课表的记录。
现在想象一下这样的业务场景,我们需要查询所有学生以及它们对应的班级(不能直接使用多表查询)
我们往往会选择先查询所有的学生,再利用学生记录里面的classno字段来查询对应的班级。

业务代码(伪代码)
<select id="selectAll" returnType="student">
	select * from student
</select>
<select id="selectClaById" returnType="clazz">
	select * from clazz where classno=#{param1}
</select>

pubulic void main(String[] args){
		//[1]解析myBatis.xml文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");

        //[2]获得sqlsession工厂
        SqlSessionFactory  factory=new SqlSessionFactoryBuilder().build(inputStream);

        //[3]获得session对象
        SqlSession sqlSession = factory.openSession(true);
		
		selectMapper mapper = sqlSession.getMapper(selectMapper.class);
		//查询所有学生
		List<Student> list = mapper.selectAll();
		//查找每个学生对应的班级
		for(Student stu:list){
			Clazz clazz = mapper.selectClaById(stu.getClassno());
			}
}
	

上述代码虽然可以查询到学生对应的班级但却无法将班级对象与学生对象相联系,我们可以在student类中添加如下字段:Clazz clazz;来保存该学生所对应的班级对象。

二、resultMap

在mybatis中,resultMap标签是用来映射返回结果的,功能如下:

  • 当数据表字段与java实体字段名称不一致时,使用resultMap来将数据库查询到的记录返回成实体对象
  • 当java实体类存在一些字段数据表中没有时,我们可以采用<association>来调用其他查询方法赋值给该实体字段

用法如下:

<select id="selectAll" returnType="rm1">
	select * from student
</select>
<resultMap id="rm1" type="student">
        <!--column:数据库的列名  property:实体的属性名-->
        <!--如果数据库的列明和实体类中的属性名一致,就可以省去该标签
            但是公共字段不建议省去
        -->
        <id column="sid" property="sid"></id>
        <result column="sname" property="sname"></result>
        <result column="clazzno" property="clazzno"></result>
        <!--
           select *  from clazz  where clazzno=?
          select:执行哪一个方法
          column:希望查询的哪一列作为参数进行传递
          javaType:返回值类型
          property:把返回的结果赋值给对象中哪一个属性
        -->
       <association select="com.xie.mapper.ClaMapper.selectClaById" 
       column="cno" property="cla" javaType="clazz"></association>
    </resultMap>

三、N+1查询方式

在我们第一节中使用的业务代码起始就是我们的N+1查询,传统的N+1查询方式代码过于冗长,在mybatis中,我们可以使用resultMap来简化我们的N+1方式,在第二节中给出了代码的使用方式,在这一节我们主要讲它如何使用,什么场景中使用?
在上一节中,我们使用resultMap简化了查询学生以及对应班级的操作,我们发现在使用association或collection的时候,使需要指定一个查询方法并且给定一个参数(该参数来自于查询的数据表中的字段),并且需要指定返回类型(返回类型与使用的查询方法有关,就是查询方法所查询的表的记录)

如果我们有一个业务需要查询每个学生以及他所对应的课程呢?(要求使用resultMap)

我们能在Student类中添加一个字段List<Session> sessions; 来表示吗?

答案:是不可以直接添加该字段来表示,因为学生与课程之间并没有直接的联系,它们是通过选课表来实现多对多的关系的,应该添加字段:List<SC> sc;来表示,然后再在SC类中添加字段:Session sess;来表示课程对象,这样就能够通过student对象的sc属性的sess属性来访问到课程。

总结

当两个实体之间存在直接联系的时候,可以将它们互相作为对方的字段保存,比如学生与班级、学生与选课记录(可以通过学号查找班级、可以通过学号查找选课记录),在student类中设置一个clazz字段,在clazz类中设置一个List<Student> sList; 字段。
这样设置的好处是:

  • 每个查询语句只能返回一个值,这样设置的话只用返回一个student对象,它就包括了clazz对象
  • 它还能将两个实体联系起来

当两个实体之间不存在直接联系而是间接联系时,就不能互相作为对象的字段保存,比如student类和Session类,无法通过student类的某字段查询其对应的Session记录,所以它们通过第三个实体SC对象来实现间接联系。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务