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

Apollo的Oracle适配改动

这几天工作需要使用Apollo配置中心。Apollo唯一的依赖是MySQL数据库,然而公司只有Oracle数据库资源。这里有一个Oracle适配改动的分支,但是它是基于0.8.0版本的Apollo。看着Apollo官方文档上各种特性都只有1.0.0以上版本才有,我决定基于当前最新版本(1.2.0)自己改一波。

基础

在开始改动前我们需要了解Apollo工程的整体结构,以及调试启动的方法。建议本地先搭建个MySQL库,然后把Apollo跑起来看看。官方对此有详细的文档。

另外,从MySQL到Oracle,一个比较大的问题是Apollo中很多表名、字段名和Oracle的关键字有冲突,导致无法在Oracle建表。这个问题可以使用双引号来解决。我们知道,Oracle的SQL语句在解释时会把所有的字符都转为大写(字符串常量除外),所以我们一般认为Oracle的SQL语法不区分大小写。比如说我可以用如下SQL建表:

create TaBle aPplicAtiOn(...);

最终我们会得到一张名为APPLICATION的表。在一些情况下,我们会需要区分大小写的表名,这时候我们可以在建表时用双引号将表名括起来:

create TaBle "aPplicAtiOn"(...);

这样,我们就真正得到了名为aPplicAtiOn的表了。同理,字段名、同名等Oracle对象也都可以用双引号来区分大小写。关于Oracle双引号,这里有更多的讲解。

Oracle适配改动

下面的改动大部分是参考已有的vanpersl/apollo基于0.8.0的Oracle版本的代码。这里是他的修改内容。

总体来说改动量不大。我大约花了一天的时间完成了整个改动。下面是改动步骤。

准备数据库用户

  • 准备两个Oracle用户(Oracle用户相当于MySQL的库),分别用于存放配置数据(假设这个用户叫ApolloConfig)和管理数据(假设这个用户叫ApolloPortal)。配置数据和管理数据有很多表名是相同的,所以必须使用两个用户。你也可以使用两个现有的用户,但是要注意不要和现有的表冲突了。
  • 使用Oracle的SQL脚本建表。这里是我整理后的两个SQL脚本,ApolloConfig用户执行apolloconfigdb.sql脚本,ApolloPortal用户执行apolloportaldb.sql脚本。

Apollo工程加入ojdbc的依赖

  • 我测试了ojdbc6和ojdbc7是可以使用的,而ojdbc12则会报版本太低的错误。我最后使用的ojdbc6,因为我最后测试的是ojdbc6就懒得再换了。
  • 另外,我在做这一步的时候发现使用Maven源的ojdbc包是无法启动项目的。只能到Oracle官网下载jar包,然后本地引用。ojdbc的依赖添加到parent项目和apollo-common项目。

修改数据库连接配置

  • 新建好Oracle的库后,将Apollo配置中原本MySQL的连接配置改为Oracle的连接配置——注意,根据你的部署方式,可能需要修改两处或者三处的连接配置。
spring.datasource.url=jdbc:oracle:thin:@{ip}:{port}:{db}
spring.datasource.username={ApolloConfig|ApolloPortal}
spring.datasource.password={password}

添加Oracle配置。

这些配置改动在apollo-commonapplication.properties配置文件。

  • 添加配置spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver指定使用Oracle驱动
  • 如果你的Oracle版本在11c以下(比如10g或者11g),那么还需要添加spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect。否则Hibernate会生成fetch first ? rows only之类的11c才支持的语句导致SQL执行错误。
  • 其他的连接池之类的配置。

Sequence

  • Apollo的表使用的自增ID作为主键。Oracle没有直接支持自增ID的功能,必须通过Sequence实现。在建表的SQL里已为两个库分别建了名为ID_SEQ的Sequence。代码中所有的Entity类的id属性都要加上GeneratedValueSequenceGenerator的配置。Apollo的代码中大部分的Entity类是继承自一个BaseEntity基类的,所以要修改的地方并不多。
    • 这几个类需要修改:BaseEntityReleaseMessageInstanceConfigInstanceUserPOConsumerAudit
    • 如下添加GeneratedValueSequenceGenerator两行:
    public abstract class BaseEntity {
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
      @SequenceGenerator(name = "sequence", sequenceName = "ID_SEQ", allocationSize = 1)
      @Column(name = "Id")
      private long id;
      ...
    }

Oracle关键字的问题

这部分的改动最多,也最枯燥。合理利用IDE的replace功能可以极大的提高修改效率。

  • 由于原本MySQL的表名列名用了很多Oracle的关键字,所以转到Oracle时所有的表名列名都用双引号括起来。可在apollo-commomapplication-properties配置中加上:
spring.jpa.hibernate.globally_quoted_identifiers=true
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

这样Hibernate的ORM生成SQL语句时就会自动给表名列名都加上双引号。

  • 另外,一些在注解里的类SQL语句用到的字段要手工加上双引号。大概有以下这些地方:
    • @SQLDelete和@Where的地方
    • AuthConfiguration.java中有一堆直接写SQL的
    • 所有的isDeleted和id都要改首字母大写
    • Namespace有个appId,Item有个key、value、comment,GreyReleaseRule有appId和releaseId
    • 其他我还没发现的犄角旮旯

成果

我最后修改的结果上传在这里:https://github.com/sKabYY/apollo。
目前已经平稳运行。后面如果有bug修改或者升级也会更新上去。

和原代码的对比可以看这里。

转载于:https://www.cnblogs.com/skabyy/p/10316720.html

相关文章:

  • 甄姬
  • Sql 排序
  • contest3 CF994 div2 ooxxx? oooox? ooooo?
  • 梯度下降算法对比(批量下降/随机下降/mini-batch)
  • Angular CLI的简单使用(2)
  • 最大团优化
  • 02-jQuery的选择器
  • Aria2 使用手札(简易部署 + 快速进阶)
  • 『The Captain 最短路建图优化』
  • 各种编码格式转换
  • Kali学习笔记40:SQL手工注入(2)
  • Ocelot 资源汇总
  • SSH端口号修改并进行远程访问
  • scrapy爬取知乎某个问题下的所有图片
  • string.intern
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • git 常用命令
  • Hibernate【inverse和cascade属性】知识要点
  • iOS 系统授权开发
  • Java|序列化异常StreamCorruptedException的解决方法
  • js ES6 求数组的交集,并集,还有差集
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • socket.io+express实现聊天室的思考(三)
  • use Google search engine
  • Zsh 开发指南(第十四篇 文件读写)
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 前端技术周刊 2019-02-11 Serverless
  • 实现简单的正则表达式引擎
  • 阿里云重庆大学大数据训练营落地分享
  • ​如何防止网络攻击?
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (4)(4.6) Triducer
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (Python第六天)文件处理
  • (循环依赖问题)学习spring的第九天
  • (转)Unity3DUnity3D在android下调试
  • ..回顾17,展望18
  • .NET 4.0中的泛型协变和反变
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET微信公众号开发-2.0创建自定义菜单
  • .Net小白的大学四年,内含面经
  • .NET性能优化(文摘)
  • .Net语言中的StringBuilder:入门到精通
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • :如何用SQL脚本保存存储过程返回的结果集