自定义TypeHandler 将mysql返回的逗号分隔的String转换到List

sql执行如下:
在这里插入图片描述
这里我定义的接受类:
在这里插入图片描述
但是这里报了错JSON parse error: Cannot deserialize value of type java.util.ArrayList<java.lang.String>from Object value (token JsonToken.START_OBJECT); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type java.util.ArrayList<java.lang.String> from Object value (token JsonToken.START_OBJECT)at [Source: (PushbackInputStream); line: 1, column: 1]",

后来才发现,mysql的GROUP_CONCAT返回的是字符串String类型,无法映射到定义的list里面,MyBatis 返回的结果集与接收结果的对象类型不匹配。

方法一:这里可以修改接受类:,用String接受,在用String的split方法分割处理成List

    private String pdbId;
    private String uniprotId;
    private String geneSymbol;

方法二:自定义一个 TypeHandler 来处理逗号分隔的字符串到列表的转换:

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

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

//自定义一个 TypeHandler 来处理逗号分隔的字符串到列表的转换
public class CommaSeparatedStringTypeHandler extends BaseTypeHandler<List<String>> {

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
        if (strings != null) {
            preparedStatement.setString(i, String.join(",", strings));
        } else {
            preparedStatement.setNull(i, jdbcType.TYPE_CODE);
        }
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String result = resultSet.getString(s);
        return convertStringToList(result);
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String result = resultSet.getString(i);
        return convertStringToList(result);
    }

    @Override
    public List<String> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String result = callableStatement.getString(i);
        return convertStringToList(result);
    }

    private List<String> convertStringToList(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        return Arrays.asList(input.split(","));
    }
}

在xml文件里自定义结果集映射并指定类型转换器:

 <resultMap id="pdbMap" type="com.herb.system.api.model.resp.analysis.PdbSearchResponse">
        <id property="pdbId" column="pdbId"/>
        <result property="uniprotId" column="uniprotId" javaType="java.util.List" jdbcType="VARCHAR" typeHandler="com.herb.entity.config.CommaSeparatedStringTypeHandler"/>
        <result property="geneSymbol" column="geneSymbol" javaType="java.util.List" jdbcType="VARCHAR" typeHandler="com.herb.entity.config.CommaSeparatedStringTypeHandler"/>
    </resultMap>

    <select id="getUniportSymbolOfPdb" resultMap="pdbMap">

        SELECT up.pdb_id as pdbId, GROUP_CONCAT(up.uniprot) AS uniprotId , GROUP_CONCAT(ug.gene_symbol) AS geneSymbol
        FROM `uniprot_pdb`  up  LEFT JOIN uniprot_gene ug on up.uniprot =  ug.uniprot
        WHERE up.pdb_id in
        <foreach collection="pdbIdList" item="id"  open="(" close=")" separator=",">
            #{id}
        </foreach>
        GROUP BY up.pdb_id
    </select>

需要注意的是,一般需要在 MyBatis 配置文件中注册这个自定义的 TypeHandler,在 src/main/resources 目录下创建一个 mybatis-config.xml 配置文件文件,在 配置文件中添加如下的配置:

<configuration>
    <typeHandlers>
        <!-- 注册自定义的 TypeHandler -->
        <typeHandler handler="your.package.path.CommaSeparatedStringTypeHandler"/>
    </typeHandlers>
</configuration>

然后在 application.properties 或 application.yml 文件中添加 MyBatis 的配置mybatis.config-location=classpath:mybatis-config.xml

但是在springboot里面,我没有加入上面的注册,也能运行,原因是MyBatis 可以通过自动扫描的方式发现自定义的 TypeHandler 而无需显式地在 中进行注册。这是因为 MyBatis 会默认扫描某些特定的包路径,例如 org.apache.ibatis.type。如果你的自定义 TypeHandler 的包路径在默认扫描路径下,MyBatis 可能会自动发现并注册它。

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/228226.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第六届“强网”拟态防御国际精英挑战赛 持续引领技术发展新潮流

12月6日&#xff0c;第六届“强网”拟态防御国际精英挑战赛在南京紫金山实验室盛大开幕&#xff0c;来自全球的40支顶尖战队开启了连续72小时的高强度对决。 本届挑战赛由江苏省委网信办指导&#xff0c;南京市委网信办、紫金山实验室、中国通信学会主办&#xff0c;是第三届网…

高精度加法,减法,乘法,除法(下)(C语言)

前言 上一篇博客我们分享了高精度加法&#xff0c;减法,这一期我将为大家讲解高精度乘法和高精度除法。那让我们开始吧&#xff01; 对加法和减法感兴趣的话就点我 文章目录 1&#xff0c;乘法2&#xff0c;除法3&#xff0c;尾声 1&#xff0c;乘法 让我们想想我们平时做数学…

使用高防IP防护有哪些优势

高防IP是针对互联网服务器在遭受大流量的DDoS攻击后导致服务不可用的情况下&#xff0c;推出的付费增值服务&#xff0c;用户可以通过配置高防IP&#xff0c;将攻击流量引流到高防IP&#xff0c;确保源站的稳定可靠。高防IP相当于搭建完转发的服务器。 高防IP有两种接入方式&a…

vue如何解决el-select下拉框显示ID不显示label问题

<template><el-select v-model"searchObj.saleAreaId" change"searchClick" placeholder"请选择" class"inpt1" clearablesize"small"><el-option v-for"item in saleAreaList" :key"item.id…

机器学习实战:预测波士顿房价

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下机器学习中一个非常经典的案例&#xff1a;预测波士顿房价&#xff0c;在此过程中也会补充很多重要的知识点&#xff0c;欢迎大家一起前来探讨学习~ 一、导入数据 在这个项目中&#xff0c;我们利用马萨诸…

uView的使用

下载好uView后&#xff0c;我们可以快速的去使用 JS中工具库的使用 例如&#xff1a;time 时间格式 | uView - 多平台快速开发的UI框架 - uni-app UI框架 我们可以快速的使用内置函数&#xff0c;例如以下时间戳&#xff1a; http请求 但是我们需要注意的是&#xff0c;需要…

Linux下的同步命令代码编写

1.设置静态IP vi /etc/syscnfig/network-scripts/ifcfg-eth1 2.设置主机名 hostnamectl --static set-hostname 主机名 如&#xff1a;hostnamectl --static set-hostname hadoop001 3.配置IP与主机名映射 vi /etc/hosts 4.关闭防火墙 systemctl stop firewalld systemctl…

Nucleo-F103RB-简介

Nucleo-F103RB-简介 1. 前言2. 概述3. 微控制器特性4. Nucleo 功能5. 电路板引脚排列6. 支持的测试板矩阵7. ST MCU板8. ST 扩展板1. 前言 经济实惠且灵活的平台,可简化使用STM32F103RBT6微控制器的原型设计。 2. 概述 STM32 Nucleo开发板为用户提供了一种经济实惠且灵活的…

创新驱动发展丨暴雨信息受邀参加广东省公路工程学术交流会

为加强公路交通工程领域技术交流&#xff0c;结合公路交通工程技术发展和行业热点问题&#xff0c;广东省公路学会联合中国公路学会交通工程与信息化分会举办公路工程学术交流会。学术交流会以“交通工程智能化新技术应用及高速公路改扩建机电工程经验交流”为主题&#xff0c;…

【开源】基于Vue+SpringBoot的河南软件客服系统

文末获取源码&#xff0c;项目编号&#xff1a; S 067 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S067。} 文末获取源码&#xff0c;项目编号&#xff1a;S067。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、…

11.Java安卓程序设计-基于SSM框架的Android平台健康管理系统的设计与实现

摘要 随着人们生活水平的提高和健康意识的增强&#xff0c;健康管理系统在日常生活中扮演着越来越重要的角色。本研究旨在设计并实现一款基于SSM框架的Android平台健康管理系统&#xff0c;为用户提供全面的健康监测和管理服务。 在需求分析阶段&#xff0c;我们明确了系统的…

Java---线程讲解(二)

文章目录 1. Runnable接口2. 卖票案例3. 同步代码块解决数据安全问题4. 同步方法解决数据安全问题5. 线程安全的类6. Lock锁 1. Runnable接口 1. 创建线程的另一种方法是声明一个实现Runnable接口的类&#xff0c;之后重写run()方法&#xff0c;然后可以分配类的实例&#xff0…

vmware安装centos7总结

vmware安装centos7总结 文章目录 vmware安装centos7总结一、配置网络&#xff08;桥接模式&#xff09;二、配置yum源&#xff08;连网配置&#xff09;三、可视化界面四、安装Docker五、安装DockerUI 一、配置网络&#xff08;桥接模式&#xff09; 网络连接模式选择桥接模式…

打包 抖音直播云游戏

抖音直播云游戏 oaid资源中的bcpkix-jdk15to18-1.68.jar与抖音云游戏的资源冲突。 其实资源名称是一样的&#xff0c;拷贝时资源名称有变化。 为解决此问题&#xff0c;需要规范化文件的资源名称&#xff0c;将.置为_ Error: Command failed: cmd /c echo off && Chc…

Java实现Socket聊天室

一、网络编程是什么&#xff1f; 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行数据传输。 应用场景&#xff1a;即时通讯、网游对战、金融证券、国际贸易、邮件、等等。 不管是什么场景&#xff0c;都是计算机与计算机之间通过网络进行数据传输。 …

Docker网络原理及Cgroup硬件资源占用控制

docker的网络模式 获取容器的进程号 docker inspect -f {{.State.Pid}} 容器id/容器名 docker初始状态下有三种默认的网络模式 &#xff0c;bridg&#xff08;桥接&#xff09;&#xff0c;host&#xff08;主机&#xff09;&#xff0c;none&#xff08;无网络设置&#xff…

Linux C语言 39-进程间通信IPC之管道

Linux C语言 39-进程间通信IPC之管道 本节关键字&#xff1a;C语言 进程间通信 管道 FIFO 相关库函数&#xff1a;pipe、mkfifo、mknod、write、read 什么是管道&#xff1f; 管道通常指“无名管道”&#xff0c;是Unix系统中最古老的IPC通信方式。 管道的分类 管道&#…

L1-027:出租

题目描述 下面是新浪微博上曾经很火的一张图&#xff1a; 一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#xff0c;index[1]0 对应 arr[0]8&#xff0c;index[2]3 对应 arr…

绝地求生:【PC】12月网页活动和特殊空投

亲爱的玩家朋友们&#xff0c;大家好&#xff01; 将为2023年画上圆满句号的大型活动和丰厚奖励已经准备就绪。参与活动即可获得武器皮肤&#xff0c;服装&#xff0c;喷漆&#xff0c;黑货票券在内的奖品&#xff0c;赶快来参与活动获得奖励吧&#xff01; 荣都上线纪念活动 …

JavaSE基础50题:19. 递归求斐波那契数列的第N项。

概述 用递归求斐波那契数列的第N项。 斐波那契数列&#xff1a; 1 1 2 3 5 8 …… f(n) f(n-1) f(n-2) 代码 public class P19 {public static int fibnacio(int n) {if (n 1 || n 2) {return 1;}int tmp fibnacio(n-1) fibnacio(n-2);return tmp;}public static void…