施國榮
(國核自儀系統(tǒng)工程有限公司,上海 200241)
核電儀控系統(tǒng)為核電廠提供了各種控制和保護手段以及監(jiān)控信息,保證了核電廠在正常啟動、停堆、異常和事故工況下能夠安全、可靠、有效地運行。由于核電儀控系統(tǒng)涉及的系統(tǒng)多、工藝復(fù)雜、控制設(shè)備多,導(dǎo)致控制和測量點的數(shù)量龐大。目前,示范項目首堆包括10 個儀控子系統(tǒng),技術(shù)接口61 個,測量信號約2 萬個,每個子系統(tǒng)由5 人共同協(xié)作設(shè)計。隨著項目數(shù)量增多,設(shè)計輸入和接口數(shù)據(jù)成倍增加,各項目之間的輸入和接口數(shù)據(jù)既有聯(lián)系又有區(qū)別,在各項目工程任務(wù)并行開展的情況下,設(shè)計人員會產(chǎn)生質(zhì)量問題。儀控系統(tǒng)設(shè)計團隊除了面臨上述問題外,設(shè)計過程受供貨商以及電廠現(xiàn)場變化影響大,各種數(shù)據(jù)、圖紙修改量極大(示范項目目前設(shè)計變更數(shù)量約320 個),因此可能出現(xiàn)質(zhì)量事故的概率也會增加。目前已實現(xiàn)自動化辦公,但所使用的軟件功能有限,不能很好地與目前核電儀控系統(tǒng)設(shè)計工作結(jié)合,設(shè)計人員在應(yīng)用時需要做大量的非技術(shù)性基礎(chǔ)工作,浪費大量時間。例如,設(shè)計數(shù)據(jù)以文件的形式保存,雖然實現(xiàn)了計算機化,但是仍然需要設(shè)計人員花費時間驗證文件的有效性、正確性。因此,利用信息化技術(shù),采用更先進的設(shè)計、管理工具,提升工作效率,降低人為失誤的概率,才是目前最行之有效的解決辦法。眾所周知,數(shù)據(jù)持久化使得程序代碼重用性強,即使更換數(shù)據(jù)庫,只需要更改配置文件,不必重寫程序代碼。此外,持久化技術(shù)可以自動優(yōu)化以減少對數(shù)據(jù)庫的訪問量,提高程序運行效率。該文將基于NHibernate技術(shù)展開研究,通過實現(xiàn)IO清單的數(shù)據(jù)持久化,與非持久化代碼進行對比,說明程序代碼的可重用性,為工程設(shè)計工具開發(fā)提供技術(shù)支持。
數(shù)據(jù)庫設(shè)計是指對于一個給定的應(yīng)用環(huán)境,構(gòu)造最優(yōu)的數(shù)據(jù)庫模式,建立數(shù)據(jù)庫及其應(yīng)用系統(tǒng),使之能夠有效地存儲數(shù)據(jù),滿足各種用戶的應(yīng)用需求。數(shù)據(jù)庫設(shè)計包括:概念設(shè)計、邏輯設(shè)計以及物理設(shè)計。概念設(shè)計是將實際的業(yè)務(wù)對象通過分類、聚集和概括等方法進行抽象,最終建立概念數(shù)據(jù)模型。邏輯設(shè)計是將概念數(shù)據(jù)模型設(shè)計成具體的數(shù)據(jù)庫管理系統(tǒng)所能支持的數(shù)據(jù)模型(即邏輯結(jié)構(gòu))。物理設(shè)計需要根據(jù)特定數(shù)據(jù)庫系統(tǒng)的存儲結(jié)構(gòu)和存取方法等各項物理設(shè)計措施,對具體的應(yīng)用任務(wù)選定最合適的物理存儲結(jié)構(gòu)。
工程設(shè)計工具用于輔助I/O及硬件設(shè)計,維護相關(guān)設(shè)計數(shù)據(jù),以便于應(yīng)用在對應(yīng)的工程項目上。設(shè)計工具中數(shù)據(jù)庫用于存儲設(shè)計數(shù)據(jù)信息、版本信息、相關(guān)的項目和人員等信息以及設(shè)計數(shù)據(jù)操作記錄。
E-R圖是描述概念數(shù)據(jù)模型的有效方法之一。圖1為工程師根據(jù)實際業(yè)務(wù)需求分析出的工程設(shè)計工具數(shù)據(jù)庫概念數(shù)據(jù)模型,圖1展示了用戶、項目、設(shè)計數(shù)據(jù)之間的邏輯關(guān)系。邏輯設(shè)計階段將概念設(shè)計階段得到的概念模型轉(zhuǎn)換為具體的邏輯結(jié)構(gòu)(即數(shù)據(jù)表表頭),以I/O清單實體邏輯結(jié)構(gòu)設(shè)計結(jié)果為例。
圖 1 工程設(shè)計工具E-R簡圖
I/O清單表頭,即邏輯結(jié)構(gòu)包括:儀表類型、位號、工藝系統(tǒng)、信號名、信號類型、信號描述、公制量程下限、量程上限公制、量程單位公制、物理量程上限公制、物理量程下限公制、物理量程單位公制、量程下限英制、量程上線英制、量程單位英制、物理量程上限英制、物理量程下限英制、物理量程單位英制、工作介質(zhì)、工作壓力、工作溫度、供電序列、供電方式、電氣分級、質(zhì)保分級、機械分級、抗震類別、抗震鑒定、環(huán)境鑒定、D-RAP/R分級、環(huán)境壓力Min、環(huán)境壓力Max、環(huán)境溫度Min、環(huán)境溫度Max、環(huán)境濕度Min、環(huán)境濕度Max、外形包絡(luò)圖-尺寸、設(shè)計壓力、設(shè)計溫度、流體介質(zhì)、工藝要求測量范圍、最低溫度、最高溫度、最高流速、最小流量、最大流量、變送器類型、傳感器類型、過程接口、電氣接口、標定量程、接口類型、I/O類型、行程時間、特殊要求、機組號、房間號、房間描述、測量方式、安裝方式、機柜號、機箱號、卡槽位置、模件類型、通道號。
非持久化方法獲取IO清單數(shù)據(jù)需要通過SqlConnection類實現(xiàn)。代碼示例如下:
//新建一個數(shù)據(jù)庫連接
using(SqlConnection conn = new SqlConnection(“Data Source=(localhost);user=develop ;password=123456”)) {
conn.Open();//打開數(shù)據(jù)庫
SqlCommand cmd = conn.CreateCommand();//創(chuàng)建數(shù)據(jù)庫連接命令
cmd.CommandText = “SELECT * FROM IOList”;//創(chuàng)建查詢語句,獲取所有I/O清單的數(shù)據(jù)
SqlDataReader reader = cmd.ExecuteReader();//從數(shù)據(jù)庫中讀取數(shù)據(jù)流存入reader中
//從reader中讀取下一行數(shù)據(jù),如果沒有數(shù)據(jù),reader.Read()返回flase
while (reader.Read()){
int ioListID = reader.GetInt32(reader.GetOrdinal(“IO_LIST_ID”));//獲取I/O清單ID
string signalName = reader.GetString(reader.GetOrdinal(“SIGNAL_NAME”));//獲取I/O信號名}}
上述代碼僅僅獲取I/O清單ID和信號名兩個字段。而I/O清單有65個業(yè)務(wù)字段,而整個工程設(shè)計工具數(shù)據(jù)庫有100多張表,如果要實現(xiàn)所有表的增刪改查的功能,那么就需要寫大量的SQL代碼。當數(shù)據(jù)表發(fā)生改變時,SQL語句還需要進行相應(yīng)的調(diào)整,代碼的可讀性、可重用性低,開發(fā)和維護的成本非常高。此外,SQL查詢優(yōu)化是非常復(fù)雜的,一條看似非常簡單的語句,可能會帶來性能的影響。程序員需要有比較專業(yè)的數(shù)據(jù)庫技能,針對不同的數(shù)據(jù)庫特點對SQL語句進行優(yōu)化。
持久化是將程序數(shù)據(jù)在持久狀態(tài)和瞬時狀態(tài)間轉(zhuǎn)換的機制,它主要是將內(nèi)存中的對象存儲在關(guān)系型的數(shù)據(jù)庫中,當然也可以存儲在磁盤文件中、 XML 數(shù)據(jù)文件中等。NHibernate是一個面向.Net環(huán)境的對象/關(guān)系數(shù)據(jù)庫映射工具。對象關(guān)系映射(O/R Mapping,Object Relational Mapping)表示一種技術(shù),用來把對象模型表示的對象映射到基于SQL的關(guān)系模型數(shù)據(jù)結(jié)構(gòu)中去。NHibernate不僅管理.Net類到數(shù)據(jù)庫表的映射(包括.Net數(shù)據(jù)類型到SQL數(shù)據(jù)類型的映射),還提供數(shù)據(jù)查詢和獲取數(shù)據(jù)的方法,大幅度減少開發(fā)者開發(fā)時人工使用SQL和ADO.NET處理數(shù)據(jù)的時間。NHibernate 采用XML 文件配置方式,每一個實體類對應(yīng)一個映射文件。體系結(jié)構(gòu)如圖2所示。從圖2中可以看到,NHibernate處于數(shù)據(jù)庫和應(yīng)用程序之間,為應(yīng)用程序提供持久化對象到數(shù)據(jù)庫的服務(wù)。
NHibernate通過使用數(shù)據(jù)庫和配置文件來為應(yīng)用程序提供持久化服務(wù),即它使用 NHibernate.properties或XML Mapping兩種配置文件方式把普通對象映射到關(guān)系數(shù)據(jù)庫中的表,從而使得應(yīng)用程序通過持久化的對象類直接訪問數(shù)據(jù)庫,而不是必須使用SQL和ADO. NET對數(shù)據(jù)庫進行操作。
圖2 NHibernate體系結(jié)構(gòu)
NHibernate持久化分為5個步驟,下面以I/O清單表為例來說明持久化方法。為了操作方便和兼容性,需要將漢字表示的邏輯設(shè)計用英文字母表示。
3.2.1 配置NHibernate
如圖3所示,在配置文件中需要告訴NHibernate使用的數(shù)據(jù)庫管理系統(tǒng)、數(shù)據(jù)庫版本、數(shù)據(jù)庫實例(包括地址名、實例名、端口號)、用戶名稱以及用戶密碼等。
圖3 NHibernate配置信息
3.2.2 在數(shù)據(jù)庫中創(chuàng)建I/O清單表
SQL語句如下:
VERSION_ID NUMBER(18) NOT NULL, //版本號
PROJECT_ITEM_ID NUMBER(18),//項目號
STATUS_ID NUMBER(18) NOT NULL,//數(shù)據(jù)狀態(tài)
COMMENTS VARCHAR2(4000 CHAR),//備注
IS_LATEST NUMBER(1) NOT NULL,//是否為最新
IS_VALID NUMBER(1) NOT NULL,//是否校驗
IO_LIST_ID NUMBER(18) NOT NULL,//IO 清單 ID(邏輯主鍵)
小學(xué)語文教學(xué)當前的發(fā)展明顯滯后于教改的進程,要求小學(xué)語文教師積極引入新課程理念來改進語文課堂教學(xué),培養(yǎng)學(xué)生良好的語文能力。而項目學(xué)習(xí)則是一種根據(jù)教師提供的課題項目而展開自主合作探究的有效學(xué)習(xí)方式,能夠充分體現(xiàn)學(xué)生在知識學(xué)習(xí)中的主體地位。在小學(xué)語文課堂中,教師應(yīng)該貫徹落實這一理念而開展高效教學(xué),培養(yǎng)學(xué)生的自主探究能力和團結(jié)協(xié)作能力。
FILE_STORE_ID NUMBER(18),//文件 ID
TAG_NO VARCHAR2(128 CHAR) NOT NULL,// 設(shè)備位號(業(yè)務(wù)主鍵)
PROCESS_SYSTEM VARCHAR2(128 CHAR) NOT NULL,//工藝系統(tǒng)
SIGNAL_NAME VARCHAR2(128 CHAR),//信號名
SIGNAL_TYPE VARCHAR2(128 CHAR),//信號類型
SIGNAL_DESCRIPTION VARCHAR2(1024 CHAR),//信號描述
RANGE_MIN NUMBER(18,5),//量程下限
RANGE_MAX NUMBER(18,5),//量程上限
RANGE_UNIT VARCHAR2(128 CHAR),//量程單位
OPERATING_MEDIUM VARCHAR2(128 CHAR),//工作介質(zhì)
OPERATING_PRES VARCHAR2(128 CHAR),//工作壓力
OPERATING_TEMP VARCHAR2(128 CHAR),//工作溫度
POWER_DIVISION VARCHAR2(128 CHAR),//供電序列
POWER_SUPPLY VARCHAR2(128 CHAR),//供電方式
ELEC_CLASS VARCHAR2(128 CHAR),//電氣分級
WANRRANTY_GRADING VARCHAR2(128 CHAR),//質(zhì)保分級
MECH_CLASS VARCHAR2(128 CHAR),//機械分級
SEISMIC_CAT VARCHAR2(128 CHAR),//抗震類別
SEISMIC_QUAL VARCHAR2(128 CHAR),//抗震鑒定
ENVIRON_QUAL VARCHAR2(128 CHAR),//環(huán)境鑒定
CARD_POSITION VARCHAR2(128 CHAR),//卡槽位置
MODULE_TYPE VARCHAR2(128 CHAR),//模件類型
CHANNEL_NO VARCHAR2(128 CHAR)//通道號
…);
3.2.3 構(gòu)建持久化的.Net類
代碼如下:
public class IOListObject {
public virtual string TagNO { get; set; } //設(shè)備位號
public virtual string ProcessSystem { get; set; }//工藝系統(tǒng)
public virtual string SignalName { get; set; }//型號名
public virtual string SignalType { get; set; }//信號類型
public virtual string SignalDescription { get; set; }//信號描述
public virtual double? RangeMin { get; set; }//量程下限
public virtual double? RangeMax { get; set; }//量程上限
public virtual string RangeUnit { get; set; }//量程單位
public virtual string OperatingMedium { get; set; }//工作介質(zhì)
public virtual string OperatingPressure { get; set; }//工作壓力
public virtual string OperatingTemperature { get; set; }//工作溫度
public virtual string PowerDivision { get; set; }//供電序列
public virtual string PowerSupply { get; set; }//供電方式
public virtual string ElecClass { get; set; }//電氣分級
public virtual string WanrrantyGrading { get; set; }//質(zhì)保分級
public virtual string MechClass { get; set; }//機械分級
public virtual string SeismicCategory { get; set; }抗震類別
public virtual string SeismicQual { get; set; }//抗震鑒定
public virtual string EnvironQual { get; set; }//環(huán)境鑒定
public virtual string CardPosition { get; set; }//卡槽位置
public virtual string ModuleType { get; set; }//模件類型
public virtual string ChannelNO { get; set; }//通道號…}
3.2.4 創(chuàng)建映射文件(Mapping File)
映射文件用于告訴NHibernate如何從數(shù)據(jù)表到.Net類的關(guān)聯(lián)。將需要映射的類、數(shù)據(jù)表信息編寫到一個映射文件中。
…
3.2.5 使用NHibernate的應(yīng)用程序編程接口(API,Application Programming Interface)來編程
在類中聲明NHibernate的Factory;在系統(tǒng)初始化的時候加載 XML文件,并創(chuàng)建Factory(即會話工廠,用于提供NHibernate會話環(huán)境),代碼如下:
public static void InitializeDataAccessModule(){
Configuration config = new Configuration();
Assembly asm = Assembly.GetAssembly(typeof(DataAccessManager));
string configFile = Path.Combine(Path.GetDirectoryName(asm.CodeBase.Remove(0, 8)), “user-hibernate.cfg.xml”);//加載XML文件
config = config.Configure(configFile);
sessionFactory = config.BuildSessionFactory();//創(chuàng) 建Factroy
isInitialized = true;
}
初始化后NHibernate環(huán)境后,可使用 Hql語言編寫具體的插入、修改、刪除、查詢語句,也可直接訪問對象,實現(xiàn)增刪改查操作。如下示例代碼,實現(xiàn)I/O清單的插入和更新:
public I List
ISession session = GetSession();
foreach (IOListVersionObject ilvo in ilvos){
if (ilvo.VersionId.HasValue) {
session.SaveOrUpdate(ilvo);//新建或保存I/O信號
session.Flush();//刷新緩存
}
else
{
session.Save(ilvo);
session.Flush();}}
return ilvos; }
至此,對IO清單進行基于NHibernate的持久化已經(jīng)實現(xiàn),通過對比持久化前后程序代碼,可以看出數(shù)據(jù)持久化后的代碼層次更加的清晰,可重用性提高。但是,NHibernate也存在明顯的不足:為了實現(xiàn)對象與關(guān)系模型之間的映射,需要編寫復(fù)雜的XML映射文件且容易出錯; NHibernate具有較大的靈活性,體系結(jié)構(gòu)比較復(fù)雜,使用難度大;不支持存儲過程、不具備事務(wù)處理等數(shù)據(jù)庫高級功能。這些都需要我們進一步研究與探討,例如,我們發(fā)現(xiàn)對象、關(guān)系模型以及XML映射文件的字段重復(fù)出現(xiàn),我們是否有辦法可以只設(shè)計其中一個,而另外兩個自動生成。