5 自定义映射 resultMap和一对多和多对一关系处理

如果我们的表的字段名和实体类的属性名不一致的话

  • 我们都知道,数据库中查询结果是通过其字段名然后找到属性名再反射赋值
  • 如果字段名和属性名不一致,那么怎么通过字段名找到属性名呢?

方法

  • 起别名,在查询的时候起别名,别名和属性名一致 select emp_id empId,emp_name empName from t_emp where emp_id = #{empId}

  • 因为mysql字段命名(表名_字段名)和java属性命名(驼峰命名)规则不一致,所以经常有字段名和属性名不一致的情况,我们可以在mybatis核心配置文件中设置一个全局配置,可以映射字段名和属性名

    • <settings>
      • <setting name="mapUnderscoreToCamelCase" value="true"/>
    • </settings>
    • 这样设置mybatis全局中,会自动将字段名映射为驼峰命名
  • 使用resultMap自定义映射处理

    • 首先我们要在映射文件里自定义resultMap标签
    • <resultMap id="empResultMap" type="Emp">
      • <id column="emp_id" property="empId"></id>
      • <result column="emp_name" property="empName"></result>
      • <result column="age" property="age"></result>
      • <result column="gender" property="gender"></result>
    • </resultMap>
    • 解释一下
      • resultMap id 表示你在使用resultMap是方便指定是哪个resultMap,type就是映射属性的实体类
      • 标签中的id 表示处理 主键映射 column表示我们要处理的从数据库中查询出来的字段名 property表示当前我们处理的实体类的属性名
      • result 表示处理普通字段的映射 其他与id同理
  • 多对一映射关系处理

    • 记好一个准则 对一就是对一个对象 对多就是一个集合
    • 现在我有一个Emp类和一个Dept类,Emp和Dept是多对一的关系
    • 所以Emp类中有一个属性是private Dept dept,但是emp表对应的Emp类中的这个dept属性该怎么映射呢
      • 一开始我们想用多表连接查询来进行映射,我们的确能查询到Emp类中dept对象属性的属性值如deptId,depName等,但是我们无法将这些属性值映射到Emp类中的dept对象属性中去,还是无法为dept属性赋值
      • 三种处理方式
        • 级联方式处理
          • <resultMap id="EmpResultMap" type="Emp">
            • <id column="emp_id" property="empId"></id>
            • <result column="emp_name" property="empName"></result>
            • <result column="age" property="age"></result>
            • <result column="gender" property="gender"></result>
            • <result column="dept_id" property="dept.deptId"></result>
            • <result column="dept_name" property="dept.deptName"></result>
          • </resultMap>
          • 通过这种方式为Emp中的dept属性赋值,通过多表查询。
        • association处理
          • 使用association处理实体类中实体类类型属性
          • <resultMap id="EmpResultMap" type="Emp">
            • <id column="emp_id" property="empId"></id>
            • <result column="emp_name" property="empName"></result>
            • <result column="age" property="age"></result>
            • <result column="gender" property="gender"></result>
            • <association property="dept" javaType="Dept">
              • <id column="dept_id" property="deptId"></id>
              • <result column="dept_name" property="deptName"></result>
            • </association>
          • </resultMap>
          • 上面的javatype就是实体类型属性的类名(别名)
          • 在assciation标签里面处理查询到的数据库字段和实体类属性的属性之间的关系
        • 分步查询处理
          • 一定要理清查询的顺序,它不需要多表查询,先查什么后查什么
          • 这个比较难搞一点,现在我有一个t_emp表和t_dept表,emp表中每条数据都有一个dept_id来表示它属于哪个dept,通过分步查询来获取它所属部门的详细信息(部门名称等)
          • 首先根据emp_id查询到对应的记录
            • <select id="getEmpById" resultMap="EmpResultMap">
              • select * from t_emp where emp_id = #{empId}
            • </select>
          • 在resultMap中定义好映射关系
            • <resultMap id="EmpResultMap" type="Emp">
              • <id column="emp_id" property="empId"></id>
              • <result column="emp_name" property="empName"></result>
              • <result column="age" property="age"></result>
              • <result column="gender" property="gender"></result>
              • <association property="dept" select="com.cn.zt.mybatis.mappers.DeptMapper.selectDeptById" column="dept_id"
              • </association>
            • </resultMap>
          • 先解释一下 这里还是要用到asscation标签,但是用法不一样,这次是在asscation中添加属性而不是在asscaation标签内添加映射关系
          • property属性还是用来表示属性名,这里的属性是dept实体类属性
          • select属性表示sql标识符(namespace+select的id) 这个是分步查询的精髓,他表示了下一步该用到哪个查询语句
          • column属性表示下一个sql语句要用的条件(参数)
          • 下一条查询语句
            • <select id="selectDeptById" resultType="Dept">
              • select * from t_dept where dept_id = #{deptId}
            • </select>
          • 通过这条查询返回dept给emp中dept属性赋值
          • 流程大概是这样,我详细点
            • 首先在测试方法中调用Emp empById = mapper.getEmpById(1);
            • Emp getEmpById(@Param("empId") int empId);
            • 然后到映射文件中
              • <select id="getEmpById" resultMap="EmpResultMap">
                • select * from t_emp where emp_id = #{empId}
              • </select>
            • 再到Dept seletDeptById(@Param("deptId") int deptId);
            • 然后到映射文件中
              • <select id="selectDeptById" resultType="Dept">
                • select * from t_dept where dept_id = #{deptId}
              • </select>
          • 分步查询的优点 [[延迟加载]]
  • 一对多映射关系处理

    • 使用collection标签(处理集合类型属性)
      • 举个例子,我一个Dept类中有一个Emp集合,一对多关系
      • 使用方法 和 asscation标签 类似
        • 使用resultMap来处理映射关系
        • <resultMap id="resultMapList" type="Dept">
          • <id column="dept_id" property="deptId"></id>
          • <result column="dept_name" property="deptName"></result>
          • <collection property="empList" ofType="Emp">
            • <id column="emp_id" property="empId"></id>
            • <result column="emp_name" property="empName"></result>
            • <result column="age" property="age"></result>
            • <result column="gender" property="gender"></result>
          • </collection>
        • </resultMap>
      • 有些不同的地方就在于collection标签中的 ofType属性设置为映射的集合属性中的实体类型
      • 然后就是多表查询映射
    • 使用分步查询
      • 过程类似多对一映射分步查询,再演示一遍
      • 举例子,Dept类中有个Emp集合,一对多映射
      • 首先
        • 第一步用deptId查到对应记录并赋值到dept对象中
          • Dept selectDept(@Param("deptId") int deptId);
        • 映射文件写法
          • <select id="selectDept" resultMap="resultMapList">
            • select * from t_dept where dept_id = #{deptId}
          • </select>
          • <resultMap id="resultMapList" type="Dept">
            • <id column="dept_id" property="deptId"></id>
            • <result column="dept_name" property="deptName"></result>
            • <collection property="empList" select="com.cn.zt.mybatis.mappers.EmpMapper.getEmpListBydeptId" column="dept_id">
            • </collection>
          • </resultMap>
        • 下一步t_emp中deptId符合条件的记录,并以集合方式放回
          • List<Emp> getEmplistBydeptId(@Param("deptId") int deptId);
        • 对应映射文件写法
          • <select id="getEmpListBydeptId" resultType="Emp">
            • select * from t_emp where dept_id = #{deptId}
          • </select>
        • 最后该集合会被赋值到dept的集合类属性中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值