Oracle數據庫歷來以價格昂貴出名,當然貴有貴的道理,成為一個Oracle DBA也是令人羨慕的事情,如果程序員熟悉Oracle使用也有機會接觸到大型的項目,但是Oracle似乎對一般程序員不怎麼友好,因為其繁瑣的安裝配置過程和對系統硬件的苛求,另一般人望而止步,我最早從Oracle 9i開始接觸它,深有感受,特別是熟悉了SqlServer的開發人員,初次接觸Oracle還是很不習慣的。比如它沒有SqlServer數據“庫”的概念,一個sa賬號管理很多數據庫,在Oracle裡面,它叫做“數據服務”,通過不同的數據庫用戶來區分數據。
現在,Oracle推出了一個免費的數據庫產品,Database 快捷版 11g ,這個就像SqlServer Express版本一樣,都是免費的,與收費版在功能沒有任何區別,但是有些使用條件限制,比如僅支持一個CPU,數據文件組大小有限制等,但是一般中小企業的一些中小應用還是夠了。Database 快捷版 11g下載地址請點擊這裡。不過下載之前要先注冊Oracle賬號,並同意下載許可聲明。
適用於 Windows x64 的 Oracle Database 快捷版 11g 第 2 版 - 解壓縮下載文件,然後運行 DISK1/setup.exe 適用於 Windows x32 的 Oracle Database 快捷版 11g 第 2 版 - 解壓縮下載文件,然後運行 DISK1/setup.exe
適用於 Linux x64 的 Oracle Database 快捷版 11g 第 2 版 - 解壓縮下載文件,可以像往常一樣安裝 RPM 文件
根據你的情況,選擇下載32位的或者64位的,我下載了64位的,安裝很簡單,中途沒有什麼特別注意的地方,一路“下一步” 即可,這比起Oracle其他版本的數據庫安裝來說,實在很簡單,安裝完成後,即可使用了,不過千萬記住不要忘記了Sys,System 用戶的密碼。安裝完成之後,在桌面會有一個快捷方式:Oracle Database 11g Express Edition 入門 ,單擊,進入Web的管理界面:
如果要查看其它界面,需要輸入管理員密碼,比如查看存儲的界面:
如果要進行創建數據庫用戶,建表等操作,還得啟動SQL plus 程序,不用做額外的配置,可以直接啟動,這相比收費版,又簡單了不少:
具體創建用戶,創建表的工作,可以使用Oracle的SQL語句來做,但我們這裡通過另外一個工具來做,還是在之前的Oracle XE 下載頁面:
Oracle SQL Developer Oracle SQL Developer Data Modeler Oracle Application Express 針對 Java 開發人員的 JDeveloper Oracle Developer Tools for Visual Studio .NET Zend Server到這裡下載一個最新版本的Oracle VS插件,有好幾個版本,下載最上面的就好了,不過下載一樣需要Oracle用戶賬號。
安裝這個插件的時候,注意安裝提示,首先管理員賬號Sys和密碼,然後是要連接的Oracle服務名,輸入相關的服務名,這裡默認是 XE,然後保存為一個TNS名字,我用的是mydb,最後還有一個ODP.Net的安裝,詢問是否安裝程序集到GAC,這裡選擇安裝。
安裝好後,在VS的“服務器資源管理器”--》“數據連接”,新建一個連接:
在圖例中,我們選擇以SysDba的角色進行登錄,之後,就可以創建用戶,查詢表和編輯數據了,很方便,這裡我建立了一個名字為SOD的用戶,然後用這個用戶登錄:
功能很多,具體內容留給大家去研究了。不過從這裡添加的用戶不太方便設置成DBA角色,還是用命令行來設置。
至此,Oracle XE 的數據服務和開發工具插件,基本上安裝好了。
不過,我們也可以使用SOD框架的集成開發工具來連接,該工具連接過程如下:
最後點擊確定,回到下面的界面,展開XE數據庫,選擇數據表,右鍵菜單查詢數據:
至此,Oracle 的安裝,連接過程就完成了,很簡單。
SOD框架是PDF.NET開發框架的數據框架,目前已經支持了SqlServer,SqlServerCe,Access,MySQL,PostgreSQL等主流數據庫的Code First,但 PDF.NET_SOD Ver 5.2.1.0307 還未實現Oracle的Code First支持,主要原因是我對 Oracle 目前使用較少,如果不是SOD會員用戶的強烈要求,可能SOD對Oracle Code First支持還要往後推延一段時間。
實際上SOD框架對Oracle Code First的支持並不復雜,主要需要解決的問題就是Oracle數據庫自增字段的處理,大部分情況下,這都是通過觸發器來實現的。
改寫下 EntityCommand 類的創建表的方法,添加Oracle的處理:
public string CreateTableCommand { get { if (_createTableCommand == null) { string script = @" CREATE TABLE @TABLENAME( @FIELDS ) "; if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.PostgreSQL && !string.IsNullOrEmpty(currEntity.IdentityName)) { string seq = "CREATE SEQUENCE " + currEntity.TableName + "_" + currEntity.IdentityName + "_" + "seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;"; script = seq + script; } else if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle && !string.IsNullOrEmpty(currEntity.IdentityName)) { // --; 語句分割符號 string seqTemp = @" CREATE SEQUENCE @TableName_@IDName_SEQ MINVALUE 1 NOMAXVALUE INCREMENT BY 1 START WITH 1 NOCACHE ;-- CREATE OR REPLACE TRIGGER @TableName_INS_TRG BEFORE INSERT ON [@TableName] FOR EACH ROW WHEN(new.[@IDName] IS NULL) BEGIN SELECT @TableName_@IDName_SEQ.NEXTVAL INTO :new.[@IDName] FROM DUAL; END; ;-- "; script = script + ";--\r\n" + seqTemp.Replace("@TableName", currEntity.TableName).Replace("@IDName", currEntity.IdentityName); } var entityFields = EntityFieldsCache.Item(this.currEntity.GetType()); string fieldsText = ""; foreach (string field in this.currEntity.PropertyNames) { string columnScript =entityFields.CreateTableColumnScript(this.currDb as AdoHelper, this.currEntity, field); fieldsText = fieldsText + "," + columnScript+"\r\n"; } string tableName =this.currDb.GetPreparedSQL("["+ currTableName+"]"); _createTableCommand = script.Replace("@TABLENAME", tableName).Replace("@FIELDS", fieldsText.Substring(1)); } return _createTableCommand; } }
由於Oracle 數據庫的字段類型名稱,對應DbType的名字並不完全相符,所以需要對AdoHelper類的Oracle實現類稍加修改:
public class Oracle : AdoHelper { //其它略 public override string GetNativeDbTypeName(IDataParameter para) { OracleParameter oraPara = (OracleParameter)para; OracleType oraType = oraPara.OracleType; if (oraType == OracleType.DateTime) return "Date"; else if (oraType == OracleType.Int32) return "INT"; else return oraType.ToString(); } }
能夠根據實體類,得到生成表的建表腳本,任務已經完成了一半,不過SOD提供了一個DbContext類的封裝,可以自動完成這個過程,下面就來實現一個Oracle的DbContext:
namespace PWMIS.Core.Extensions { public abstract class OracleDbContext :DbContext { /// <summary> /// 用連接字符串名字初始化本類 /// </summary> /// <param name="connName"></param> public OracleDbContext(string connName) : base(connName) { } /// <summary> /// 檢查實體類對應的數據表是否在數據庫中存在 /// </summary> protected override void CheckTableExists<T>() { //創建表 if (CurrentDataBase.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle) { var entity = new T(); var dsScheme = CurrentDataBase.GetSchema("Tables", null); string owner = CurrentDataBase.ConnectionUserID; var rows = dsScheme.Select("OWNER='"+ owner +"' and table_name='" + entity.GetTableName() + "'"); if (rows.Length == 0) { EntityCommand ecmd = new EntityCommand(entity, CurrentDataBase); string sql = ecmd.CreateTableCommand; //OracleClient 不能批量執行多條SQL語句 string[] sqlArr = sql.Split(new string[] {";--" }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in sqlArr) { if(item.Length >10) //去除回車行 CurrentDataBase.ExecuteNonQuery(item); } } } } } }
將SOD框架源碼的 SampleORMTest 測試項目的SqlServerDbContext 改成OracleDbContext的:
namespace SampleORMTest { /// <summary> /// 用來測試的本地SqlServer 數據庫上下文類 /// </summary> public class LocalDbContext : OracleDbContext // SqlServerDbContext { public LocalDbContext() : base("local") { //local 是連接字符串名字 } #region 父類抽象方法的實現 protected override bool CheckAllTableExists() { //創建用戶表 CheckTableExists<User>(); return true; } #endregion } }
只需要在OracleDbContext 實現類的CheckAllTableExists 方法內,實現各個實體類的表創建工作即可,比如本例創建用戶表。
修改下App.config 文件的連接配置:
<connectionStrings> <!--<add name="local" connectionString="Data Source=.;Initial Catalog=LocalDB;Integrated Security=True" providerName="SqlServer" />--> <!--下面的配置適應於 Oracle.Client--> <add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123;Integrated Security=no;" providerName="Oracle" /> </connectionStrings>
在本文中,已經說到安裝了Oracle 的.net數據訪問組件ODP.Net,MS也建議用這個組件來代替MS自己的Oracle.Client,下面,我們只需要新建立一個項目,引用下ODP.Net組件即可:
把SOD框架的核心程序集PWMIS.Core 的Oracle.cs 文件拷貝下來,只需要修改下命名空間即可使用。
編譯這個項目,讓SampleORMTest 測試項目引用它,或者直接拷貝DLL到測試項目,
重新修改下App.config文件的連接配置:
<add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123" providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />
運行項目,首先拋出下面這樣一個異常:
其他信息: 未能加載文件或程序集“Oracle.DataAccess, Version=2.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342”或它的某一個依賴項。試圖加載格式不正確的程序。
第一反應,應該是32位於6位程序不兼容的問題,仔細回想下,這可能是 Oracle VS插件安裝時候安裝到GAC裡面的程序集。於是將測試程序修改成32位的(編譯目標為x86),運行良久,再次報錯,說TNS無法解析。
奇怪,使用MS Oracle Client都沒有問題,為何用了ODP.Net缺不行了呢?百度了下,但覺得別人說的跟我當前不太一樣。
檢查Oracle的VS插件程序的安裝目錄,在 E:\app\client\dth\product\12.1.0\client_1\Network\Admin 目錄中發現TSN配置文件 tnsnames.ora ,打開,原來是這樣的內容:
mydb = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE) ) )
分析內容,這應該是安裝VS插件的時候,配置生成的。 那麼原來的XE服務的監聽名字是怎麼來的? 在搜索下Oracle服務的安裝目錄,在 E:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN 下面找到了 tnsnames.ora 文件,打開:
XE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dth-home)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE) ) ) EXTPROC_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) ) (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO) ) ) ORACLR_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) ) (CONNECT_DATA = (SID = CLRExtProc) (PRESENTATION = RO) ) )
原來默認的Oracle XE 監聽服務名是這樣定義的。
重新配置連接,將服務名從XE更改為mydb,順利通過。
<add name="local" connectionString="Data Source=mydb;User Id=SOD;Password=sod123" providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />
如果不配置mydb這個TNS名字,可否直接使用呢?答案是可以,只需要將連接字符串做如下修改即可:
<add name="local" connectionString="Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE) ) );User Id=SOD;Password=sod123" providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />
測試運行,成功,可惜目前為止,還是基於32位的ODP.Net做的測試。
回憶之前安裝XE數據庫服務,確認當時安裝的是64位的數據庫,那麼去它的安裝目錄,看看有沒有ODP,一看,果然有:
E:\oraclexe\app\oracle\product\11.2.0\server\odp.net\bin\2.x
這裡的 Oracle.DataAccess.dll 是64位的。
將它拷貝到SOD框架下面,再運行,終於看到了成功界面:
前面使用ODP.Net的過程,都是在本地機器安裝了Oracle XE數據庫和Oracle VS 開發插件的情況下進行的,但是,如果把訪問Oracle的程序部署到一台沒有裝過Oracle程序的機器上,程序是無法使用的,這還得做下Oracle 環境的部署,過程如下:
打開下面的鏈接:
http://www.oracle.com/technetwork/topics/dotnet/downloads/index-2235287.html?ssSourceSiteId=otncn
這裡提供了2種下載安裝方式,前一種,Oracle Universal Installer 安裝包比較大,略過,我們選擇第二種,XCopy方式來部署。
根據你的需要,下載32位或者 64位的ODAC,並且下載 ODP.Net ,Managed Driver.
比如我下載的是 64位的ODAC,以管理員權限啟動命令行,
第一步,輸入下面的命令:
install.bat all c:\oracle odac
這裡表示將Oracle客戶端程序復制到 c:\oracle 目錄下面
第二步,安裝ODP.Net,輸入下面的命令:
install_odpm.bat c:\oracle x64 true
注意:c:\oracle 目錄是第一步命令裡面指定的路徑。
第三步,關鍵,在系統環境變量裡面,Path變量裡面,包含Oracle程序的路徑:
c:\oracle;c:\oracle\bin;
這樣設置以後,本文的Oracle訪問程序,就可以正常運行了。
當前程序的全部代碼已經簽入SOD框架的開源項目,地址 http://pwmis.codeplex.com ,你在源碼欄目可以查看到當前最新的更改,如果你有codeplex賬號,可以直接連接TFS下載,如果沒有,可以用SVN下載,獨立下載包,
打造最輕,最方便而又靈活的數據開發框架,感謝你的支持!
歡迎加入SOD開發者團隊,更多詳細信息,請看框架官網 http://www.pwmis.com/sqlmap