都說(shuō)Hibernate框架的使用可以很容易的讓你的研發(fā)平臺(tái)支持多種不同類型的數(shù)據(jù)庫(kù),但實(shí)踐表明,這里的容易,是相對(duì)的。 想讓研發(fā)平臺(tái)支持多種數(shù)據(jù)庫(kù),并不是一件簡(jiǎn)單的事,也可以這么說(shuō):并不是只要使用了Hibernate框架就能實(shí)現(xiàn)的。 下面記錄一下我做這件事情
都說(shuō)Hibernate框架的使用可以很容易的讓你的研發(fā)平臺(tái)支持多種不同類型的數(shù)據(jù)庫(kù),但實(shí)踐表明,這里的“容易”,是相對(duì)的。
想讓研發(fā)平臺(tái)支持多種數(shù)據(jù)庫(kù),并不是一件簡(jiǎn)單的事,也可以這么說(shuō):并不是只要使用了Hibernate框架就能實(shí)現(xiàn)的。
下面記錄一下我做這件事情的過(guò)程和一些感悟。
當(dāng)我接到該任務(wù)時(shí),我先大致的理了一下思路:
要完成遷移,總體上有2大塊工作要做,分別是:數(shù)據(jù)庫(kù)層面的遷移 和 平臺(tái)底層代碼的改造
一、數(shù)據(jù)庫(kù)層面的遷移過(guò)程:
1、通過(guò)sqlServer Studio2008 工具將數(shù)據(jù)從Oracle導(dǎo)入到SqlServer數(shù)據(jù)庫(kù)
從SSMS2008開始才支持此功能,具體操作步驟(右鍵點(diǎn)擊數(shù)據(jù)庫(kù)-選擇導(dǎo)入-點(diǎn)下一步-選擇 Oracle Provider for OLE DB 數(shù)據(jù)源-點(diǎn)擊屬性-填寫數(shù)據(jù)源,格式為 IP:端口/實(shí)例名),后面的步驟根據(jù)向?qū)б徊讲降牟僮骷纯?。需要注意的是?選擇源表和源視圖的步驟中:
?。?)、要把【目標(biāo)】列中的默認(rèn)前綴去掉,這樣導(dǎo)入的表才會(huì)默認(rèn)關(guān)聯(lián)到dbo下,否則你每次查詢表都要帶上schema前綴,導(dǎo)致你之前的應(yīng)用程序中的sql無(wú)法執(zhí)行,因?yàn)槟阒皩懙哪切﹕ql肯定不會(huì)帶這種前綴。
?。?)、先勾選你要導(dǎo)入的源,然后雙擊每一行記錄,在彈出的對(duì)話框中檢查是否所有的類型都正確綁定好了,我在檢查的時(shí)候就遇到了oracle中是varchar2類型的,在該對(duì)話框顯示的表結(jié)構(gòu)中變成了130,只能手動(dòng)的去將所有130改成varchar類型(sqlserver里沒有varchar2類型)。還有原來(lái)是clob類型的,現(xiàn)在變成了varchar,要手動(dòng)改成text類型(因?yàn)閏lob類型的字段比較少,所以可以通過(guò)在oracle中執(zhí)行“select * from user_tab_columns c where c.data_type='CLOB';”來(lái)查看哪些表中用到了CLOB類型的字段)。
2、增加to_date、to_char、to_number、concat等常用的函數(shù)
說(shuō)明:我在編寫to_date函數(shù)的時(shí)候,只提供了一種格式“yyyy-mm-dd HH:mi:ss”,這是因?yàn)樵趕qlserver中是沒有和to_date函數(shù)的類似的函數(shù)的,只能使用convert函數(shù)實(shí)現(xiàn),但是convert函數(shù)不支持傳入格式化字符串,只能傳入格式字符對(duì)應(yīng)的整型數(shù)字,而120對(duì)應(yīng)的正是之前提到的“yyyy-mm-dd HH:mi:ss”格式;另外此次是遷移到Sqlserver2005,該版本是沒有內(nèi)嵌concat函數(shù)的,根據(jù)官方文檔的說(shuō)法,是從sqlServer2012開始才有concat函數(shù)的,所以這里我要自己編寫一個(gè)concat函數(shù)。
------------------------------------------------------------------concat函數(shù) USE [skyplatform] GO /****** Object: UserDefinedFunction [dbo].[concat] Script Date: 03/10/2015 17:11:31 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[concat] ( @param1 varchar(500), @param2 varchar(500) ) returns varchar(1000) as begin DECLARE @returntext varchar(1000) if (@param1 is null) SELECT @returntext= @param2; else if (@param2 is null) SELECT @returntext= @param1; else SELECT @returntext= @param1 + @param2; return @returntext; end --------------------------------------------------------------------to_char函數(shù) USE [skyplatform] GO /****** Object: UserDefinedFunction [dbo].[to_char] Script Date: 03/10/2015 17:12:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[to_char] ( @param1 datetime, @param2 varchar(20) ) returns varchar(20) as begin return convert(varchar(20),@param1,120) end --------------------------------------------------------------------to_date函數(shù) USE [skyplatform] GO /****** Object: UserDefinedFunction [dbo].[to_date] Script Date: 03/10/2015 17:12:58 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[to_date] ( @param1 varchar(20), @param2 varchar(20) ) returns datetime as begin return convert(datetime,@param1,120)--120 means that yyyy-mm-dd hh:mi:ss(24h) end --------------------------------------------------------------------to_number函數(shù) USE [skyplatform] GO /****** Object: UserDefinedFunction [dbo].[to_number] Script Date: 03/10/2015 17:13:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[to_number] ( @param1 varchar ) returns numeric as begin return convert(numeric,@param1) end
二、平臺(tái)底層代碼的改造
1、引入SqlServer的jar包:sqljdbc4-4.0.jar
com.microsoft.sqlserver sqljdbc4 4.0
2、修改db.properties中關(guān)于數(shù)據(jù)庫(kù)連接信息的配置
jdbc.dialect=org.hibernate.dialect.SQLServerDialect jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc.url=jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=xxx jdbc.default_schema=dbo jdbc.username=xxx jdbc.password=xxx
3、修改平臺(tái)中使用的一些非sql標(biāo)準(zhǔn)的語(yǔ)法
在使用delete insert update這些dml語(yǔ)句的時(shí)候,切記不要使用別名,因?yàn)樵趏racle和sqlserver中,這些dml語(yǔ)句使用別名的語(yǔ)法是不一樣的。
4、各實(shí)體類主鍵策略的改造
最好都使用string類型的主鍵,但是因?yàn)橹暗拇a中都用的sequence做主鍵策略,現(xiàn)在改成string類型工作量勢(shì)必很大,所以決定使用table策略來(lái)兼容各種數(shù)據(jù)庫(kù)。
5、dao層對(duì)sql的處理
由于sqlserver中調(diào)用自定義標(biāo)量值函數(shù),必須在函數(shù)名前加上dbo.的前綴,但是這樣寫勢(shì)必會(huì)導(dǎo)致不能兼容其它的關(guān)系型數(shù)據(jù)庫(kù),所以只能從dao實(shí)現(xiàn)層,對(duì)sql進(jìn)行統(tǒng)一的處理,處理規(guī)則就是:如果當(dāng)前數(shù)據(jù)庫(kù)是sqlserver,并且sql中出現(xiàn)了concat、to_date、to_char、to_number等函數(shù),就為這些函數(shù)名加上dbo.的前綴。
以上做完,基本就可以讓平臺(tái)在sqlserver數(shù)據(jù)庫(kù)上跑了,同時(shí)也可以通過(guò)改配置文件切換到Oracle數(shù)據(jù)庫(kù)。
以上的做法可能并不是最優(yōu)的方式,如果有更好的方案,希望各位大牛能給予指點(diǎn)。
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com