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

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

2、我的上一篇博文

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

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值;

下面直接看一下代码:

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

package com.dcy.domain;

public class Student2 {
    private Integer id2;
    private String name2;
    private String email;
    private Integer age;

    public Integer getId2() { return id2; }

    public void setId2(Integer id2) { this.id2 = id2; }

    public String getName2() { return name2; }

    public void setName2(String name2) { this.name2 = name2; }

    public String getEmail() { return email; }

    public void setEmail(String email) { this.email = email; }

    public Integer getAge() { return age; }

    public void setAge(Integer age) { this.age = age; }

    @Override
    public String toString() {
        return "Student2{" +
                "id2=" + id2 +
                ", name2='" + name2 + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

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

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

package com.dcy.dao;

import com.dcy.domain.Student;
import com.dcy.domain.Student2;

import java.util.List;
import java.util.Map;

public interface StudentDao {
    public List<Student2> selectAll();
}

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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dcy.dao.StudentDao">
    <resultMap id="Student2" type="com.dcy.domain.Student2">
        <id column="id" property="id2"></id>
        <result column="name" property="name2"></result>
        <result column="email" property="email"></result>
        <result column="age" property="age"></result>
    </resultMap>
<!--
select标签表示的是查询操作,里面是查询语句。
id属性的值是SQL语句的唯一标识,是一个自定义的字符串。
按照编码规范,这里统一推荐使用dao接口中对应的方法名称。
resultType属性是表示执行SQL语句后,结果对应那个类型的JAVA对象。resultType的值是某个实体类的全限定名称。
比如:com.dcy.domain.Student
-->
<!--    详细介绍一下resultType:
                    1、属性值是 数据类型的全限定路径名称或者是 别名
                    表示MyBatis执行SQL语句后,得到的JAVA对象类型
               规则:同名列 赋值给  同名属性,如果属性没有对应同名的列,那么这个属性就会是null,即使查出来的有结果。
-->
    <select id="selectAll" resultMap="Student2">
        select * from student
    </select>

</mapper>

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

package com.dcy;

import com.dcy.dao.StudentDao;
import com.dcy.domain.Student2;
import com.dcy.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class Starter {
    public static void main(String[] args) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student2> student2List = studentDao.selectAll();
        System.out.println(student2List);
    }
}

结果如下所示:

java 从sql语句获取查询字段 java中sql查询语句_java

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

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

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

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

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

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

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

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

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