mapper.xml中的结果映射

域对象(就是domain下面的类)之间的关联关系:
按照多重性可分为一对一、一对多、多对一和多对多,即数据库中的表之间的关系
根据关联关系,所以以右为主,所以一对一、多对一的处理方式是一样的,一对多和多对多一样,而左边决定抽象方法的返回类型。

举例:一个年级的班级信息表与学生信息表
如果用一张表来存储的话,每条学生数据都有班级字段,并且都是写“xx班级”;
但如果将学生信息和班级信息拆分,而学生表仍有班级Id字段,虽然看起来并没有什么区别,
但是这样就会减少占用的存储空间,毕竟数字肯定是比"xx班级"的字节数小;
一旦数据多了,差距就出现了,而且有利于数据的维护,比如需要改班级信息,两张表的情况下,只需要改班级表就好;但如果在一张表中,需要改与班级相关的每天学生信息。
但两张表的查询要比一张表麻烦一点,
所以就用resultMap来做结果映射:就是在多表查询时,用来根据需求,配置查询结果

============================================================
*对一

员工实体类

public class Employee {

    private Long id;
    private String name;

    //多对一配置:多个员工属于一个部门
    private Department department;

//省略getter与setter,toString
    ...
}

部门实体类

public class Department {
    private Long id;
    private String name;
    //省略getter与setter,toString
    ...
}

映射文件
1、嵌套结果:查出多表的全部字段,然后选自己想要的

<mapper namespace="cn.itsource.many2one.mapper.EmployeeMapper">

    <!--
        resultMap:完成结果映射
            1. id代表映射名称(随便取),给别的sql调用
            2. type:映射对应返回的对象类型
    -->
    <resultMap id="employeeMap" type="cn.itsource.mybatis.many2one.domain.Employee">
        <id property="id" column="id" /><!--id标签表示主键,这里用result也可,但规范一点-->
        <result property="name" column="name" />
        <!--association :联系 -->
        <association property="department" column="dept_id" javaType="cn.itsource.many2one.domain.Department">
            <id  property="id" column="did"/>
            <result property="name" column="dname" />
        </association>
    </resultMap>
    
    <!--
        resultMap:通过id,引用结果映射
            1.把查询结果弄成自己想要的实体类,必需使用结果映射
            2.多张表查询时,如果出现相同的列名,一定要取别名,不然默认赋值出现column值的第一列
    -->
    <select id="findAll" resultMap="employeeMap">
        select e.id,e.name,d.id did,d.name dname from 
        employee e left join department d 
        on d.id = e.dept_id
    </select>

</mapper>

查询结果

2、嵌套查询:先查一张表,然后外键的那一列做为参数,执行另一条sql,去另一张表查
EmployeeMapper.xml

<mapper namespace="cn.itsource.many2one.mapper.EmployeeMapper">

    <resultMap id="employeeMap" type="cn.itsource.many2one.domain.Employee">
        <id property="id" column="id" />
        <result property="name" column="name" />
        
        <!-- select:指向要查询的sql,并执行(如果在同一个文件中可以省略前面的namespace) 
        	 所以xml之间调用sql,是直接根据命名空间+id,而不是去找接口哦~
        	 column:就是把当前查出来的这一列,作为参数,传给select指向的sql-->
        <association property="department" column="dept_id"
                     select="cn.itsource.many2one.mapper.DepartmentMapper.findById">
        </association>
    </resultMap>
    
    <!-- resultMap:引用结果映射 -->
    <select id="findAll" resultMap="employeeMap">
        select * from employee
    </select>

</mapper>

DepartmentMapper.xml:为了规范,操作哪个表的sql就应该写在哪个mapper.xml文件中

<mapper namespace="cn.itsource.many2one.mapper.DepartmentMapper">
    <!--根据id获取相应的部门数据-->
    <select id="findById" resultType="cn.itsource.many2one.domain.Department">
        select * from department where id=#{id}
    </select>
</mapper>

===========================================================
*对多
员工实体类

public class Employee {

    private Long id;
    private String name;
    
	//省略getter与setter,toString
    ...
}

部门实体类

public class Department {
    private Long id;
    private String name;
    //一对多配置(一个部门对应多个员工)
    private List<Employee> employees = new ArrayList<>();
    //省略getter与setter,toString
    ...
}

也是同样的2种处理方式,基本一模一样
而不同点是,联系用的是collectionofType,因为*对多是’多’嘛,当然用集合接收;
而一/多对一,其实也是可以用collection,因为集合能装多个,所以当然能装一个,
不过为了规范,各用各的吧

myBatis会自动把从第二张表查询出来的数据放入对应的list,所以是这样显示的

ClassInfo{id=1, name='0531班级', students=[Student{id=7, name='陈佳星', age=22}, Student{id=8, name='李鹏', age=25}]}
ClassInfo{id=2, name='0532班级', students=[Student{id=9, name='郑杨', age=24}, Student{id=10, name='高小满', age=19}, Student{id=11, name='张鑫', age=21}]}
ClassInfo{id=3, name='0533班级', students=[Student{id=12, name='廖家乐', age=28,}, Student{id=13, name='母杨帆', age=22}]}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值