Mybatis中ResultMap的简单使用

前言

MyBatis在进行查询映射时,查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。但当指定返回类型属性resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。
而当我们提供的返回类型是resultMap的时候,这就需要自己再进一步的把它转化为对应的对象,这常用于级联查询以及缓存功能。
我们先用一个简单的例子来了解一下 resultMap 的使用。

场景

实体类中的某个属性在数据库中没有相应的字段,但可以通过其它字段来做业务逻辑获取到。
实体类文件:
User.java

package com.lks.domain;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by likaisong on 2019/2/24.
 */
public class User implements Serializable {
    private int id;
    private String name;
    private int age;
    private String county;
    private Date date;
    private Integer birthYear;

    public User(){}

    //resultMap 实现新字段赋值
    public User(Integer age){
        this.age = age;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        this.birthYear = Integer.valueOf(simpleDateFormat.format(new Date()))  - age;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getCounty() {
        return county;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public void setCounty(String county) {
        this.county = county;
    }

    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date= date;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", age=" + age + ", county=" + county + ", date=" + date + ", birthYear=" + birthYear + "]";
    }
}

其中birthYear属性在数据库中是没有相应字段的,但可以通过数据库中的age字段间接获取到,主要看User带参构造方法。
在userMapper.xml文件中配置resultMap,其中借助construct标签

<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的-->
<mapper namespace="userMapper">
    <!--resultMap 实现新字段赋值-->
    <resultMap id="TypeChangeResultMap" type="com.lks.domain.User">
        <constructor>
            <arg column="age" javaType="Integer"/>
        </constructor>
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="county" column="county"/>
        <result property="date" column="date"/>
    </resultMap>
    <sql id="tableAllkey">
         id AS "id",
         name AS "name",
         age AS "age",
         county AS "county",
         date AS "date"
    </sql>

    <select id="resultMapTypeChange" parameterType="int" resultMap="TypeChangeResultMap">
        select <include refid="tableAllkey"/> from users where id=#{id}
    </select>
</mapper>

此处对字段我是用了一个 sql 标签进行包裹,sql 字段可复用,也可直接写到 sql 语句的 select 后面,可自行选择。需要说明的一点是,如果数据库字段与实体类字段完全匹配,字段是可以不添加别名的,如果不是完全匹配,则必须添加别名,只用这样才能使数据库字段映射列到 JavaBean 的属性上。
编写测试类来校验结果:
TestMain.java

package com.lks.test;

import com.lks.domain.User;
import com.lks.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

/**
 * Created by likaisong on 2019/2/24.
 */
public class TestMain {
    private static SqlSession session;

    private static SqlSession getSqlSession(String resource) {
        if (resource == null || "".equals(resource)) {
            return null;
        }
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
        return session;
    }
        @Test
    public static void testResultMapNewKey() {
        String resource = "mybatis-config.xml";
        session = getSqlSession(resource);
        String statement = "userMapper.resultMapTypeChange";
        User user = session.selectOne(statement, 23);
        System.out.println(user);
    }

    @AfterTest
    public static void closeSession() {
        session.close();
    }
}

在这里插入图片描述
可以看到结果中我们取得了我们新增的字段birthYear。
ResultMap还有许多高级用法,尤其是级联查询以及缓存功能。

猜你喜欢

转载自blog.csdn.net/lks1139230294/article/details/87945704