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 指南
“哲学家们只是用不同的方式解释世界,而问题在于改变世界。” ——卡尔马克思 (Karl Marx) 解读:马克思强调了实践的重要性,主张哲学不仅要理解世界,更要致力于改造世界。 本文我们引入 Mybatis Plus 作为 ORM ,并且使…...
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 组件,依赖 tooltip 组件;当 tooltip 的 trigger 的值不是 hover 时,会触发 close 事件;下拉框的 click 事件,触发了 tooltip 组件的 close 事件 总结一下&am…...
SQLI LABS | Less-37 POST-Bypass mysql_real_escape_string
关注这个靶场的其它相关笔记:SQLI LABS —— 靶场笔记合集-CSDN博客 0x01:过关流程 输入下面的链接进入靶场(如果你的地址和我不一样,按照你本地的环境来): http://localhost/sqli-labs/Less-37/ 是一个登…...
数字后端零基础入门系列 | Innovus零基础LAB学习Day9
Module 16 Wire Editing 这个章节的学习目标是学习如何在innovus中手工画线,切断一根线,换孔,更改一条net shape的layer和width等等。这个技能是每个数字IC后端工程师必须具备的。因为项目后期都需要这些技能来修复DRC和做一些手工custom走线…...
深度学习:GLUE(General Language Understanding Evaluation)详解
GLUE(General Language Understanding Evaluation)详解 GLUE(General Language Understanding Evaluation)是一个用于评估和比较自然语言理解(NLU)系统的综合基准测试。它包括了一系列的任务,旨…...
基于Multisim直流稳压电源电路±9V、±5V(含仿真和报告)
【全套资料.zip】直流稳压电源电路9V、5VMultisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 一般直流稳压电源都使用220伏市电作为电源,经过变压、整流、滤波后给稳压电路进行稳压…...
Vue Cli的配置中configureWebpack和chainWebpack的主要作用及区别是什么?
直接区别: configureWebpack项直接覆盖同名配置;chainWebpack项直接修改默认配置。 configureWebpack配置: // 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 ,ubuntu22.04,aarch64 ,cpu rk3588s targetubuntu22.04target-archaarch64target-cpurk3588s 安装 qemu-user-static 进入 …...
Python注意力机制Attention下CNN-LSTM-ARIMA混合模型预测中国银行股票价格|附数据代码...
全文链接:https://tecdat.cn/?p38195 股票市场在经济发展中占据重要地位。由于股票的高回报特性,股票市场吸引了越来越多机构和投资者的关注。然而,由于股票市场的复杂波动性,有时会给机构或投资者带来巨大损失。考虑到股票市场的…...
实验三 JDBC数据库操作编程(设计性)
实验三 JDBC数据库操作编程(设计性) 实验目的 掌握JDBC的数据库编程方法。掌握采用JDBC完成数据库链接、增删改查,以及操作封装的综合应用。实验要求 本实验要求每个同学单独完成;调试程序要记录调试过程中出现的问题及解决办法…...
各种环境换源教程
目录 pip 换源相关命令永久换源1. 命令行换源2. 配置文件换源 临时换源使用官方源使用镜像源 报错参考 npm换源相关命令永久换源1. 命令行换源2. 配置文件换源 pip 换源 相关命令 更新 pip 本身 首先,为了确保你使用的是最新版本的 pip,可以通过以下命…...
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的安装和使用
使用场景: 我们需要对某个接口进行压力测试,在多线程环境下,服务的抗压能力;还有就是关于分布式开发需要测试多线程环境下数据的唯一性。 解决方案: jmeter官网连接:Apache JMeter - Apache JMeter™ 下载安装包 配…...
初识Electron 进程通信
概述 Electron chromium nodejs native API,也就是将node环境和浏览器环境整合到了一起,这样就构成了桌面端(chromium负责渲染、node负责操作系统API等) 流程模型 预加载脚本:运行在浏览器环境下,但是…...
go语言中的通道(channel)详解
在 Go 语言中,通道(channel) 是一种用于在 goroutine(协程)之间传递数据的管道。通道具有类型安全性,即它只能传递一种指定类型的数据。通道是 Go 并发编程的重要特性,能够让多个 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 信息,表示临时响应并需要请求者继续执行操作 2xx 成功,操作被成功接收并处理 3xx 表示要完成请求,需要进一步操作。通常,这些状态码用来重定向 4xx 客户端错误,请求包含语法错误或无法完成请求 5xx 服务…...
代码训练营 day59|并查集
前言 这里记录一下陈菜菜的刷题记录,主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕,一年车企软件开发经验 代码能力:有待提高 常用语言:C 系列文章目录 第59天 :第十一章:图论part05 文章目录…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
