• MyBatis学习:使用resultMap或在SQL语句中给列起别名处理查询结果中列名和JAVA对象属性名不一致的问题


    1、本篇博客的背景和目的

    目前我本人正在学习MyBatis框架,在原先了解并且懵懵懂懂使用的基础上,开始系统正式的学习。阐述了MVC架构模式和三层架构,明晰了在Web项目中的普遍编码层次,回顾了JDBC连接数据库,建立了使用MyBatis和MySQL的Maven项目,解释了STDOUT_LOGGING日志和手动提交事务,记录了MyBatis中#占位符的使用方法,回顾了MyBatis执行SQL语句的过程和使用到的一些重要类和接口,记录了将固定化的代码整合到一个工具类MyBatisUtil中,以减少代码量。记录了dao层接口的实现以及为什么要实现它。记录了MyBatis动态代理和使用动态代理的要求以及使用了动态代理生成的实现类。记录了MyBatis框架下传参的五种方法,占位符#和$,如何自定义别名,resultType属性的使用方法。本篇博客记录一下处理数据库中列名和JAVA对象属性名不一致的情况(这种情况一般情况下是都会出现的,因为数据库和代码中的命名规范不一样)。

    2、我的上一篇博文

    我的上一篇博文记录的是resultType的使用方法和注意事项,虽然之前的博客中也提到过,但是不够详细,也不够系统。感兴趣的读者可以移步查阅,链接如下所示:

    MyBatis学习:resultType属性默认转换规则,返回Map结构等详解_你是我的日月星河的博客-CSDN博客https://blog.csdn.net/weixin_46281472/article/details/126532142

    3、使用resultMap标签和属性

    这种解决方法是主流使用方法,是最应该掌握的。

    首先介绍一下resultMap标签:1、resultMap标签使用在mapper.xml文件中,需要先定义后才能在后面的代码中使用。2、resultMap标签翻译成中文就是:结果映射。它可以自定义SQL查询后的结果(列名)和JAVA对象属性的映射关系,更加灵活的把列值赋值给指定的属性多说一下:resultMap标签更多的使用在一对多和多对多的关系上面,就比如多表查询。

    resultMap标签的用法:1、需要先写一个resultMap标签,指定查询结果中的列名和属性名之间的对应关系。一般情况下这个标签都写在mapper.xml文件内的上方部分。2、在resultMap标签中,可以有一个id标签,用来表示主键列对应哪一个属性。不过,即使有主键,这个id标签也是可以没有的。其余的非主键列,统一使用result标签定义映射关系。3、result标签和id标签都有一个column和一个property属性。column属性值为查询结果中的某一个列名,property属性值是这个列对应的JAVA对象的属性名。4、每一个resultMap标签还都有一个id属性,这个id属性值是一个唯一的字符串,在这个mapper.xml文件中必须是唯一的。此外还有一个type属性,属性值是要将结果转换为JAVA的某一个类型的全限定路径名称或者是别名。5、在select标签中使用resultMap属性,属性值是上面定义的某一个resultMap标签的id值;

    下面直接看一下代码:

    首先是要将查询结果转换为某一个实体类的实体类代码,如下所示:

    1. package com.dcy.domain;
    2. public class Student2 {
    3. private Integer id2;
    4. private String name2;
    5. private String email;
    6. private Integer age;
    7. public Integer getId2() { return id2; }
    8. public void setId2(Integer id2) { this.id2 = id2; }
    9. public String getName2() { return name2; }
    10. public void setName2(String name2) { this.name2 = name2; }
    11. public String getEmail() { return email; }
    12. public void setEmail(String email) { this.email = email; }
    13. public Integer getAge() { return age; }
    14. public void setAge(Integer age) { this.age = age; }
    15. @Override
    16. public String toString() {
    17. return "Student2{" +
    18. "id2=" + id2 +
    19. ", name2='" + name2 + '\'' +
    20. ", email='" + email + '\'' +
    21. ", age=" + age +
    22. '}';
    23. }
    24. }

    实体类代码就只有四个属性还有必要的get/set方法,还有重写了toString()方法。实体类中使用的是id2和name2属性,但是数据库中的列名是id和name,这一点是不一致的

    然后是dao层次的接口方法,代码如下所示:

    1. package com.dcy.dao;
    2. import com.dcy.domain.Student;
    3. import com.dcy.domain.Student2;
    4. import java.util.List;
    5. import java.util.Map;
    6. public interface StudentDao {
    7. public List selectAll();
    8. }

    接下来是对应的mapper.xml配置文件,代码如下所示:

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.dcy.dao.StudentDao">
    6. <resultMap id="Student2" type="com.dcy.domain.Student2">
    7. <id column="id" property="id2">id>
    8. <result column="name" property="name2">result>
    9. <result column="email" property="email">result>
    10. <result column="age" property="age">result>
    11. resultMap>
    12. <select id="selectAll" resultMap="Student2">
    13. select * from student
    14. select>
    15. mapper>

    在Main方法中进行必要的测试,代码如下所示:

    1. package com.dcy;
    2. import com.dcy.dao.StudentDao;
    3. import com.dcy.domain.Student2;
    4. import com.dcy.utils.MyBatisUtil;
    5. import org.apache.ibatis.session.SqlSession;
    6. import java.util.List;
    7. public class Starter {
    8. public static void main(String[] args) {
    9. SqlSession sqlSession = MyBatisUtil.getSqlSession();
    10. StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    11. List student2List = studentDao.selectAll();
    12. System.out.println(student2List);
    13. }
    14. }

    结果如下所示:

    多说一下:resultType和resultMap属性是不能同时使用的。

    4、在SQL语句中给列起别名

    还可以使用在SQL语句中给查询出来的结果起别名的方式解决这个问题。但是:这种方式是不常使用的。其实这种方法完全就是考验我们SQL语句的编写能力的。说一下原理吧:比如select语句,我们将结果查询出来以后,其实结果就是一张二维表,二维表总是有表头的。默认情况下,这张二维表的表头就是数据库表中的字段名。但是,我们是可以更改这张二维表的表头的。依据resultType属性的规则,MyBatis其实按照的是这张二维表的表头和JAVA对象的属性名进行对照的。

    依旧使用上面的实体类,明显:Student2这个实体类中的属性id2,name2和数据表中的属性名id,name是不对应的。这样可以在SQL语句中进行一下转换。

    下面我就只粘贴mapper.xml文件中select标签下的SQL语句:

    1. <select id="selectAll2" resultType="com.dcy.domain.Student2">
    2. select id id2,name name2,email,age from student
    3. select>

    注意:这种方法用的是真的不多,因为要直接在SQL语句中修改,非常不推荐使用这种方式。resultMap的那种方式使用的还是更多一点。

    这里我就简单的记录了一下。当然啦,实际的开发中,总是会进行多表查询的,实际的SQL语句会更加的复杂。这个时候使用resultMap的解决方式是最合适的了。

    这里还缺少dao层接口中的方法,依旧使用的是MyBatis的动态代理生成实现类的技术,代码我没有粘贴。运行结果与上面的还是一样的。

    5、本篇博文使用到的代码保存的gitee仓库地址

    本篇博文使用到的代码我都推到了我的gitee仓库中,包含SQL脚本,感兴趣的读者可以移步下载查阅。链接如下所示:

    MyBatis20220827: 20220827记录使用resultMap或在SQL语句中给列起别名解决数据库字段名和对象属性名不一致的情况https://gitee.com/MissShe/MyBatis20220827.git

    6、我的下一篇博文

  • 相关阅读:
    web前端期末大作业:美食文化网页设计与实现——美食餐厅三级(HTML+CSS+JavaScript)
    从零开始自己动手写自旋锁
    Entity Framework Core 简明教程(3)- 关系处理
    hadoop宕机的处理方法
    GreenDaoUpgradeHelper-greenDao的数据库升级帮助类
    围观大神的代码,提高一下精气神
    Pod 健康检查和服务可用性检查
    c语言常见的面试问题
    【C语言 |动态内存管理】堆区动态内存的管理!!!
    gcc编程4步编译、调试c程序实操详解(Linux系统编程)
  • 原文地址:https://blog.csdn.net/weixin_46281472/article/details/126550113