mybatis自定义类型控制器(TypeHandler)处理将字符串处理为集合

news2024/11/16 7:41:49

在这里插入图片描述

1. 问题:

假设这么一个场景
在这里插入图片描述

localurl里面的值大概这样:dwad21.jpg,dwad22.jpg,dwad.23.jpg 是一个字符串

如果我在sql表中有一个字段(local_url)是本地图片资源的多个url字符串拼接值。我想在java后端中不进行额外的转换就取值加值。我需要的是里面的dwad21.jpg,最好做集合处理。

🌴 最好的情况就是使用sql映射到对象的时候就把把字符串变成集合dwad21.jpg,dwad22.jpg,dwad.23.jpg => {dwad21.jpg,dwad22.jpg,dwad.23.jpg}

🌴 然后使用insert或者update的时候自动把集合变成字符串{dwad21.jpg,dwad22.jpg,dwad.23.jpg} =>dwad21.jpg,dwad22.jpg,dwad.23.jpg

2. 解决思路:

2.1.typehandler官网介绍

主要是对请求数据或者接受数据进行自定义映射处理。

我只能说mybaits非常任性了提供了自定义类型转换器。

mybatis官网=>配置=>类型处理器
《------------------------------------------------------------------》
功能:MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。

在这里插入图片描述
下面是常用的数据类型的默认使用的类型处理器。

类型处理器Java 类型=>JDBC 类型
BooleanTypeHandlerjava.lang.Boolean,boolean =>BOOLEAN
ByteTypeHandlerjava.lang.Byte,byte => NUMERIC,BYTE
ShortTypeHandlerjava.lang.Short, short =>NUMERIC , SMALLINT
IntegerTypeHandlerjava.lang.Integer, int =>NUMERIC , INTEGER
LongTypeHandlerjava.lang.Long, long => NUMERIC , BIGINT
FloatTypeHandlerjava.lang.Float, float => NUMERIC , FLOAT
DoubleTypeHandlerjava.lang.Double, double=> NUMERIC ,DOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal =>NUMERIC, DECIMAL
StringTypeHandlerjava.lang.String => CHAR, VARCHAR

2.2. 创建自定义handler

你可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:

  1. 实现 org.apache.ibatis.type.TypeHandler 接口,
  2. 继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 并且可以(可选地)将它映射到一个 JDBC 类型。比如:

在大部分使用场景中mybaitis的默认类型转换器就可以帮助大家的java对象到jdbc对象的转换。

但是我的整的花活显然不是满足。正好mybatis允许我们自定义类转换器。

我们这里使用实现接口的方法进行类型控制器的声明

public class StringToListTypeHandler implements TypeHandler<List<String>> {

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

    @Override
    public List<String> getResult(ResultSet rs, String columnName) throws SQLException {
        String columnValue = rs.getString(columnName);
        return convertStringToList(columnValue);
    }

    @Override
    public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {
        String columnValue = rs.getString(columnIndex);
        return convertStringToList(columnValue);
    }

    @Override
    public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String columnValue = cs.getString(columnIndex);
        return convertStringToList(columnValue);
    }

    private List<String> convertStringToList(String columnValue) {
        if (columnValue != null) {
            return Arrays.asList(columnValue.split(","));
        } else {
            return null;
        }
    }
}
  • setParameter 方法:这个方法用于将 Java 对象的参数设置到 PreparedStatement 中,通常用于将参数绑定到 SQL 语句中的占位符。在这个示例中,它将 List 类型的参数转换为逗号分隔的字符串,并设置到 PreparedStatement 中。如果参数为 null,它将设置为数据库类型的 null 值。

  • getResult(ResultSet rs, String columnName):从 ResultSet 对象中获取结果,根据列名 columnName 获取对应的列的值。

  • getResult(ResultSet rs, int columnIndex):从 ResultSet 对象中获取结果,根据列索引 columnIndex 获取对应的列的值。

  • getResult(CallableStatement cs, int columnIndex):从 CallableStatement 对象中获取结果,根据列索引 columnIndex 获取对应的列的值。通常,这种情况用于从存储过程中获取结果。
    🌴一般只实现一个方法即可

2.3. 注册类型转换器

要注意 MyBatis 不会通过检测数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指明字段是 VARCHAR 类型

<typeHandlers>
    <typeHandler handler="com.chen.behindimagesmanage.handler.StringToListTypeHandler" javaType="java.util.List<java.lang.String>" jdbcType="VARCHAR"/>
</typeHandlers>

当然这里也可以配置别名,如果这里设置了类型在mapper里就可以不用设置了。

2.4. mapper使用类型转换器

  1. 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.chen.behindimagesmanage.dao.FileDao">

    <!-- 定义一个查询语句 -->
    <resultMap id="imageMetaDataResultMap" type="com.chen.behindimagesmanage.pojo.ImageMetaData">
        <id property="id" column="id" />
        <result property="md5" column="md5" />
        <result property="aliyunUrl" column="aliyun_url" />
        <result property="localUrl" column="local_url" typeHandler="com.chen.behindimagesmanage.handler.StringToListTypeHandler" />
        <result property="version" column="version" />
    </resultMap>
    <select id="getAllImg" resultType="imageMetaDataResultMap">
        SELECT * FROM image_metadata
    </select>



    <!-- 定义一个更新语句 -->
    <parameterMap id="imageMetaDataParamMap" type="com.chen.behindimagesmanage.pojo.ImageMetaData">
        <parameter property="id" jdbcType="INTEGER" javaType="java.lang.Integer" mode="IN"/>
        <parameter property="md5" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
        <parameter property="aliyunUrl" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
        <parameter property="localUrl" typeHandler="com.chen.behindimagesmanage.handler.StringToListTypeHandler"/>
        <parameter property="version" jdbcType="INTEGER" javaType="int" mode="IN"/>
    </parameterMap>
    <update id="updateLocalUrl" parameterType="imageMetaDataParamMap"
    >
        UPDATE image_metadata SET  local_url= #{imageMetaData.localUrl}, version = #{imageMetaData.localUrl} + 1 WHERE version = #{imageMetaData.localUrl}
    </update>

</mapper>

  1. mapper接口层
@Mapper
public interface FileDao {
    /**
     * 获取所有img归属信息
     * @return 所有归属信息
     */
    List<ImageMetaData> getAllImg();

    /**
     * 更新元数据归属服务器
     * @param imageMetaData 更新的元数据列
     * @return 影响行
     */
    int updateLocalUrl(ImageMetaData imageMetaData);
}

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

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

相关文章

华硕灵耀X双屏pro(UX8402Z)原装Windows11系统恢复安装方法及其教程

华硕灵耀X双屏pro&#xff08;UX8402Z&#xff09;原装Windows11系统恢复安装方法及其教程 第一步&#xff1a;自备原装系统swm/esd/wim/iso等用PE安装还原的系统文件&#xff0c;或者拥有或者售后zip工厂恢复安装包&#xff08;6个底包&#xff1a;EDN.KIT.OFS.HDI.SWP.TLK&a…

【LeetCode:86. 分隔链表 | 链表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

2023年中国档案信息化发展历程、竞争格局及行业市场规模分析[图]

档案信息化是以网络、计算机、信息技术为手段&#xff0c;以档案资源为对象&#xff0c;以档案工作为依托&#xff0c;以档案管理学最新理论为指导&#xff0c;按照信息社会和国家档案行政管理部门的要求、开展档案的收集、整理、保管、开发和利用的现代化管理过程。 档案信息化…

Node.js、Vue的安装与使用(Linux OS)

Vue的安装与使用&#xff08;Linux OS&#xff09; Node.js的安装Vue的安装Vue的使用 操作系统&#xff1a;Ubuntu 20.04 LTS Node.js的安装 安装Node.js Node.js官方下载地址 1.选择合适的系统架构&#xff08;可通过uname -m查看&#xff09;版本安装 2.下载文件为tar.xz格…

1 如何入门TensorFlow

近年来人工智能的火爆吸引了很多人&#xff0c;网上相关的热门课程报名的人很多&#xff0c;但是坚持下去的人却少。那些晦涩的原理没有一定知识的积累很难能理解。 如果你对人工智能感兴趣&#xff0c;且想利用人工智能去实现某项功能&#xff0c;而不是对人工智能本身感兴趣&…

Vue3 + Echarts(5.x) 实现中国地图

Echarts展示地图 效果图 安装 npm install echarts默认安装的是 5.x 版本 在这个版本中的引入方式必须是下面这种方法 import * as echarts from echarts源码 在echarts5.x版本中&#xff0c;已经不再提供地图数据&#xff0c;所以需要我们自己手动下载&#xff0c;我这里…

Qt扫盲-QTextCodec理论总结

QTextCodec理论总结 一、概述二、编码支持三、使用四、创建自己的编解码器类 一、概述 QTextCodec 是Qt提供的一个管理字符串编码的功能&#xff0c;他可以在不同编码方式中来回转换&#xff0c;在文件读取的时候、格式编码转换的时候用处很大。Qt使用Unicode 编码来存储、绘制…

探索未来的视觉革命:卷积神经网络的崭新时代(一)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

【圆满落幕】IDCF社区天津理工大学华信软件学院校友会技术沙龙丨IDCF

金秋十月的校园既充满活力又不失庄重&#xff0c;既富有学术气息又不失生活情趣&#xff0c;这里是学生们求学、成长和发展的小天地&#xff0c;洋溢着青春的活力和积极向上的氛围。由IDCF社区&天津理工大学华信软件学院联合举办的校友会技术沙龙活动在这里圆满举行——让技…

Kotlin 知识点小结

一.Kotlin 协程启动方式总结 1.withContext 同步串行 带返回 2.launch 异步 不带返回 3.asyc 异步 带返回 4.runblocking 同步 带返回 二.作用域函数 &#xff0c;T的扩展函数 &#xff08;with不是T的扩展函数&#xff09;都是内联函数 Kotlin中的lateinit和by lazy有以下…

短视频矩阵系统源码---php搭建

一、智能剪辑、矩阵分发、无人直播、爆款文案于一体独立应用开发 抖去推----主要针对本地生活的----移动端(小程序软件系统&#xff0c;目前是全国源头独立开发)&#xff0c;开发功能大拆解分享&#xff0c;功能大拆解&#xff1a; &#xff08;1&#xff09;数据概览&#x…

【LeetCode力扣】86. 分隔链表

目录 1、题目介绍 2、解题思路 2.1、双链表双指针 2.2、代码描述 1、题目介绍 原题链接&#xff1a;86. 分隔链表 - 力扣&#xff08;LeetCode&#xff09; 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&#xff1a;[1,2,2,4,3,5] 示例 2&#xff…

2048天创作纪念日

2048天创作纪念日 初心收获日常成就憧憬 初心 大一的时候&#xff0c;老师上课说可以通过浏览他人博客或者自己写博客来学习编程。从那以后&#xff0c;写博客这件事情就埋在了我心里&#xff0c;但是我一直没有什么内容想写。直到入选了ACM校队后&#xff0c;需要经常做大量的…

【算法|动态规划No.24】leetcode LCR 093. 最长的斐波那契子序列的长度

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

wireshark抓包解密TLS,解决个人环境看不到明文流量

wireshark抓包浏览器流量 https://monkeywie.cn/2020/08/07/wireshark-capture-https/ 解密TLS流量 按照上面的步骤抓到流量后&#xff0c;正常是可以看到明文数据&#xff0c;但在我的wireshark上一直看不到。因为有其它替代方案&#xff08;在反向代理后面抓包、fiddler&a…

2023下半年信息系统集成设计师选择题

选择题 第一章 信息基础知识第二章 信息系统集成第三章 专业技能知识第四章 项目管理一般知识第五章 项目立项管理第六章 项目整体管理第七章 项目范围管理第八章 项目进度管理第九章 项目成本管理第十章 项目质量管理第十一章 项目管理干系人第十三章 合同管理第十五章 配置管…

springBoot整合讯飞星火认知大模型

1.概述 讯飞星火大模型是科大讯飞最近开放的拥有跨领域的知识和语言理解能力的大模型&#xff0c;能够完成问答对话和文学创作等。由于讯飞星火大模型最近可以免费试用&#xff0c;开发者都可以免费申请一个QPS不超过2的账号&#xff0c;用来实现对平台能力的验证。本文将利用…

好物周刊#27:音乐助手

https://github.com/cunyu1943/JavaPark https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. lamp 快速开发平台 lamp-cloud 基于 Jdk11 SpringCloud SpringBoot …

【LeetCode】101. 对称二叉树

101. 对称二叉树&#xff08;简单&#xff09; 方法&#xff1a;递归 思路 两个树互为镜像的条件&#xff1a; 它们的两个根结点具有相同的值。每个树的右子树都与另一个树的左子树镜像对称。 因此&#xff0c;我们需要递归比较左子树和右子树&#xff0c;将根节点的左子树记…

线程池在项目中的使用

1.runAsync执行完后无返回值 package com.search.thread; import java.util.concurrent.*; public class ThreadTest {public static ExecutorService executor Executors.newFixedThreadPool(10);public static void main(String[] args) throws ExecutionException, Interr…