Mybatis-plus 使用 typeHandler 将 String 拼接字符串转换为 List 列表

news2025/1/16 8:22:30

一、需求描述

首先说明需求,有三张表:
学生
学生表、角色表、以及一张关联的中间表。
角色
学生可以有多个角色,但是这多个角色我是作为多条记录存储在另外一张表中的,现在想将这多条记录查询出来,注入到Student对象中的一个List属性中去。

即最后的Student对象结果应该长这样:

[
    {
        "id": 1,
        "name": "硕子鸽",
        "roles": [
            "物理课代表",
            "数学课代表"
        ]
    }
]

总之就是要将 1,2,3 或者 1 2 3 转换为 Java 中的 List = [1,2,3]。

我可以在Service层中做两次查询然后分别注入,但是为了优雅一点,我想只使用持久层框架就解决这个问题。

二、实现方案

这边了解到Mybatis框架中提供了一个类型转换器,我可以实现该接口来完成自定义类型转换。这个抽象类为BaseTypeHandler

首先我需要写个SQL将想要的数据查询出来,然后再考虑类型转换。

查询的语句为:

SELECT stu.*,
       (SELECT group_concat(r.role_name) AS roles
        FROM stud_role sr
                 left join role r on sr.role_id = r.role_id
        WHERE sr.stu_id = stu.id) AS roles
FROM student stu;

这段SQL的查询结果如下,含义是把该学生信息、以及该学生所属的角色拼接成字符串作为一个字段查出来。

其中group_concatMysql中的函数,在Oracle中请使用wmsys.wm_concat以达到同样的效果。
查询结果
然后就是类型转换了。

实现BaseTypeHandler抽象类:

package com.shuo.mpth.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;

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

/**
 * @author : wshuo
 * @date : 2023/1/11 15:59
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes({List.class})
public class ListTypeHandler extends BaseTypeHandler<List<String>> {

    private static final String DELIM = ",";

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
        String value = StringUtils.collectionToDelimitedString(strings, DELIM);
        preparedStatement.setString(i, value);
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String value = resultSet.getString(s);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String value = resultSet.getString(i);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }

    @Override
    public List<String> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String value = callableStatement.getString(i);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }
}
  • @MappedJdbcTypes:表示SQL语句中查出来的类型;
  • @MappedTypes:表示要转成 Java 对象的类型;
  • DELIM:表示字符串的分隔符,如果你是用空格分开的就赋值为空格。

这知识第一步,下面我们需要在指定的地方使用它,这里我直接使用 @TableField 注解指定待转换字段。

@Data
public class Student {
    /**
     * 学生ID
     */
    private Integer id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 该学生所具备的角色
     */
    @TableField(typeHandler = ListTypeHandler.class)
    private List<String> roles;
}
  • typeHandler:指定类型转换器;

如果没有使用 mybatis-plus ,使用的是 mybatis 的 xml 配置,则在 property 标签里增加typeHandler属性是一样的效果。

最后我们还需要在 yml 配置文件中增加一段配置:

mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.shuo.mpth.**.entity
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-handlers-package: com.shuo.mpth.handler
  • type-handlers-package:指定handler的包名。

随即启动项目,请求接口,发现已经完成类型的转换:
请求接口

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务之JVM调优

一、Xms Xmx Xss等定义及功能 1.Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。 2.Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异…

易基因|14种全基因组DNA甲基化测序(WGBS)标准分析比对软件的比较| 生信专区

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。全基因组重亚硫酸盐测序&#xff08;WGBS&#xff09;是甲基化研究的重要技术。尽管已经开发了一系列工具来解决由亚硫酸盐处理引起的比对问题&#xff0c;但尚未对最新可用工具的reads比对…

HashMap,Hashtable,ConcurrentHashMap

目录 一、多线程使用HashMap的一些线程安全问题 ①造成数据新增丢失 ②扩容时候&#xff0c;造成链表成环 二、Hashtable和HashMap的区别 ①核心方法加锁 ②其他语法上面的略微差异 三、引入ConcurrentHashMap【重要】 ①ConcurrentHashMap相比于Hashtable的优势 Hashtab…

著名相声艺术家侯耀华,77岁寿宴现场曝光,郭德纲师哥前去祝贺

在中国的相声界&#xff0c;有一条不成文的规定&#xff0c;关于著名相声表演艺术家的判定&#xff0c;从来不是以相声水平高低为标准。只要你有足够长的寿命&#xff0c;只要你能把其他人都熬走熬败&#xff0c;就算你是一个相声小白&#xff0c;也能摇身一变成为艺术家。 不过…

Git介绍与使用

1.集中式版本控制 svn 中央服务器 所有的版本数据都存在服务器上&#xff0c;用户本地只有自己所同步的版本&#xff0c;如果不联网的话&#xff0c;用户就看不到 SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的 而工作的时候,用的都是自己的电脑,所以首先…

跨境电商物流系统功能框架

随着国内互联网巨头们逐渐将更多注意力投向了跨境电商市场&#xff0c;电商巨头出海也在掀起新的发展高潮。下面是跨境电商物流系统功能框架&#xff0c;供大家参考1、OMS叫做订单管理系统&#xff08;Order Management System&#xff09;&#xff0c;在不同公司&#xff0c;不…

云原生时代的运维体系进化

云原生已经成为数字经济技术的创新基石&#xff0c;并且正在深刻地改变企业上云和用云的方式。云原生的用云方式可以帮助企业最大化获得云价值&#xff0c;也给企业的计算基础设施、应用架构、组织文化和研发流程带来新一轮变革。而业务和技术挑战也催生了新一代云原生运维技术…

设计模式(一)----设计模式概述及UML图解析

1、设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大&#xff08;Christopher Alexander&#xf…

Golang开发 02

文章目录一、Golang开发工具二、visual studio code安装(VS code)1、安装window2、安装mac、linux一、Golang开发工具 # 1、Visual studio code &#xff08;常用&#xff09; # 2、Sublime Text(免费) # 3、Vim # 4、Emacs # 5、Eclipes IDE工具&#xff0c;开源免费&#xf…

数据分析-深度学习PytorchDay1

深度学习框架pytorch学习(一)准备环境准备环境一、深度学习框架简介二、Tensorflow与Pytorch的比较三、安装开发环境一、深度学习框架简介1、Google阵营最早的是由加拿大团队开发的theano一个机器学习库&#xff0c;现在已经停止更新。接着Google开发了Tensorflow&#xff0c;并…

【机器学习知识点】3. 目标检测任务中如何在图片上的目标位置绘制边界框

目录前言导入图片定义边界框绘制函数在图片中绘制边界框总结前言 在图像分类任务中&#xff0c;很多时候我们不仅要知道图像中目标的类别&#xff0c;而且还想知道它们在图像中的具体位置。在计算机视觉里&#xff0c;这类任务被称为目标检测&#xff08;object detection&…

uniapp开发技术

目录 1、js 判断iPhone|iPad|iPod|iOS|Android客户端 2、js实现防抖 3、 js实现节流 4、 页面在弹窗时禁止底部页面滚动&#xff08;h5端&#xff09; touchmove.stop.prevent 5、scrollIntoView 1、js 判断iPhone|iPad|iPod|iOS|Android客户端 // fullScreen代表整个页面…

【C++】STL---list的模拟实现

目录前言一、list和vector的区别二、节点的定义三、list类定义四、push_back函数五、push_front函数六、迭代器七、begin和end函数八、迭代器区间初始化九、迭代器的操作符重载操作符重载操作符- -重载操作符&#xff01;重载操作符重载操作符*重载十、insert函数十一、erase函…

如何应用卫星图像插入到Auto CAD

如何应用卫星图像插入到Auto CAD发布时间&#xff1a;2018-01-17 版权&#xff1a;工具准备BIGEMAP GIS Office&#xff1a;http://www.bigemap.com/reader/download/案例&#xff1a;等高线完美套合卫星影像教程本实例使用AutoCAD2008软件进行影像与矢量数据叠加配准。影像获取…

变压器和特斯拉线圈

目录 变压器用途 变压器的原理 变压器特点 特斯拉线圈用途 特斯拉线圈原理 特斯拉线圈特点 参考&#xff1a; 变压器用途 电压变换、电流变换、阻抗变换、隔离、稳压等 1&#xff09;开关电源&#xff0c;充电器&#xff0c;220v转换为指定电压&#xff0c;以给各类电子…

Revit建模幕墙问题:幕墙添加门/窗和生成幕墙

一、Revit中如何在幕墙当中添加门、窗构件 今天跟大家分享一下幕墙当中添加门窗的方法&#xff0c;这种方法大家可以联想到很多应用上&#xff0c;因为这个既是个方法也是个技巧&#xff0c;好了&#xff0c;我们直接进入主题吧。 首先&#xff0c;我们新建幕墙&#xff0c;给它…

范数的意义与计算方法

1. 范数的意义 范数可以简单的理解为“距离”。由于向量是既有大小又有方向的量&#xff0c;所以向量是不能直接比较大小的&#xff0c;但是范数提供了一种方法&#xff0c;可以将所有的向量转化为一个实数&#xff0c;然后就可以比较向量的大小了。&#xff08;注&#xff1a…

【计算机视觉】Pooling层的作用以及如何进行反向传播

问题 CNN网络在反向传播中需要逐层向前求梯度,然而pooling层没有可学习的参数,那它是如何进行反向传播的呢? 此外,CNN中为什么要加pooling层,它的作用是什么? Pooling层 CNN一般采用average pooling或max pooling来进行池化操作,而池化操作会改变feature map的大小,…

swagger的使用与步骤

1、导入maven工程首先我们创建一个 Spring Boot 项目&#xff0c;并引入 Swagger3 的核心依赖包&#xff0c;如下&#xff1a;<dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.…

2022年度游戏本行业数据报告:十大热门品牌销量排行榜

2022年游戏本市场的总体局面是&#xff1a;产品竞争极为激烈&#xff0c;同时又各具特色卖点。今年的游戏本市场&#xff0c;市场格局并未有较大的变化&#xff0c;但是新技术、新产品层出不穷&#xff0c;各个游戏本厂商们通过不断创新、提升产品性能&#xff0c;推出了体验感…