目录

场景解决之mybatis当中resultType= map时,因某个字段为null导致返回的map的key不存在怎么处理

1、场景:通过查询数据表将返回结果封装到map当中返回,因某个字段为null,导致map当中key丢失

java 复制代码
<select id="queryMyBonus" parameterType="com.cn.entity.student" resultType= "map">
        SELECT
        b.projectName as "projectName",
        b.money as "money",
        b.yearMonthDay as "yearMonthDay",
        b.description as "description"
        FROM
        Student b
        <where>
            <if test='userId != null and userId != ""'>
                AND b.USERID = #{userId,jdbcType=VARCHAR}
            </if>
        </where>
        order by b.YEARMONTHDAY desc, b.totalFlag desc, b.BONUSID asc
    </select>

注意上面的resultType= "map",此时当查询结果为

返回的map结果为,丢失了description

2、解决方案

  1. 修改查询SQL:在查询SQL中使用数据库函数(如 IFNULL 或 COALESCE )来为可能为 null 的字段提供一个默认值。
  2. 使用实体类代替Map:如果可能,修改返回类型为一个实体类而不是 map ,这样即使字段值为 null ,也会在实体类中正确地表示出来。
  3. 配置MyBatis:在MyBatis的配置文件中设置 callSettersOnNulls 属性为 true 。这会使得MyBatis在处理结果集时,即使字段值为 null 也会调用映射对象的setter方法(对于 map 来说就是 put 方法),从而在 map 中包含这个键。在 mybatis-config.xml 中添加如下配置
java 复制代码
<configuration>
  <settings>
  <!--  这个修改是全局的 -->
    <setting name="callSettersOnNulls" value="true"/>
  </settings>
</configuration>

如果是Spring Boot项目,可以在 application.properties 或 application.yml 中添加:

properties:

java 复制代码
mybatis.configuration.call-setters-on-nulls=true

yaml:

java 复制代码
mybatis:
  configuration:
    call-setters-on-nulls: true
  1. 自定义TypeHandler:创建一个实现 TypeHandler 接口的类,用于处理 null 值的情况。
java 复制代码
/**
 * 自定义类型处理器,用于将数据库中的null值转换为空字符串
 * 这在避免空指针异常和统一数据处理逻辑方面非常有用
 */
package com.cn.config;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class EmptyStringIfNull implements TypeHandler<String> {
    /**
     * 设置参数值到PreparedStatement中
     * 本方法暂未实现,因为在这种情况下不需要特殊处理
     *
     * @param ps          预编译的SQL语句对象
     * @param i           参数索引
     * @param parameter   参数值
     * @param jdbcType    JDBC类型
     * @throws SQLException 如果操作数据库时发生错误
     */
    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 无需特殊处理,保留默认行为
    }

    /**
     * 从ResultSet中根据列名获取结果,并将null值转换为空字符串
     * 这是处理null值的关键方法
     *
     * @param rs          结果集对象
     * @param columnName  列名
     * @return            字符串结果,如果数据库中的值为null,则返回空字符串
     * @throws SQLException 如果操作数据库时发生错误
     */
    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        // 获取字符串值,如果为null,则返回空字符串
        return (rs.getString(columnName) == null) ? "" : rs.getString(columnName);
    }

    /**
     * 从ResultSet中根据列索引获取结果
     * 本方法未实现,因为当前逻辑不需要使用列索引获取结果
     *
     * @param rs          结果集对象
     * @param columnIndex 列索引
     * @return            未使用,始终返回null
     * @throws SQLException 如果操作数据库时发生错误
     */
    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        // 无需处理,返回null
        return null;
    }

    /**
     * 从CallableStatement中根据列索引获取结果
     * 本方法未实现,因为当前逻辑不需要通过CallableStatement获取结果
     *
     * @param cs          可调用语句对象
     * @param columnIndex 列索引
     * @return            未使用,始终返回null
     * @throws SQLException 如果操作数据库时发生错误
     */
    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 无需处理,返回null
        return null;
    }
}

使用方式:

将select标签的resulttype=map 改成resultMap映射

java 复制代码
 <!-- 查询信息 -->
    <resultMap id="BonusResultMap" type="map">
        <result property="projectName" column="projectName"/>
        <result property="money" column="money"/>
        <result property="yearMonthDay" column="yearMonthDay"/>
        <result property="description" column="description" typeHandler="com.cn.config.EmptyStringIfNull"/>
    </resultMap>

上述配置 typeHandler="com.cn.config.EmptyStringIfNull"

可以单个指定使用较为方便

结果验证:

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
坤小满学Java4 小时前
【从0到1学MybatisPlus】MybatisPlus入门
java·mybatis
bing_1584 小时前
如何在 Spring Boot 项目中使用 MyBatis 进行批量操作以提升性能?
spring boot·后端·mybatis·性能提升
magic 24519 小时前
MyBatis的缓存、逆向工程、使用PageHelper、使用PageHelper
java·spring·maven·mybatis
XiaoLeisj20 小时前
【图书管理系统】深入解析基于 MyBatis 数据持久化操作:全栈开发图书管理系统:查询图书属性接口(注解实现)、修改图书属性接口(XML 实现)
xml·java·数据库·spring boot·sql·java-ee·mybatis
烟沙九洲21 小时前
MyBatis-Plus 的 FieldStrategy 属性
java·mybatis
三天不学习1 天前
Lucene.Net 分词器选择指南:盘古分词 vs 结巴分词
.net·mybatis·lucene
要天天开心啊2 天前
mybatis的第四天学习笔记中
笔记·学习·mybatis
Determined_man2 天前
Mybatis-plus listObjs()
mybatis
Yharim2 天前
MyBatis中如何实现自定义插件
面试·mybatis