MyBatis PostgreSQL实现数组类型的操作

news2024/10/6 22:33:45

我的GitHub:Powerveil · GitHub

我的Gitee:Powercs12 (powercs12) - Gitee.com

皮卡丘每天学Java

最近在学习数据库PostgreSQL,遇到如何实现对数组类型的数据操作,试着自己尝试学习实现。

话不多说,直接撸代码。

建表语句 PostgreSQL DDL

-- auto-generated definition
create table faviroute_book
(
    employee_id integer,
    books       integer[]
);

insert into faviroute_book values (1,ARRAY [1,2,55]);
insert into faviroute_book values (2,ARRAY [1,2,23]);
insert into faviroute_book values (3,ARRAY [1,23,554]);

select *
from faviroute_book;

备注:integer

 application.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/test
    driver-class-name: org.postgresql.Driver
    username: postgres
    password: 123456

FavirouteBookMapper.xml需要的配置

<resultMap id="BaseResultMap" type="com.power.mytest.domain.FavirouteBook">
    <result property="employeeId" column="employee_id" jdbcType="INTEGER"/>
<!--        <result property="books" column="books" jdbcType="ARRAY" typeHandler="org.apache.ibatis.type.ArrayTypeHandler"/>-->
<!--这里使用resultMap会识别到,注意这里说的是mybatis/>-->
    <result property="books" column="books" jdbcType="ARRAY"
            typeHandler="com.power.mytest.handler.ArrayTypeHandler"/>
</resultMap>


<insert id="insertFavirouteBook" parameterType="com.power.mytest.domain.FavirouteBook">
    INSERT INTO faviroute_book (employee_id, books)
    VALUES (#{employeeId}, #{books, jdbcType=ARRAY, typeHandler=com.power.mytest.handler.ArrayTypeHandler})
</insert>

以插入和查询单个为例

FavirouteBookMapper.java

@Mapper
public interface FavirouteBookMapper extends BaseMapper<FavirouteBook> {

    int insertFavirouteBook(FavirouteBook favirouteBook);

    FavirouteBook getOneByIdMy(Integer id);
}

插入方法时需要加上jdbcType=ARRAY, typeHandler=org.apache.ibatis.type.ArrayTypeHandler

typeHandler是一个数组类型转换器,

查询方法时,resultMap的数组字段要加上jdbcType=ARRAY, typeHandler=org.apache.ibatis.type.ArrayTypeHandler

这里我使用的是apache的

也可以使用自定义,当然apache更全,下面是一个自定义的数组类型转换器

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

import java.sql.*;

public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
    private static final String TYPE_NAME_VARCHAR = "varchar";
    private static final String TYPE_NAME_INTEGER = "integer";
    private static final String TYPE_NAME_BOOLEAN = "boolean";
    private static final String TYPE_NAME_NUMERIC = "numeric";
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException {
        String typeName = null;
        if (parameter instanceof Integer[]) {
            typeName = TYPE_NAME_INTEGER;
        } else if (parameter instanceof String[]) {
            typeName = TYPE_NAME_VARCHAR;
        } else if (parameter instanceof Boolean[]) {
            typeName = TYPE_NAME_BOOLEAN;
        } else if (parameter instanceof Double[]) {
            typeName = TYPE_NAME_NUMERIC;
        }
        if (typeName == null) {
            throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
        }
        // 这3行是关键的代码,创建Array,然后ps.setArray(i, array)就可以了
        Connection conn = ps.getConnection();
        Array array = conn.createArrayOf(typeName, parameter);
        ps.setArray(i, array);
    }
    @Override
    public Object[] getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return getArray(resultSet.getArray(s));
    }
    @Override
    public Object[] getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return getArray(resultSet.getArray(i));
    }
    @Override
    public Object[] getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return getArray(callableStatement.getArray(i));
    }
    private Object[] getArray(Array array) {
        if (array == null) {
            return null;
        }
        try {
            return (Object[]) array.getArray();
        } catch (Exception e) {
        }
        return null;
    }
}

对应的xml

<insert id="insertFavirouteBook" parameterType="com.power.mytest.domain.FavirouteBook">
    INSERT INTO faviroute_book (employee_id, books)
    VALUES (#{employeeId}, #{books, jdbcType=ARRAY, typeHandler=org.apache.ibatis.type.ArrayTypeHandler})
</insert>

<select id="getOneByIdMy" resultMap="BaseResultMap">
    select * from faviroute_book
    where employee_id = #{id}
</select>

测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyTestApplication.class})
public class Test01 {

    @Autowired
    private FavirouteBookService favirouteBookService;

    @Test
    public void test02() {
        FavirouteBook favirouteBook = new FavirouteBook();
        Integer[] arrays = new Integer[] {43,123,321};
        favirouteBook.setEmployeeId(100);
        favirouteBook.setBooks(arrays);
        favirouteBookService.insertFavirouteBook(favirouteBook);
    }


    @Test
    public void test03() {
        FavirouteBook oneByIdMy = favirouteBookService.getOneByIdMy(1);
        System.out.println(oneByIdMy);
    }
}

效果

插入

 

查询

如果要使用MyBatis Plus查询,而且使用内置的方法就不可以了

测试方法

@Test
public void test01() {
    System.out.println("Hello World");
    System.out.println("==============使用list()方法====================");
    List<FavirouteBook> list = favirouteBookService.list();
    System.out.println(list);
    System.out.println("==============使用getOne()方法====================");
    LambdaQueryWrapper<FavirouteBook> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(FavirouteBook::getEmployeeId, 1);
    FavirouteBook favirouteBook = favirouteBookService.getOne(queryWrapper);
    System.out.println(favirouteBook);
    System.out.println(Arrays.toString(favirouteBook.getBooks()));
}

效果

怎么解决呢?

需要在实体类中加入一些配置,必须加入的有

autoResultMap = true

@TableField(value = "books", jdbcType = JdbcType.ARRAY, typeHandler = ArrayTypeHandler.class)

@TableName(value ="faviroute_book", autoResultMap = true)
@Data
public class FavirouteBook implements Serializable {
    @TableField(value = "employee_id")
    private Integer employeeId;
    @TableField(value = "books", jdbcType = JdbcType.ARRAY, typeHandler = ArrayTypeHandler.class)
    private Integer[] books;
}

为了让框架识别通过实体类加过直接生成的resultMap,框架默认识别不了我们自己写的resultMap

查看效果

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

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

相关文章

linux下一个iic驱动(按键+点灯)-互斥

一、前提&#xff1a; 硬件部分&#xff1a; 1. rk3399开发板&#xff0c;其中的某一路iic&#xff0c;这个作为总线的主控制器 2. gd32单片机&#xff0c;其中的某一路iic&#xff0c;从设备。主要是按键上报和灯的亮灭控制。&#xff08;按键大约30个&#xff0c;灯在键的…

新手杯—easy_base

0x00 前言 CTF 加解密合集&#xff1a;CTF 加解密合集 0x01 题目 0XezFWZfNXafRjNlNXYit3dvh2cmR3Y0x02 Write Up 先倒序 然后base64解码 以上

Self-Attention Cross-Attention

transformer的细节到底是怎么样的&#xff1f;Transformer 连环18问&#xff01; 4.1 从功能角度&#xff0c;Transformer Encoder的核心作用是提取特征&#xff0c;也有使用Transformer Decoder来提取特征。例如&#xff0c;一个人学习跳舞&#xff0c;Encoder是看别人是如何…

智能网卡在分布式 SDN 网络的应用与实践 | 龙蜥技术

编者按&#xff1a;当前智能网卡能够加速数据处理和传输&#xff0c;并能实现网络、存储和安全等功能卸载&#xff0c;在云计算领域得到广泛的应用。今天&#xff0c;浪潮数据云计算网络架构师王培辉带大家了解智能网卡加速原理和以及在浪潮分布式 SDN 网络加速的应用&#xff…

我连夜咨询了30个老同学,学IT上培训班到底有用么?

文章目录 一、背景二、学习IT上培训班的益处2.1 IT行业本身还不错2.2 获取到系统的专业知识2.3 获取到实战经验2.4 获取到网络资源和支持2.5 获取到职业发展指导2.6 建立初步的职业圈子人脉 三、学习IT上培训班的风险3.1 质量风险3.2 课程更新速度风险3.2 缺乏互动与实践机会风…

积分微分电路

积分微分电路 通过写出时域的推导&#xff0c;再到频域&#xff0c;详细介绍了积分微分的频率响应的推导&#xff0c;手绘了bode图&#xff0c;并仿真电路得到对应的结果。积分的频率响应&#xff1a;频率增加10倍&#xff0c;增益下降20db。输出相位超前输入相位90度。微分的…

GPT-4 最强竞争对手,Claude 杀疯了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 在今年早些时候&#xff0c;ChatGPT、Bard、Claude 等大语言模型&#xff0c;在 AI 领域呈三权鼎立之势&#xff0c;无人能出其右&#xff0c;被视为是能力表现最为卓越的 3 款 AI 聊天机器…

阿里云无影云电脑具体价格_云桌面不同配置1元报价

阿里云无影云电脑配置费用&#xff0c;4核8G企业办公型云电脑可以免费使用3个月&#xff0c;无影云电脑地域不同费用不同&#xff0c;无影云电脑是由云桌面配置、云盘、互联网访问带宽、AD Connector、桌面组共用桌面session等费用组成&#xff0c;阿里云百科分享阿里云无影云电…

大模型的“第一性原理”:技术创新与社会价值的接轨

随着时间来到2023年第三季度&#xff0c;国产大模型已经达到100多个&#xff0c;“百模大战”正式开启。 大模型&#xff0c;我们有了很多选择&#xff0c;也开始呈现出某种同质化。除了拼参数、比背景、看榜单&#xff0c;有没有其他方法&#xff0c;让我们更好地判断一个大模…

解决Gson解析json字符串,Integer变为Double类型的问题

直接上代码记录下。我代码里没有Gson包&#xff0c;用的是nacos对Gson的封装&#xff0c;只是包不同&#xff0c;方法都一样 import com.alibaba.nacos.shaded.com.google.common.reflect.TypeToken; import com.alibaba.nacos.shaded.com.google.gson.*;import java.util.Map;…

经典CNN(一):ResNet-50算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 1 ResNet理论 深度残差网络ResNet(deep residual network)在2015年由何凯明等提出&#xff0c;因为它简单与实用并存&#xff0c;随后很多研究…

Hutool工具类 -集常用工具类为一体 - 工具类之大成

文章目录 说在前面的话简介gitee介绍项目介绍 网址gtiee 网址github 网址 安装pom依赖引入 &#xff1a;下载jar 文档中文文档中文备用文档参考API视频介绍 部分截图首页包含组件(总)IO流相关部分工具类(Util)集合类HTTP客户端 功能不再一一赘述和截图&#xff0c;具体请查看官…

详解TCP协议

TCP协议段格式 序号和确认序号&#xff1a;在真实服务器和客服端通信过程中请求是并行执行的&#xff0c;这会导致到达是乱序的&#xff0c;所以才会有序号这个东西&#xff0c;确认序号是对方应答时返回的&#xff0c;例如序号发送到1&#xff0c;确认序号会返回2&#xff0c;…

计算机网络 day6 arp病毒 - ICMP协议 - ping命令 - Linux手工配置IP地址

目录 arp协议 arp病毒\欺骗 arp病毒的运行原理 arp病毒产生的后果&#xff1a; 解决方法&#xff1a; ICMP协议 ICMP用在哪里&#xff1f; ICMP协议数据的封装过程 ​编辑 为什么icmp协议封装好数据后&#xff0c;还要加一个ip包头&#xff0c;再使用ip协议再次进…

springboot农机电招平台

本系统为了数据库结构的灵活性所以打算采用MySQL来设计数据库&#xff0c;而java技术&#xff0c;B/S架构则保证了较高的平台适应性。本文主要介绍了本系统的开发背景&#xff0c;所要完成的功能和开发的过程&#xff0c;主要说明了系统设计的重点、设计思想。 本系统主要是设…

关于java垃圾回收的小结

一、为什么要有垃圾回收 我们每次创建对象都需要在栈上开辟空间&#xff0c;堆上使用内存&#xff0c;如果我们只是开辟了这个空间&#xff0c;而不去释放他&#xff0c;那么再大的内存和空间也会有满的一天&#xff0c;所以我们在Java中引入了GC&#xff08;垃圾回收机制&…

Foxit PDF ActiveX 5.9.8 Crack

Foxit PDF SDK ActiveX 即时添加PDF显示功能至Windows应用程序&#xff0c;快速投放市场&#xff0c;可视化编程组件功能强大且易于使用的PDF软件开发工具包 对于刚接触PDF或不愿投入过多精力学习PDF技术的产品管理者及开发者来说&#xff0c;Foxit PDF SDK ActiveX无疑是理想…

中国1km分辨率逐月平均气温数据集(1901-2022)

时间分辨率月空间分辨率1km - 10km共享方式开放获取数据大小9.71 GB数据时间范围 1901.1-2022.12 数据集摘要 该数据为中国逐月平均温度数据,空间分辨率为0.0083333(约1km),时间为1901.1-2022.12。数据格式为NETCDF,即.nc格式。数据单位为0.1 ℃。该数据集是根据CRU发布的…

对Vue组件化开发思想的一些理解

目录 组件的分类 为什么需要组件化开发 如何设计组件 组件间通信 组件系统是 Vue的一个重要概念&#xff0c;让我们可以用独立可复用的小组件来构建大型应用。几乎任意类型的应用的界面都可以抽象为一个组件树&#xff1a; 写一个 Vue 项目&#xff0c;其实就是在写一个个的…

接口测试 react+unittest+flask 接口自动化测试平台

目录 1 前言 2 框架 2-1 框架简介 2-2 框架介绍 2-3 框架结构 3 平台 3-1 平台组件图 1 新建用例 2 生成测试任务 3 执行并查看测试报告 3-2 用例管理 3-2-1 用例设计 3-3 任务管理 3-3-1 创建任务 3-3-2 执行任务 3-3-3 测试报告 3-3-4 邮件通知 1 前言 构建…