文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

系统mysql、sqlserver数据库兼容方案

2023-09-14 09:59

关注

一、技术选型

springboot2.4+、mybatisplus3.4+、mysql5.7+、redis3.0+

二、编写目的

如果产品开发默认数据库采用mysql,但是当客户提出数据库需要采用Sqlserver或者Oracle以及其他国产数据库时,程序中就不能出现方言性的sql语句,否则程序在个性化的sql上做不到数据库兼容,因此要想产品能兼容多种数据类型,则在编码时就要考虑将个性化的方言sql抽离出来。

三、数据库兼容方案

实现思路:
(1)应用启动时要根据数据源知道当前链接的数据库类型,并存到全局变量
(2)根据数据库类型自动设置mybatis-plus分页方言
(3)个性化方言实现不要在主业务中耦合(如:if mysql … else if sqlserver…)
(4)个性化方言实现可以多种数据库类型复用(如mysql、mariadb可以用一种实现)
(5)个性化方言实现类能根据数据库类型自动注入
代码实现:
根据url获取数据库类型

import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;public class Dialect {    private static DbType dbType = null;    private static final String DB_URL = "spring.datasource.url";        public synchronized static DbType getDbType(){        if(dbType == null){            String url = PropUtil.getValue(DB_URL);            dbType = JdbcUtils.getDbType(url);        }        return dbType;    }}

自定义注解(实现方言实现的选择注入)

import com.baomidou.mybatisplus.annotation.DbType;import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE, ElementType.METHOD })@Documented@Conditional(DbTypeCondition.class)public @interface ConditionalOnDbType {        DbType[] types() default DbType.OTHER;}

注解条件实现

import com.baomidou.mybatisplus.annotation.DbType;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.type.AnnotatedTypeMetadata;public class DbTypeCondition implements Condition {    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        DbType[] dbTypes = (DbType[]) metadata.getAnnotationAttributes(ConditionalOnDbType.class.getName()).get("types");        for(DbType dbType : dbTypes){            if(Dialect.getDbType().equals(dbType)){                return true;            }        }        return false;    }}

1、mybatisplus配置

分页方言配置

@Configurationpublic class MybatisPlusConfig {    @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor() {        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();        //添加分页插件        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(Dialect.getDbType()));        return interceptor;    }}

2、数据库YAML配置

数据源配置上注意驱动和URL的替换。

mysql配置

spring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    url: jdbc:mysql://ip:3306/db?serverTimezone=Asia/Shanghai&useUnicode=true    username: username    password: password    hikari:      ## 最小空闲连接数      minimum-idle: 5      ## 最大连接数      maximum-pool-size: 20      ## 自动提交      auto-commit: true      ## 连接池名称      pool-name: TmcHikariCP      ## 超时时间(ms)      connection-timeout: 30000

sqlserver配置

spring:  datasource:    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver    url: jdbc:sqlserver://ip:1433;databasename=db_schema;trustServerCertificate=true;integratedSecurity=false;    username: username    password: password    hikari:      ## 最小空闲连接数      minimum-idle: 5      ## 最大连接数      maximum-pool-size: 20      ## 自动提交      auto-commit: true      ## 连接池名称      pool-name: TmcHikariCP      ## 超时时间(ms)      connection-timeout: 30000 

3、应用举例

方言抽离接口

public interface DialectService<T> {        void conditon(QueryWrapper<T> queryWrapper, Map<String, Clazz> attrMap,Object k,Object v);}

Mysql方言实现

import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service;import java.util.Map;@Slf4j@Service@ConditionalOnDbType(types = {DbType.MYSQL,DbType.MARIADB})public class MysqlFormDataDialectServiceImpl implements FormDataDialectService<FormDataEntity> {    @Override    public void conditon(QueryWrapper<FormDataEntity> queryWrapper, Map<String, Clazz> attrMap, Object k, Object v) {        try {            //替换时间类型判断(时间查询为时间段)            Clazz.Format format = attrMap.get(k).getFormat();            if(Clazz.Format.DateTime.equals(format) || Clazz.Format.Date.equals(format)){                String[] dateArray = ObjectMapperHelper.mapper().readValue(v.toString(), String[].class);                queryWrapper.ge("attr_json->'$." + k + "'", dateArray[0]);                queryWrapper.lt("attr_json->'$." + k + "'", dateArray[1]);            }else {                queryWrapper.eq("attr_json->'$." + k + "'", v);            }        }catch (Exception e){            log.error("form data query k:{},v:{} error:{}",k,v,e.getMessage());        }    }}

Sqlserver方言实现

import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service;import java.util.Map;@Slf4j@Service@ConditionalOnDbType(types = {DbType.SQL_SERVER2005,DbType.SQL_SERVER})public class SqlServerFormDataDialectServiceImpl implements FormDataDialectService<FormDataEntity> {    @Override    public void conditon(QueryWrapper<FormDataEntity> queryWrapper, Map<String, Clazz> attrMap, Object k, Object v) {        try {            //替换时间类型判断(时间查询为时间段)            Clazz.Format format = attrMap.get(k).getFormat();            if(Clazz.Format.DateTime.equals(format) || Clazz.Format.Date.equals(format)){                String[] dateArray = ObjectMapperHelper.mapper().readValue(v.toString(), String[].class);                queryWrapper.ge("JSON_VALUE(attr_json, '$." + k + "')", dateArray[0]);                queryWrapper.lt("JSON_VALUE(attr_json, '$." + k + "')", dateArray[1]);            }else {                queryWrapper.eq("JSON_VALUE(attr_json, '$." + k + "')", v);            }        }catch (Exception e){            log.error("form data query k:{},v:{} error:{}",k,v,e.getMessage());        }    }}

4、数据库脚本转换

最后注意数据库脚本从mysql到sqlserver的转换,可以用微软的工具Microsoft SQL Server Migration Assistant for MySQL
可参照官网实现。
下载链接:https://www.microsoft.com/en-us/download/details.aspx?id=54257&6B49FDFB-8E5B-4B07-BC31-15695C5A2143=1

来源地址:https://blog.csdn.net/little_pig_lxl/article/details/130485475

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯