当前位置:首页 期刊杂志

基于NHibernate的核电仪控系统设计工具数据持久化

时间:2024-05-17

施国荣

(国核自仪系统工程有限公司,上海 200241)

1 背景

核电仪控系统为核电厂提供了各种控制和保护手段以及监控信息,保证了核电厂在正常启动、停堆、异常和事故工况下能够安全、可靠、有效地运行。由于核电仪控系统涉及的系统多、工艺复杂、控制设备多,导致控制和测量点的数量庞大。目前,示范项目首堆包括10 个仪控子系统,技术接口61 个,测量信号约2 万个,每个子系统由5 人共同协作设计。随着项目数量增多,设计输入和接口数据成倍增加,各项目之间的输入和接口数据既有联系又有区别,在各项目工程任务并行开展的情况下,设计人员会产生质量问题。仪控系统设计团队除了面临上述问题外,设计过程受供货商以及电厂现场变化影响大,各种数据、图纸修改量极大(示范项目目前设计变更数量约320 个),因此可能出现质量事故的概率也会增加。目前已实现自动化办公,但所使用的软件功能有限,不能很好地与目前核电仪控系统设计工作结合,设计人员在应用时需要做大量的非技术性基础工作,浪费大量时间。例如,设计数据以文件的形式保存,虽然实现了计算机化,但是仍然需要设计人员花费时间验证文件的有效性、正确性。因此,利用信息化技术,采用更先进的设计、管理工具,提升工作效率,降低人为失误的概率,才是目前最行之有效的解决办法。众所周知,数据持久化使得程序代码重用性强,即使更换数据库,只需要更改配置文件,不必重写程序代码。此外,持久化技术可以自动优化以减少对数据库的访问量,提高程序运行效率。该文将基于NHibernate技术展开研究,通过实现IO清单的数据持久化,与非持久化代码进行对比,说明程序代码的可重用性,为工程设计工具开发提供技术支持。

2 数据库设计以及非持久化实现

2.1 数据库设计

数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求。数据库设计包括:概念设计、逻辑设计以及物理设计。概念设计是将实际的业务对象通过分类、聚集和概括等方法进行抽象,最终建立概念数据模型。逻辑设计是将概念数据模型设计成具体的数据库管理系统所能支持的数据模型(即逻辑结构)。物理设计需要根据特定数据库系统的存储结构和存取方法等各项物理设计措施,对具体的应用任务选定最合适的物理存储结构。

工程设计工具用于辅助I/O及硬件设计,维护相关设计数据,以便于应用在对应的工程项目上。设计工具中数据库用于存储设计数据信息、版本信息、相关的项目和人员等信息以及设计数据操作记录。

E-R图是描述概念数据模型的有效方法之一。图1为工程师根据实际业务需求分析出的工程设计工具数据库概念数据模型,图1展示了用户、项目、设计数据之间的逻辑关系。逻辑设计阶段将概念设计阶段得到的概念模型转换为具体的逻辑结构(即数据表表头),以I/O清单实体逻辑结构设计结果为例。

图 1 工程设计工具E-R简图

I/O清单表头,即逻辑结构包括:仪表类型、位号、工艺系统、信号名、信号类型、信号描述、公制量程下限、量程上限公制、量程单位公制、物理量程上限公制、物理量程下限公制、物理量程单位公制、量程下限英制、量程上线英制、量程单位英制、物理量程上限英制、物理量程下限英制、物理量程单位英制、工作介质、工作压力、工作温度、供电序列、供电方式、电气分级、质保分级、机械分级、抗震类别、抗震鉴定、环境鉴定、D-RAP/R分级、环境压力Min、环境压力Max、环境温度Min、环境温度Max、环境湿度Min、环境湿度Max、外形包络图-尺寸、设计压力、设计温度、流体介质、工艺要求测量范围、最低温度、最高温度、最高流速、最小流量、最大流量、变送器类型、传感器类型、过程接口、电气接口、标定量程、接口类型、I/O类型、行程时间、特殊要求、机组号、房间号、房间描述、测量方式、安装方式、机柜号、机箱号、卡槽位置、模件类型、通道号。

2.2 非持久化方法实现

非持久化方法获取IO清单数据需要通过SqlConnection类实现。代码示例如下:

//新建一个数据库连接

using(SqlConnection conn = new SqlConnection(“Data Source=(localhost);user=develop ;password=123456”)) {

conn.Open();//打开数据库

SqlCommand cmd = conn.CreateCommand();//创建数据库连接命令

cmd.CommandText = “SELECT * FROM IOList”;//创建查询语句,获取所有I/O清单的数据

SqlDataReader reader = cmd.ExecuteReader();//从数据库中读取数据流存入reader中

//从reader中读取下一行数据,如果没有数据,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个业务字段,而整个工程设计工具数据库有100多张表,如果要实现所有表的增删改查的功能,那么就需要写大量的SQL代码。当数据表发生改变时,SQL语句还需要进行相应的调整,代码的可读性、可重用性低,开发和维护的成本非常高。此外,SQL查询优化是非常复杂的,一条看似非常简单的语句,可能会带来性能的影响。程序员需要有比较专业的数据库技能,针对不同的数据库特点对SQL语句进行优化。

3 NHibernate介绍和以及实现持久化

3.1 NHibernate体系结构

持久化是将程序数据在持久状态和瞬时状态间转换的机制,它主要是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、 XML 数据文件中等。NHibernate是一个面向.Net环境的对象/关系数据库映射工具。对象关系映射(O/R Mapping,Object Relational Mapping)表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。NHibernate不仅管理.Net类到数据库表的映射(包括.Net数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,大幅度减少开发者开发时人工使用SQL和ADO.NET处理数据的时间。NHibernate 采用XML 文件配置方式,每一个实体类对应一个映射文件。体系结构如图2所示。从图2中可以看到,NHibernate处于数据库和应用程序之间,为应用程序提供持久化对象到数据库的服务。

NHibernate通过使用数据库和配置文件来为应用程序提供持久化服务,即它使用 NHibernate.properties或XML Mapping两种配置文件方式把普通对象映射到关系数据库中的表,从而使得应用程序通过持久化的对象类直接访问数据库,而不是必须使用SQL和ADO. NET对数据库进行操作。

图2 NHibernate体系结构

3.2 NHibernate持久化步骤与实例

NHibernate持久化分为5个步骤,下面以I/O清单表为例来说明持久化方法。为了操作方便和兼容性,需要将汉字表示的逻辑设计用英文字母表示。

3.2.1 配置NHibernate

如图3所示,在配置文件中需要告诉NHibernate使用的数据库管理系统、数据库版本、数据库实例(包括地址名、实例名、端口号)、用户名称以及用户密码等。

图3 NHibernate配置信息

3.2.2 在数据库中创建I/O清单表

SQL语句如下:

VERSION_ID NUMBER(18) NOT NULL, //版本号

PROJECT_ITEM_ID NUMBER(18),//项目号

STATUS_ID NUMBER(18) NOT NULL,//数据状态

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(逻辑主键)

小学语文教学当前的发展明显滞后于教改的进程,要求小学语文教师积极引入新课程理念来改进语文课堂教学,培养学生良好的语文能力。而项目学习则是一种根据教师提供的课题项目而展开自主合作探究的有效学习方式,能够充分体现学生在知识学习中的主体地位。在小学语文课堂中,教师应该贯彻落实这一理念而开展高效教学,培养学生的自主探究能力和团结协作能力。

FILE_STORE_ID NUMBER(18),//文件 ID

TAG_NO VARCHAR2(128 CHAR) NOT NULL,// 设备位号(业务主键)

PROCESS_SYSTEM VARCHAR2(128 CHAR) NOT NULL,//工艺系统

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),//工作介质

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),//质保分级

MECH_CLASS VARCHAR2(128 CHAR),//机械分级

SEISMIC_CAT VARCHAR2(128 CHAR),//抗震类别

SEISMIC_QUAL VARCHAR2(128 CHAR),//抗震鉴定

ENVIRON_QUAL VARCHAR2(128 CHAR),//环境鉴定

CARD_POSITION VARCHAR2(128 CHAR),//卡槽位置

MODULE_TYPE VARCHAR2(128 CHAR),//模件类型

CHANNEL_NO VARCHAR2(128 CHAR)//通道号

…);

3.2.3 构建持久化的.Net类

代码如下:

public class IOListObject {

public virtual string TagNO { get; set; } //设备位号

public virtual string ProcessSystem { get; set; }//工艺系统

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; }//工作介质

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; }//质保分级

public virtual string MechClass { get; set; }//机械分级

public virtual string SeismicCategory { get; set; }抗震类别

public virtual string SeismicQual { get; set; }//抗震鉴定

public virtual string EnvironQual { get; set; }//环境鉴定

public virtual string CardPosition { get; set; }//卡槽位置

public virtual string ModuleType { get; set; }//模件类型

public virtual string ChannelNO { get; set; }//通道号…}

3.2.4 创建映射文件(Mapping File)

映射文件用于告诉NHibernate如何从数据表到.Net类的关联。将需要映射的类、数据表信息编写到一个映射文件中。

3.2.5 使用NHibernate的应用程序编程接口(API,Application Programming Interface)来编程

在类中声明NHibernate的Factory;在系统初始化的时候加载 XML文件,并创建Factory(即会话工厂,用于提供NHibernate会话环境),代码如下:

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();//创 建Factroy

isInitialized = true;

}

初始化后NHibernate环境后,可使用 Hql语言编写具体的插入、修改、删除、查询语句,也可直接访问对象,实现增删改查操作。如下示例代码,实现I/O清单的插入和更新:

public I ListInsertOrUpdateIOListInfoVersions(Listilvos) {

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; }

4 结语

至此,对IO清单进行基于NHibernate的持久化已经实现,通过对比持久化前后程序代码,可以看出数据持久化后的代码层次更加的清晰,可重用性提高。但是,NHibernate也存在明显的不足:为了实现对象与关系模型之间的映射,需要编写复杂的XML映射文件且容易出错; NHibernate具有较大的灵活性,体系结构比较复杂,使用难度大;不支持存储过程、不具备事务处理等数据库高级功能。这些都需要我们进一步研究与探讨,例如,我们发现对象、关系模型以及XML映射文件的字段重复出现,我们是否有办法可以只设计其中一个,而另外两个自动生成。

免责声明

我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!