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

和原代碼的對比可以看這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM