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

mybatis-plus由mysql改成达梦数据库

前置条件: 达梦数据库设置了大小写敏感,我比较菜,改不动!先这么凑合着用吧;
因为设置了大小写敏感,所以所有的sql语句都要加 引号;

这样是会报错的:
SELECT  remark,createDept,createBy,createTime,updateBy,updateTime  FROM sys_oss_config这样才可以
SELECT  "create_dept", "create_by", "create_time","update_by", "update_time" FROM "sys_oss_config"

所以只需要将表名和字段名都加上引号就行了

第一步添加依赖

     <dependency><groupId>com.dameng</groupId><artifactId>Dm8JdbcDriver18</artifactId><version>8.1.1.49</version></dependency><!-- Druid 数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency>

配置文件修改

type: com.alibaba.druid.pool.DruidDataSource
driverClassName: dm.jdbc.driver.DmDriver
url: jdbc:dm://10.10.10.10:5236?schema=RY_VUE5&useUnicode=true&characterEncoding=utf8
username: SYSDBA
password: DmAdmin123

尤其要注意的是 库名 里面不能有横杠 类似这样"RY-VUE5",这就容易出问题;
指定库要用 schema=RY_VUE5

剩下的就在mybatis-plus配置类中添加两个拦截器
一个是针对所有sql ,添加引号 ,一个是对mybatisplus分页sql 改写的

import cn.hutool.core.net.NetUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.DdlApplicationRunner;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
import com.baomidou.mybatisplus.extension.ddl.IDdl;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.*;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 这俩拦截器要放前面interceptor.addInnerInterceptor(new QuoteAllSqlInterceptor());interceptor.addInnerInterceptor(new DmMultiLevelPaginationInterceptor());return interceptor;}public static class QuoteAllSqlInterceptor implements InnerInterceptor {// 表名匹配正则(不变)private static final Pattern TABLE_PATTERN = Pattern.compile("(FROM|JOIN)\\s+([a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)?)",Pattern.CASE_INSENSITIVE);// 优化字段匹配正则:解决末尾字段未被匹配的问题// 新增对SQL末尾字段的支持(允许字段后是空格、逗号或换行)private static final Pattern COLUMN_PATTERN = Pattern.compile("(?<!\\\")\\b([a-zA-Z0-9_]+)\\b(?!\\\")(?!\\s+[A-Za-z0-9_]*\\.)(?=\\s*[,)\\s]|\\s+AS|\\s+IN|\\s+LIKE)",Pattern.CASE_INSENSITIVE);private static final Pattern COLUMN_ALIAS = Pattern.compile("(FROM|JOIN)\\s+[\"`\\w\\.]+\\s+([a-zA-Z0-9_]+)",Pattern.CASE_INSENSITIVE);@Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter,RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {processSql(boundSql);}@Overridepublic void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {BoundSql boundSql = ms.getBoundSql(parameter);processSql(boundSql);}@Overridepublic void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {BoundSql boundSql = sh.getBoundSql();processSql(boundSql);}private void processSql(BoundSql boundSql) {PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);String originalSql = mpBs.sql();if (originalSql == null || originalSql.isEmpty()) {return;}// 先处理表名,再处理字段名String sqlWithTables = addQuotesToTables(originalSql);String sqlWithColumns = addQuotesToColumns(sqlWithTables);//  mp 强制更新SQL,确保所有字段被处理mpBs.sql(sqlWithColumns);}// 表名添加引号(不变)private String addQuotesToTables(String sql) {Matcher matcher = TABLE_PATTERN.matcher(sql);StringBuffer sb = new StringBuffer();while (matcher.find()) {String keyword = matcher.group(1);String tableName = matcher.group(2);if (tableName.contains(".")) {String[] parts = tableName.split("\\.");matcher.appendReplacement(sb, keyword + " \"" + parts[0] + "\".\"" + parts[1] + "\"");} else {matcher.appendReplacement(sb, keyword + " \"" + tableName + "\"");}}return matcher.appendTail(sb).toString();}// 字段名添加引号(重点优化)private String addQuotesToColumns(String sql) {Matcher matcher1 = COLUMN_ALIAS.matcher(sql);List<String> aliases = new ArrayList<>();while (matcher1.find()) {aliases.add(matcher1.group(2)); // 捕获组2为别名}Matcher matcher = COLUMN_PATTERN.matcher(sql);StringBuffer sb = new StringBuffer();while (matcher.find()) {String column = matcher.group(1);// 单独打印匹配到的字段,方便调试System.out.println("匹配到字段:" + column);if (isKeyword(column)) {matcher.appendReplacement(sb, column);} else {if (aliases.contains(column)) {System.out.println("别名不加引号:" + column);} else {matcher.appendReplacement(sb, "\"" + column + "\"");}}}String result = matcher.appendTail(sb).toString();// 打印处理后的SQL,确认是否添加引号System.out.println("处理后的SQL:" + result);return result;}// 完善关键字列表(确保不包含实际字段名)private boolean isKeyword(String word) {Set<String> keywords = new HashSet<>(Arrays.asList("SELECT", "FROM", "WHERE", "AND", "OR", "GROUP", "BY", "ORDER", "LIMIT","INSERT", "UPDATE", "DELETE", "SET", "VALUES", "AS", "JOIN", "ON", "NULL","DESC", "ASC", "IN", "LIKE", "BETWEEN", "IS", "NOT", "LEFT","INTO"));return keywords.contains(word.toUpperCase());}@Overridepublic boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {return true;}@Overridepublic boolean willDoUpdate(Executor executor, MappedStatement ms, Object parameter) {return true;}}/*** 达梦数据库分页拦截器(不依赖setPriority方法)*/public static class DmMultiLevelPaginationInterceptor extends PaginationInnerInterceptor {public DmMultiLevelPaginationInterceptor() {super(DbType.DM);}@Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter,RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {// 1. 获取分页参数IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);if (page == null || page.getSize() <= 0) {// 无分页参数时执行默认逻辑super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);return;}// 2. 手动构建无歧义的分页SQLString originalSql = boundSql.getSql();String paginationSql = buildMultiLevelPaginationSql(originalSql, page);// 3. 替换原始SQL(关键步骤)PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);mpBs.sql(paginationSql);// 4. 执行父类逻辑,但禁用其分页处理(使用RowBounds.DEFAULT)super.beforeQuery(executor, ms, parameter, RowBounds.DEFAULT, resultHandler, boundSql);}/*** 构建仅两层嵌套的分页SQL,彻底避免ROW_ID重复*/private String buildMultiLevelPaginationSql(String originalSql, IPage<?> page) {long current = page.getCurrent();long size = page.getSize();long offset = (current - 1) * size;// 清除原始SQL中的分号和多余空格originalSql = originalSql.replaceAll(";|\\s+", " ").trim();// 达梦分页核心:仅用两层嵌套,别名绝对唯一return String.format("SELECT * FROM (" +"  SELECT TMP.*, ROWNUM AS RN2 FROM (" +"    SELECT TMP.*, ROWNUM AS RN1 FROM (" +"      %s" +  // 原始查询"    ) TMP WHERE ROWNUM <= %d" +  // 总条数限制:当前页末尾"  ) TMP WHERE RN1 > %d" +       // 偏移量:跳过前几页"  ORDER BY RN1" +               // 保证排序一致性") TMP WHERE ROWNUM <= %d",      // 每页条数限制originalSql, current * size, offset, size);}}
}
http://www.dtcms.com/a/305239.html

相关文章:

  • 【Linux】重生之从零开始学习运维之Mysql事务
  • Python day28
  • 破解企业无公网 IP 难题:可行路径与实现方法?
  • Three.js 渲染优化处理
  • 【C++算法】74.优先级队列_最后一块石头的重量
  • 查找特定的值
  • zama test
  • BGP团体属性
  • Linux部署各类软件
  • 《剑指offer》-算法篇-位运算
  • 【深度学习新浪潮】什么是世界模型?
  • 洛谷 P9779 [HUSTFC 2023] 不定项选择题
  • 记一次导出pdf表单引发的问题
  • Linux救援模式之简介篇
  • 文件相关问题(AI回答)
  • 【从0开始学习Java | 第5篇】封装
  • 85、【OS】【Nuttx】【番外】gcc 关键字:位域(上)
  • 影翎Antigravity将发布全球首款全景无人机,8月开启公测招募
  • Leetcode 08 java
  • Linux | 文件权限
  • 面试刷题平台项目总结
  • ERROR c.a.c.n.c.NacosPropertySourceBuilder
  • 对讲机该怎么选?2025建议买的对讲机品牌
  • 并查集介绍及典型应用和编程题
  • 专线与专线之间的区别
  • Docker初学者需要了解的几个知识点(二):Docker、容器镜像
  • 2025年运维相关面试题
  • 前端手写贴
  • 北方公司面试记录
  • A1324LLHLX-T Allegro:高精度线性霍尔效应传感器 ±1%精度+4.5mV/G超高灵敏度