二、数据访问层
这里演示了一个 一对多的例子:
两个表:事件表和日志表,事件表 (1: n) 日志表.
以下是两个实体类和对应的配置文件。我单独建了一个项目来存放它们,它们不算是数据访问层!数据访问层、业务逻辑层、显示层都要用它。
//-----------------------------------------------------------------------------------------
//模块编号:030101
//文件名:EventTypeInfo.cs
//描述:EventTypeInfo实体类
//作者:ChenJie
//编写日期:-4-27
//Copyright
//-----------------------------------------------------------------------------------------
usingSystem;
usingSystem.Collections;
namespaceNovelty.Model.LogRecordBlcok
{
/**////<summary>
///<para>EventTypeInfo类</para>
///<para>操作事件类型</para>
///<para><seecref="member"/></para>
///<remarks></remarks>
///</summary>
publicclassEventTypeInfo:IComparable
{
内部成员变量#region内部成员变量
privateint_eventId;
privateint_eventParentId;
privatestring_eventName=string.Empty;
privatestring_description=string.Empty;
privateIList_systemLogs;
#endregion
构造函数#region构造函数
/**////<summary>
///默认的构造函数
///</summary>
publicEventTypeInfo()
{
}
/**////<summary>
///构造函数
///</summary>
///<paramname="eventId">事件源编号</param>
///<paramname="eventParentId">事件源父编号</param>
///<paramname="eventName">事件源名称</param>
///<paramname="description">事件描述</param>
publicEventTypeInfo(inteventId,inteventParentId,stringeventName,stringdescription)
{
_eventId=eventId;
_eventParentId=eventParentId;
_eventName=eventName;
_description=description;
}
#endregion
属性#region属性
/**////<summary>
///事件源编号
///</summary>
publicvirtualintEventId
{
get
{
return_eventId;
}
set
{
if(_eventId==value)
return;
_eventId=value;
}
}
/**////<summary>
///事件源父编号
///</summary>
publicvirtualintEventParentId
{
get
{
return_eventParentId;
}
set
{
if(_eventParentId==value)
return;
_eventParentId=value;
}
}
/**////<summary>
///事件源名称
///</summary>
publicvirtualstringEventName
{
get
{
return_eventName;
}
set
{
if(_eventName==value)
return;
_eventName=value;
}
}
/**////<summary>
///事件描述
///</summary>
publicvirtualstringDescription
{
get
{
return_description;
}
set
{
if(_description==value)
return;
_description=value;
}
}
/**////<summary>
///系统日志列表
///</summary>
publicvirtualIListSystemLogs
{
get
{
if(_systemLogs==null)
{
_systemLogs=newArrayList();
}
return_systemLogs;
}
set{_systemLogs=value;}
}
#endregion
重载方法#region重载方法
/**////<summary>
///根据关键字重新载Equals方法
///</summary>
///<paramname="obj">比较对象</param>
///<returns>比较结果</returns>
publicoverrideboolEquals(objectobj)
{
if(!(objisEventTypeInfo))
{
thrownewInvalidCastException("比较的对象不是EventTypeInfo的类型!");
}
EventTypeInfoeventTypeInfo=(EventTypeInfo)obj;
return_eventId==eventTypeInfo.EventId;
}
/**////<summary>
///获得对象的hash值
///</summary>
///<returns></returns>
publicoverrideintGetHashCode()
{
inthash=100;
hash=100*_eventId.GetHashCode();
returnhash;
}
/**////<summary>
///实现IComparable接口的比较方法
///</summary>
///<paramname="obj"></param>
///<returns></returns>
publicintCompareTo(objectobj)
{
if(!(objisEventTypeInfo))
{
thrownewInvalidCastException("比较的对象不是EventTypeInfo的类型!");
}
EventTypeInfoeventTypeInfo=(EventTypeInfo)obj;
pareTo(eventTypeInfo.EventId);
}
#endregion
}
}
//-----------------------------------------------------------------------------------------
//模块编号:
//文件名:SystemLogInfo.cs
//描述:SystemLogInfo实体类
//作者:ChenJie
//编写日期:-5-11
//Copyright
//-----------------------------------------------------------------------------------------
usingSystem;
usingNovelty.Model.UserAccountBlcok;
namespaceNovelty.Model.LogRecordBlcok
{
/**////<summary>
///<para>SystemLogInfo类</para>
///<para>操作日志表</para>
///<para><seecref="member"/></para>
///<remarks></remarks>
///</summary>
publicclassSystemLogInfo:IComparable
{
内部成员变量#region内部成员变量
privateint_systemLogId;
privateDateTime_operationTime;
privatestring_description=string.Empty;
privatestring_iPAddress=string.Empty;
privatedecimal_userSerial;
privateEventTypeInfo_eventType;
#endregion
构造函数#region构造函数
/**////<summary>
///默认的构造函数
///</summary>
publicSystemLogInfo()
{
}
/**////<summary>
///构造函数
///</summary>
///<paramname="systemLogId">日志编号</param>
///<paramname="operationTime">操作时间</param>
///<paramname="description">事件描述</param>
///<paramname="iPAddress">计算机地址</param>
///<paramname="userSerial">用户序号</param>
///<paramname="eventType">事件对象</param>
publicSystemLogInfo(intsystemLogId,DateTimeoperationTime,stringdescription,
stringiPAddress,decimaluserSerial,EventTypeInfoeventType)
{
_systemLogId=systemLogId;
_operationTime=operationTime;
_description=description;
_iPAddress=iPAddress;
_eventType=eventType;
_userSerial=userSerial;
}
#endregion
属性#region属性
/**////<summary>
///日志编号
///</summary>
publicvirtualintSystemLogId
{
get
{
return_systemLogId;
}
set
{
if(_systemLogId==value)
return;
_systemLogId=value;
}
}
/**////<summary>
///操作时间
///</summary>
publicvirtualDateTimeOperationTime
{
get
{
return_operationTime;
}
set
{
if(_operationTime==value)
return;
_operationTime=value;
}
}
/**////<summary>
///事件描述
///</summary>
publicvirtualstringDescription
{
get
{
return_description;
}
set
{
if(_description==value)
return;
_description=value;
}
}
/**////<summary>
///计算机地址
///</summary>
publicvirtualstringIPAddress
{
get
{
return_iPAddress;
}
set
{
if(_iPAddress==value)
return;
_iPAddress=value;
}
}
/**////<summary>
///用户序号
///</summary>
publicvirtualdecimalUserSerial
{
get
{
return_userSerial;
}
set
{
if(_userSerial==value)
return;
_userSerial=value;
}
}
/**////<summary>
///事件类型对象
///</summary>
publicvirtualEventTypeInfoEventType
{
get
{
return_eventType;
}
set
{
if(_eventType==value)
return;
_eventType=value;
}
}
#endregion
重载方法#region重载方法
/**////<summary>
///根据关键字重新载Equals方法
///</summary>
///<paramname="obj">比较对象</param>
///<returns>比较结果</returns>
publicoverrideboolEquals(objectobj)
{
if(!(objisSystemLogInfo))
{
thrownewInvalidCastException("比较的对象不是SystemLogInfo的类型!");
}
SystemLogInfosystemLogInfo=(SystemLogInfo)obj;
return_systemLogId==systemLogInfo.SystemLogId;
}
/**////<summary>
///获得对象的hash值
///</summary>
///<returns></returns>
publicoverrideintGetHashCode()
{
inthash=100;
hash=100*_systemLogId.GetHashCode();
returnhash;
}
/**////<summary>
///实现IComparable接口的比较方法
///</summary>
///<paramname="obj"></param>
///<returns></returns>
publicintCompareTo(objectobj)
{
if(!(objisSystemLogInfo))
{
thrownewInvalidCastException("比较的对象不是SystemLogInfo的类型!");
}
SystemLogInfosystemLogInfo=(SystemLogInfo)obj;
pareTo(systemLogInfo.SystemLogId);
}
#endregion
}
}
EventTypeInfo.hbm.xml:
<?xmlversion="1.0"encoding="utf-8"?>
<hibernate-mappingxmlns="urn:nhibernate-mapping-2.2">
<classname="Novelty.Model.LogRecordBlcok.EventTypeInfo,Novelty.Model"table="EventType">
<idname="EventId"column="EventId"type="Int32"unsaved-value="null">
<generatorclass="assigned"/>
</id>
<propertyname="EventParentId"type="Int32">
<columnname="EventParentId"length="4"sql-type="int"not-null="true"/>
</property>
<propertyname="EventName"type="string">
<columnname="EventName"length="32"sql-type="nvarchar"not-null="true"/>
</property>
<propertyname="Description"type="string">
<columnname="Description"length="128"sql-type="nvarchar"not-null="false"/>
</property>
<bagname="SystemLogs"inverse="true"lazy="true"cascade="all-delete-orphan">
<keycolumn="EventId"/>
<one-to-manyclass="Novelty.Model.LogRecordBlcok.SystemLogInfo,Novelty.Model"/>
</bag>
</class>
</hibernate-mapping>
SystemLogInfo.hbm.xml:
<?xmlversion="1.0"encoding="utf-8"?>
<hibernate-mappingxmlns="urn:nhibernate-mapping-2.2">
<classname="Novelty.Model.LogRecordBlcok.SystemLogInfo,Novelty.Model"table="SystemLog">
<idname="SystemLogId"column="SystemLogId"type="Int32"unsaved-value="null">
<generatorclass="assigned"/>
</id>
<propertyname="OperationTime"type="DateTime">
<columnname="OperationTime"length="8"sql-type="datetime"not-null="true"/>
</property>
<propertyname="Description"type="string">
<columnname="Description"length="128"sql-type="nvarchar"not-null="true"/>
</property>
<propertyname="IPAddress"type="string">
<columnname="IPAddress"length="15"sql-type="nvarchar"not-null="false"/>
</property>
<propertyname="UserSerial"type="Decimal">
<columnname="UserSerial"length="5"sql-type="decimal"not-null="true"/>
</property>
<many-to-onename="EventType"class="Novelty.Model.LogRecordBlcok.EventTypeInfo,Novelty.Model">
<columnname="EventId"length="4"sql-type="int"not-null="true"index="OperationEvent_FK"/>
</many-to-one>
</class>
</hibernate-mapping>
上面的代码太长了,你省略它们也不太影响思路。(为什么不早说?:) )
我们就举一个数据层访问类,它是操作 SystemLog 表的!
关于下面的代码,我就解释一下 Insert 方法,它是整个数据层中思路最重要的部分!
由于EventTypeInfo 和 SystemLogInfo 和 是一对多的关系!所以我们在插入 SystemLogInfo 对象前,先创建EventTypeInfo 对象:
先获得EventTypeInfo 的实体通用操作对象:
EntityControl<EventTypeInfo> eventTypeEntityControl = CommonDatabaseOperation<EventTypeInfo>.Instance.GetEntityControl(DEFAULT_DATABASE_IDENTIFIER);
然后通过EventTypeInfo 的实体通用操作对象来获得EventTypeInfo 对象:
EventTypeInfo eventType = eventTypeEntityControl.GetEntity(eventId);
在这里我们就不需要强制转换对象了,因为使用了范型类!当然,这里还不足以体现它的优越性!
由于我们声明了全局变量:
private readonly EntityControl<SystemLogInfo> entityControl;
然后在构造函数中创建它:
entityControl = CommonDatabaseOperation<SystemLogInfo>.Instance.GetEntityControl("SystemDatabase");
然后在该类的各个方法中都可以使用属于SystemLogInfo 的实体通用操作对象,其中在获得对象或是对象列表时均不需要强制转换对象。
这个数据访问层类只写了对应实体通用操作类中的一些方法,还应该包含其他方法!文件中没有给出例子,但是我还是举两个例说一下。
(1)比如批量删除记录,怎么办?听说NH的作者说要么不用NH,要么用SQL!已经用NH,那就只有SQL来进行批量删除记录。(可能是执行SQL 的代码太简单,或者担心破坏面向对象操作的思想,或者其他,我不知道!)但是我们来进行处理SQL,特别是带条件的SQL。因为条件各不相同,所以为什么我不把执行SQL的操作方法抽象出来放在实体通用操作类中,而是在各自需要的数据访问层类写各自的。
我在底层的SessionFactory类中放了一个方法:
public Configuration GetConfiguration(string assemblyName, string nhibernateConfigName, string connectionString);
通过它可以获得 ISessionFactoryImplementor 类的对象,然后再获得连接 IDbConnection 接口对象,然后再获得cmd,将相应的参数值赋上,然后再进行 SQL 操作。
具体参考底层的 EntityControl 类中方法:
public IList<T> GetEntitiesByExecuteSQL(string sql)
它给出了执行 SQL 语句的思路。
(2)多条件查询!
这个就是完全和 NH相关,还是因为条件各不相同,我无法在实体通用操作类中完成!
这个可以参考底层的 EntityControl 类中方法:
public IList<T> GetEntities(string propertyName, object value)
还补充一类情况:
string hql = "FROM SystemLogInfo WHERE UserSerial = :UserSerial ";
IQuery q = session.CreateQuery(hql);
q.SetDemical("UserSerial ", userSerial );
q.SetMaxResults(number);
return q.List();
这个例子中的session底层的SessionFactory类的方法
public ISession OpenSession(string assemblyName, string nhibernateConfigName, string connectionString)
中获得。
这类查询还有很多,这里只是简单举例,目的在于说明数据访问层里面究竟包含一些什么东西。
《面向对象的NHibernate数据查询语言-HQL》这篇文章关于查询讲的非常好,可供我们好好学习!
//-----------------------------------------------------------------------------------------
//模块编号:
//文件名:SystemLog.cs
//描述:SystemLog 数据层访问类
//作者:ChenJie
//编写日期:-5-11
//Copyright
//-----------------------------------------------------------------------------------------
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Data;
usingNovelty.Model.LogRecordBlcok;
usingNovelty.CustomSystem;
usingNovelty.CustomSystem.NHibernateOperation;
usingNovelty.CustomSystem.NHibernateOperation.NHibernateModule;
namespaceNovelty.CustomSystem.LogStrategy.LogRecordBlcok
{
/**////<summary>
///SystemLog表的数据层访问类
///</summary>
internalclassSystemLog
{
常量#region常量
/**////<summary>
///默认的数据库标识符
///</summary>
privateconststringDEFAULT_DATABASE_IDENTIFIER="SystemDatabase";
/**////<summary>
///HQL查询语句
///</summary>
privateconststringHQL_MAX_SYSTEM_LOG_ID="SELECTMAX_MAX;(systemLog.SystemLogId)FROMSystemLogInfoASsystemLog";
#endregion
私有变量#region私有变量
privatereadonlyEntityControl<SystemLogInfo>entityControl;
#endregion
构造函数#region构造函数
/**////<summary>
///默认的构造函数
///</summary>
publicSystemLog()
{
entityControl=CommonDatabaseOperation<SystemLogInfo>.Instance.GetEntityControl("SystemDatabase");
}
#endregion
接口#region接口
/**////<summary>
///将日志写入到数据库中
///</summary>
///<paramname="eventId">事件关编号</param>
///<paramname="userSerial">用户序号</param>
///<paramname="clientAddress">客户地址</param>
///<paramname="description">日志描述</param>
publicvoidInsert(inteventId,decimaluserSerial,stringclientAddress,stringdescription)
{
try
{
EntityControl<EventTypeInfo>eventTypeEntityControl=CommonDatabaseOperation<EventTypeInfo>.Instance.GetEntityControl(DEFAULT_DATABASE_IDENTIFIER);
EventTypeInfoeventType=eventTypeEntityControl.GetEntity(eventId);
intsystemLogId=entityControl.GetDataFieldValue<int>(HQL_MAX_SYSTEM_LOG_ID,0)+1;
SystemLogInfosystemLogInfo=
newSystemLogInfo(systemLogId,DateTime.Now,description,clientAddress,userSerial,eventType);
entityControl.AddEntity(systemLogInfo);
}
catch(Exceptionexception)
{
//记录日志,抛出异常,不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
/**////<summary>
///获得SystemLogInfo对象
///</summary>
///<paramname="systemLogId">日志编号</param>
///<returns>SystemLogInfo对象</returns>
publicSystemLogInfoGetSystemLogInfo(intsystemLogId)
{
returnentityControl.GetEntity(systemLogId);
}
/**////<summary>
///获得SystemLogInfo对象的列表
///</summary>
///<returns>SystemLogInfo对象列表</returns>
publicIList<SystemLogInfo>GetSystemLogInfos()
{
returnentityControl.GetEntities();
}
/**////<summary>
///获得SystemLogInfo对象的数据集
///</summary>
///<returns>SystemLogInfo对象的数据集</returns>
publicDataSetGetAll()
{
returnentityControl.ConvertToDataSet(entityControl.GetEntities());
}
/**////<summary>
///更新SystemLogInfo对象
///</summary>
///<paramname="systemLogInfo">SystemLogInfo对象</param>
publicvoidUpdate(SystemLogInfosystemLogInfo)
{
try
{
entityControl.UpdateEntity(systemLogInfo,systemLogInfo.SystemLogId);
}
catch(Exceptionexception)
{
//记录日志,抛出异常,不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
/**////<summary>
///删除满足条件的的SystemLogInfo对象
///</summary>
///<paramname="userSerial">用户序号</param>
///<returns>返回删除的记录数目数目</returns>
publicintDelete(decimaluserSerial)
{
intcount=0;
returncount;
}
/**////<summary>
///删除SystemLogInfo对象
///</summary>
///<paramname="systemLogInfo">SystemLogInfo对象</param>
publicvoidDelete(SystemLogInfosystemLogInfo)
{
try
{
entityControl.DeleteEntity(systemLogInfo);
}
catch(Exceptionexception)
{
//记录日志,抛出异常,不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
#endregion
}
}
NHibernate 配置文件的处理和使用多数据库的多层架构思路(第一部分)
/scucj/archive//05/15/747688.html
NHibernate 配置文件的处理和使用多数据库的多层架构思路(第三部分)
/scucj/archive//05/15/747698.html