当前位置: 首页 > news >正文

Mybatis Plus 集成 PgSQL 指南

“哲学家们只是用不同的方式解释世界,而问题在于改变世界。”

——卡尔·马克思 (Karl Marx)

解读:马克思强调了实践的重要性,主张哲学不仅要理解世界,更要致力于改造世界。

本文我们引入 Mybatis Plus 作为 ORM ,并且使用 PgSQL 作为数据库,实现一个自定义复合类型数组参数的自定义函数。

一、POM 依赖

<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.6.0</version>
</dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version><scope>provided</scope>
</dependency><!-- web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

二、配置 YML

spring:datasource:# 数据源基本配置url: jdbc:postgresql://127.0.0.1:5432/dbnameusername: postgrespassword: #################driver-class-name: org.postgresql.Drivertype: com.alibaba.druid.pool.DruidDataSource

三、配置 Mybatis

package com.example.pgsqldemo.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;/*** @version: V1.0* @author: 余衫马* @description: mybatis 配置* @data: 2024-10-25 14:25**/
@Configuration
@MapperScan("com.example.pgsqldemo.dao")
public class MybatisConfig {
}

四、实体类封装

模拟复合类型传参,创建 MySettingsDTO 类,

package com.example.pgsqldemo.dto;import lombok.Data;/*** @version: V1.0* @author: 余衫马* @description: 自定设置类 DTO* @data: 2024-10-25 14:42**/
@Data
public class MySettingsDTO {/*** 配置项*/private String item;/*** 配置值*/private String content;}

创建 TestDTO 它有一个成员 List<MySettingsDTO> mySettingsDTOList

package com.example.pgsqldemo.dto;import lombok.Data;import java.util.List;/*** @version: V1.0* @author: 余衫马* @description: 测试 DTO* @data: 2024-10-25 14:37**/
@Data
public class TestDTO {private List<MySettingsDTO> mySettingsDTOList;}

五、数据库操作

创建复合类型,

CREATE TYPE type_my_setting AS (item text,content text
);

创建函数 dynamic_sql_query ,输出 item 字母顺序上最大的一行记录

CREATE OR REPLACE FUNCTION dynamic_sql_query (arr type_my_setting [])
RETURNS type_ptl_setting  AS $$
DECLAREmax_record type_my_setting ;
BEGIN-- Initialize max_record with the first element of the arraymax_record := arr[1];-- Loop through the array to find the record with the maximum item valueFOR i IN 2 .. array_length(arr, 1) LOOPIF arr[i].item > max_record.item THENmax_record := arr[i];END IF;END LOOP;RETURN max_record;
END;
$$ LANGUAGE plpgsql;

函数测试,

SELECT dynamic_sql_query (ARRAY[ROW('apple', 'content1')::type_my_setting ,ROW('banana', 'content2')::type_my_setting ,ROW('cherry', 'content3')::type_my_setting 
]);

六、自定义handler

处理复合类型数组

package com.example.pgsqldemo.handler;import com.example.pgsqldemo.dto.MySettingsDTO;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgresql.util.PGobject;import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;/*** @version: V1.0* @author: 余衫马* @description: MySettings复合类型数组处理器* @data: 2024-10-25 17:07**/
public class MySettingsArrayTypeHandler extends BaseTypeHandler<List<MySettingsDTO>> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, List<MySettingsDTO> parameter, JdbcType jdbcType) throws SQLException {Connection conn = ps.getConnection();PGobject[] pgObjects = new PGobject[parameter.size()];// 每个对象都是 type_my_setting 复合类型for (int j = 0; j < parameter.size(); j++) {MySettingsDTO mySettingsDTO = parameter.get(j);PGobject pgObject = new PGobject();pgObject.setType("type_my_setting");pgObject.setValue(String.format("(%s,%s)", mySettingsDTO.getItem(), mySettingsDTO.getContent()));pgObjects[j] = pgObject;}// pgsql 复合数组类型 type_my_setting[]Array array = conn.createArrayOf("type_my_setting", pgObjects);ps.setArray(i, array);}@Overridepublic List<MySettingsDTO> getNullableResult(ResultSet rs, String columnName) throws SQLException {return toList(rs.getArray(columnName));}@Overridepublic List<MySettingsDTO> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return toList(rs.getArray(columnIndex));}@Overridepublic List<MySettingsDTO> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return toList(cs.getArray(columnIndex));}private List<MySettingsDTO> toList(Array pgArray) throws SQLException {if (pgArray == null) {return null;}Object[] array = (Object[]) pgArray.getArray();List<MySettingsDTO> list = new ArrayList<>();for (Object obj : array) {PGobject pgObject = (PGobject) obj;String[] values = Objects.requireNonNull(pgObject.getValue()).replace("(", "").replace(")", "").split(",");MySettingsDTO mySettingsDTO = new MySettingsDTO(values[0], values[1]);list.add(mySettingsDTO);}return list;}
}

七、Mapper 与 XML 编写

在 DAO 层新建一个动态查询方法 dynamicSqlQuery

package com.example.pgsqldemo.dao;import com.example.pgsqldemo.dto.TestDTO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.HashMap;
import java.util.List;/*** @version: V1.0* @author: 余衫马* @description: 测试 DAO* @data: 2024-10-25 14:26**/
@Mapper
public interface TestDao {public List<HashMap<String, Object>> dynamicSqlQuery(@Param("dto") TestDTO dto);}
<select id="dynamicSqlQuery" resultType="java.util.HashMap" statementType="CALLABLE">select * FROM dynamic_sql_query(#{dto.mySettingsDTOList,jdbcType=ARRAY,typeHandler=com.example.pgsqldemo.handler.MySettingsArrayTypeHandler});
</select>

八、Postman测试

POST localhost:8080/api/dynamicSqlQuery# 请求报文
{"mySettingsDTOList": [{"item": "AAAAA","content": "BBBBB"},{"item": "123","content": "456"},{"item": "ABC","content": "FFFFFF"}]
}# 响应报文
[{"item": "ABC","content": "FFFFFF"}
]

可以看到,传复合类型的数组参数可以被 SQL 函数正常执行,并返回了预期结果。

相关文章:

Mybatis Plus 集成 PgSQL 指南

“哲学家们只是用不同的方式解释世界&#xff0c;而问题在于改变世界。” ——卡尔马克思 (Karl Marx) 解读&#xff1a;马克思强调了实践的重要性&#xff0c;主张哲学不仅要理解世界&#xff0c;更要致力于改造世界。 本文我们引入 Mybatis Plus 作为 ORM &#xff0c;并且使…...

Rust常用数据结构教程 Map

文章目录 一、Map类型1.HashMaphashMap的简单插入entry().or_insert()更新hashMap 2.什么时候用HashMap3.HashMap中的键 二、BTreeMap1.什么时候用BTreeMap2.BTreeMap中的键 参考 一、Map类型 键值对数据又称字典数据类型 主要有两种 HashMap - BTreeMap 1.HashMap HashM…...

<el-popover>可以展示select change改变值的时候popover 框会自动隐藏

一、问题定位 点击查看详细链接 element-plus 的 popover 组件&#xff0c;依赖 tooltip 组件&#xff1b;当 tooltip 的 trigger 的值不是 hover 时&#xff0c;会触发 close 事件&#xff1b;下拉框的 click 事件&#xff0c;触发了 tooltip 组件的 close 事件 总结一下&am…...

SQLI LABS | Less-37 POST-Bypass mysql_real_escape_string

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-37/ 是一个登…...

数字后端零基础入门系列 | Innovus零基础LAB学习Day9

Module 16 Wire Editing 这个章节的学习目标是学习如何在innovus中手工画线&#xff0c;切断一根线&#xff0c;换孔&#xff0c;更改一条net shape的layer和width等等。这个技能是每个数字IC后端工程师必须具备的。因为项目后期都需要这些技能来修复DRC和做一些手工custom走线…...

深度学习:GLUE(General Language Understanding Evaluation)详解

GLUE&#xff08;General Language Understanding Evaluation&#xff09;详解 GLUE&#xff08;General Language Understanding Evaluation&#xff09;是一个用于评估和比较自然语言理解&#xff08;NLU&#xff09;系统的综合基准测试。它包括了一系列的任务&#xff0c;旨…...

基于Multisim直流稳压电源电路±9V、±5V(含仿真和报告)

【全套资料.zip】直流稳压电源电路9V、5VMultisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 一般直流稳压电源都使用220伏市电作为电源&#xff0c;经过变压、整流、滤波后给稳压电路进行稳压…...

Vue Cli的配置中configureWebpack和chainWebpack的主要作用及区别是什么?

直接区别&#xff1a; configureWebpack项直接覆盖同名配置&#xff1b;chainWebpack项直接修改默认配置。 configureWebpack配置&#xff1a; // vue.config.js module.exports {configureWebpack: {plugins: [new MyAwesomeWebpackPlugin()]} }该代码段中的对象将会被web…...

ubuntu主机搭建sysroot交叉编译环境

ubuntu主机搭建sysroot交叉编译环境 主机是 ubuntu22.04 x86-64 hostubuntu22.04host-archx86-64host-cpui9-13900k 目标板是香橙派5b &#xff0c;ubuntu22.04,aarch64 ,cpu rk3588s targetubuntu22.04target-archaarch64target-cpurk3588s 安装 qemu-user-static 进入 …...

Python注意力机制Attention下CNN-LSTM-ARIMA混合模型预测中国银行股票价格|附数据代码...

全文链接&#xff1a;https://tecdat.cn/?p38195 股票市场在经济发展中占据重要地位。由于股票的高回报特性&#xff0c;股票市场吸引了越来越多机构和投资者的关注。然而&#xff0c;由于股票市场的复杂波动性&#xff0c;有时会给机构或投资者带来巨大损失。考虑到股票市场的…...

实验三 JDBC数据库操作编程(设计性)

实验三 JDBC数据库操作编程&#xff08;设计性&#xff09; 实验目的 掌握JDBC的数据库编程方法。掌握采用JDBC完成数据库链接、增删改查&#xff0c;以及操作封装的综合应用。实验要求 本实验要求每个同学单独完成&#xff1b;调试程序要记录调试过程中出现的问题及解决办法…...

各种环境换源教程

目录 pip 换源相关命令永久换源1. 命令行换源2. 配置文件换源 临时换源使用官方源使用镜像源 报错参考 npm换源相关命令永久换源1. 命令行换源2. 配置文件换源 pip 换源 相关命令 更新 pip 本身 首先&#xff0c;为了确保你使用的是最新版本的 pip&#xff0c;可以通过以下命…...

Rust项目中的Labels

姊妹篇: Go项目中的Labels 按照issue数量从多到少排序: https://github.com/rust-lang/rust/labels?page2&sortcount-desc https://github.com/rust-lang/rust/labels/A-contributor-roadblock 第1页: 标签/中文说明数字T-compiler/编译器Relevant to the compiler tea…...

Jmeter的安装和使用

使用场景&#xff1a; 我们需要对某个接口进行压力测试&#xff0c;在多线程环境下&#xff0c;服务的抗压能力&#xff1b;还有就是关于分布式开发需要测试多线程环境下数据的唯一性。 解决方案: jmeter官网连接&#xff1a;Apache JMeter - Apache JMeter™ 下载安装包 配…...

初识Electron 进程通信

概述 Electron chromium nodejs native API&#xff0c;也就是将node环境和浏览器环境整合到了一起&#xff0c;这样就构成了桌面端&#xff08;chromium负责渲染、node负责操作系统API等&#xff09; 流程模型 预加载脚本&#xff1a;运行在浏览器环境下&#xff0c;但是…...

go语言中的通道(channel)详解

在 Go 语言中&#xff0c;通道&#xff08;channel&#xff09; 是一种用于在 goroutine&#xff08;协程&#xff09;之间传递数据的管道。通道具有类型安全性&#xff0c;即它只能传递一种指定类型的数据。通道是 Go 并发编程的重要特性&#xff0c;能够让多个 goroutine 之间…...

【JS】内置类型的相关问题

我是目录 引言内置类型undefined与nullnull和undefined的区别字符串转换为字符串数字0.1+0.2不等于0.3NaNBigInt大数相加问题原生函数(封箱与解封)判断类型的方法typeofinstanceofObject.prototype.toString.callconstructor类型转换toStringtoNumbertoBoolean显式强制类型转…...

Mac上无法访问usr/local的文件

sudo chmod 755 /usr/loca 最后用百度提供的方法解决了...

http 常见状态码

1xx 信息&#xff0c;表示临时响应并需要请求者继续执行操作 2xx 成功&#xff0c;操作被成功接收并处理 3xx 表示要完成请求&#xff0c;需要进一步操作。通常&#xff0c;这些状态码用来重定向 4xx 客户端错误&#xff0c;请求包含语法错误或无法完成请求 5xx 服务…...

代码训练营 day59|并查集

前言 这里记录一下陈菜菜的刷题记录&#xff0c;主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕&#xff0c;一年车企软件开发经验 代码能力&#xff1a;有待提高 常用语言&#xff1a;C 系列文章目录 第59天 &#xff1a;第十一章&#xff1a;图论part05 文章目录…...

如何用Kafka-King轻松管理Kafka集群:5分钟上手完整指南

如何用Kafka-King轻松管理Kafka集群&#xff1a;5分钟上手完整指南 【免费下载链接】Kafka-King A modern and practical kafka GUI client &#x1f495;&#x1f389;Kafka-King 是一款现代化、实用的 Kafka GUI 客户端&#xff0c;旨在通过直观的桌面界面简化 Apache Kafka …...

给UE4蓝图和C++开发者的Lua/UnLua入门:什么时候该用,怎么设计架构?

UE4架构设计指南&#xff1a;何时引入Lua与UnLua的最佳实践 当你在UE4项目中频繁修改玩法逻辑时&#xff0c;是否经历过这样的困境&#xff1a;每次调整都需要重新编译C代码&#xff0c;等待时间从几分钟到几小时不等&#xff1b;或者蓝图节点越连越多&#xff0c;最终变成难以…...

学习信息系统项目管理师我们以什么视角学习?

如果你只是死记硬背那些定义&#xff0c;你会觉得这本书枯燥乏味&#xff0c;而且做题时很容易掉进陷阱。但如果你**“入戏”**&#xff0c;把自己当成那个掌握全局的项目经理&#xff0c;很多答案你凭直觉就能选对。为了帮你把“入戏”进行到底&#xff0c;我给你三个**“入戏…...

终极虚拟显示器解决方案:ParsecVDisplay完全指南

终极虚拟显示器解决方案&#xff1a;ParsecVDisplay完全指南 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd ParsecVDisplay是一款基于Parsec虚拟显示驱动&#xff08;VDD&#x…...

保姆级教程:在OBS Studio里开启H.264帧内刷新,解决录屏文件体积暴增问题

保姆级教程&#xff1a;在OBS Studio里开启H.264帧内刷新&#xff0c;解决录屏文件体积暴增问题 你是否遇到过这样的困扰&#xff1a;用OBS Studio录制静态界面&#xff08;比如文档、代码编辑器&#xff09;时&#xff0c;明明画面几乎没有变化&#xff0c;生成的视频文件却像…...

从零开始通过Taotoken平台文档快速完成首个大模型API调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 从零开始通过Taotoken平台文档快速完成首个大模型API调用 对于初次接触大模型API的开发者而言&#xff0c;面对众多模型厂商、复杂…...

Zabbix监控大屏展示中文总乱码?手把手教你替换DejaVuSans为微软雅黑字体

Zabbix监控大屏中文乱码终极解决方案&#xff1a;从字体替换到视觉优化 当你精心配置的Zabbix监控大屏在向管理层汇报时突然出现中文乱码&#xff0c;那种尴尬就像交响乐团演出时小提琴突然走音。作为经历过数十次企业级监控系统部署的资深运维&#xff0c;我深知字体问题远不止…...

GNN与MLIP:材料科学计算的高效新方法

1. GNN与MLIP&#xff1a;材料科学计算的新范式在材料科学领域&#xff0c;传统的第一性原理计算&#xff08;如密度泛函理论DFT&#xff09;虽然精度高&#xff0c;但计算成本极其昂贵&#xff0c;难以处理大体系或长时间尺度的模拟。图神经网络&#xff08;GNN&#xff09;与…...

Linux 下用火焰图进行性能分析

软件的性能分析&#xff0c;往往需要查看 CPU 耗时&#xff0c;了解瓶颈在哪里。火焰图 (flame graph) 是性能分析的利器。 1. 火焰图简介 很多人感冒发烧的时候&#xff0c;往往会模仿神农氏尝百草的路子&#xff1a;先尝尝抗病毒的药&#xff0c;再试试抗细菌的药&#xff…...

探索OpenBoardView:硬件工程师的PCB分析利器

探索OpenBoardView&#xff1a;硬件工程师的PCB分析利器 【免费下载链接】OpenBoardView View .brd files 项目地址: https://gitcode.com/gh_mirrors/op/OpenBoardView 在现代电子硬件开发与维修领域&#xff0c;面对复杂的电路板设计文件&#xff0c;工程师们常常需要…...