天天看點

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建表:

最終我們會得到一張名為<code>APPLICATION</code>的表。在一些情況下,我們會需要區分大小寫的表名,這時候我們可以在建表時用雙引号将表名括起來:

這樣,我們就真正得到了名為<code>aPplicAtiOn</code>的表了。同理,字段名、同名等Oracle對象也都可以用雙引号來區分大小寫。關于Oracle雙引号,這裡有更多的講解。

下面的改動大部分是參考已有的<code>vanpersl/apollo</code>基于0.8.0的Oracle版本的代碼。這裡是他的修改内容。

總體來說改動量不大。我大約花了一天的時間完成了整個改動。下面是改動步驟。

準備兩個Oracle使用者(Oracle使用者相當于MySQL的庫),分别用于存放配置資料(假設這個使用者叫ApolloConfig)和管理資料(假設這個使用者叫ApolloPortal)。配置資料和管理資料有很多表名是相同的,是以必須使用兩個使用者。你也可以使用兩個現有的使用者,但是要注意不要和現有的表沖突了。

使用Oracle的SQL腳本建表。這裡是我整理後的兩個SQL腳本,ApolloConfig使用者執行apolloconfigdb.sql腳本,ApolloPortal使用者執行apolloportaldb.sql腳本。

我測試了ojdbc6和ojdbc7是可以使用的,而ojdbc12則會報版本太低的錯誤。我最後使用的ojdbc6,因為我最後測試的是ojdbc6就懶得再換了。

另外,我在做這一步的時候發現使用Maven源的ojdbc包是無法啟動項目的。隻能到Oracle官網下載下傳jar包,然後本地引用。ojdbc的依賴添加到parent項目和apollo-common項目。

建立好Oracle的庫後,将Apollo配置中原本MySQL的連接配接配置改為Oracle的連接配接配置——注意,根據你的部署方式,可能需要修改兩處或者三處的連接配接配置。

這些配置改動在<code>apollo-common</code>的<code>application.properties</code>配置檔案。

添加配置<code>spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver</code>指定使用Oracle驅動

如果你的Oracle版本在11c以下(比如10g或者11g),那麼還需要添加<code>spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect</code>。否則Hibernate會生成<code>fetch first ? rows only</code>之類的11c才支援的語句導緻SQL執行錯誤。

其他的連接配接池之類的配置。

Apollo的表使用的自增ID作為主鍵。Oracle沒有直接支援自增ID的功能,必須通過Sequence實作。在建表的SQL裡已為兩個庫分别建了名為<code>ID_SEQ</code>的Sequence。代碼中所有的Entity類的<code>id</code>屬性都要加上<code>GeneratedValue</code>和<code>SequenceGenerator</code>的配置。Apollo的代碼中大部分的Entity類是繼承自一個<code>BaseEntity</code>基類的,是以要修改的地方并不多。

這幾個類需要修改:<code>BaseEntity</code>、<code>ReleaseMessage</code>、<code>InstanceConfig</code>、<code>Instance</code>、<code>UserPO</code>、<code>ConsumerAudit</code>

如下添加<code>GeneratedValue</code>和<code>SequenceGenerator</code>兩行:

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

由于原本MySQL的表名列名用了很多Oracle的關鍵字,是以轉到Oracle時所有的表名列名都用雙引号括起來。可在<code>apollo-commom</code>的<code>application-properties</code>配置中加上:

這樣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修改或者更新也會更新上去。

和原代碼的對比可以看這裡。