NHibernate 配置文件的处理和使用多数据库的多层架构思路(第二部分)
二、数据访问层
这里演示了一个 一对多的例子:
两个表:事件表和日志表,事件表 (1: n) 日志表.
以下是两个实体类和对应的配置文件。我单独建了一个项目来存放它们,它们不算是数据访问层!数据访问层、业务逻辑层、显示层都要用它。
// 模块编号:030101
// 文件名: EventTypeInfo.cs
// 描述: EventTypeInfo 实体类
// 作者:ChenJie
// 编写日期:2007-4-27
// Copyright 2007
//-----------------------------------------------------------------------------------------
using System;
using System.Collections;
namespace Novelty.Model.LogRecordBlcok
{
/**//// <summary>
/// <para>EventTypeInfo 类</para>
/// <para>操作事件类型</para>
/// <para><see cref="member"/></para>
/// <remarks></remarks>
/// </summary>
public class EventTypeInfo : IComparable
{
内部成员变量#region 内部成员变量
private int _eventId;
private int _eventParentId;
private string _eventName = string.Empty;
private string _description = string.Empty;
private IList _systemLogs;
#endregion
构造函数#region 构造函数
/**//// <summary>
/// 默认的构造函数
/// </summary>
public EventTypeInfo()
{
}
/**//// <summary>
/// 构造函数
/// </summary>
///<param name="eventId">事件源编号</param>
///<param name="eventParentId">事件源父编号</param>
///<param name="eventName">事件源名称</param>
///<param name="description">事件描述</param>
public EventTypeInfo(int eventId, int eventParentId, string eventName, string description)
{
_eventId = eventId;
_eventParentId = eventParentId;
_eventName = eventName;
_description = description;
}
#endregion
属性#region 属性
/**//// <summary>
/// 事件源编号
/// </summary>
public virtual int EventId
{
get
{
return _eventId;
}
set
{
if (_eventId == value)
return;
_eventId = value;
}
}
/**//// <summary>
/// 事件源父编号
/// </summary>
public virtual int EventParentId
{
get
{
return _eventParentId;
}
set
{
if (_eventParentId == value)
return;
_eventParentId = value;
}
}
/**//// <summary>
/// 事件源名称
/// </summary>
public virtual string EventName
{
get
{
return _eventName;
}
set
{
if (_eventName == value)
return;
_eventName = value;
}
}
/**//// <summary>
/// 事件描述
/// </summary>
public virtual string Description
{
get
{
return _description;
}
set
{
if (_description == value)
return;
_description = value;
}
}
/**//// <summary>
/// 系统日志列表
/// </summary>
public virtual IList SystemLogs
{
get
{
if (_systemLogs == null)
{
_systemLogs = new ArrayList();
}
return _systemLogs;
}
set { _systemLogs = value; }
}
#endregion
重载方法#region 重载方法
/**//// <summary>
/// 根据关键字重新载 Equals 方法
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public override bool Equals(object obj)
{
if (!(obj is EventTypeInfo))
{
throw new InvalidCastException("比较的对象不是 EventTypeInfo 的类型!");
}
EventTypeInfo eventTypeInfo = (EventTypeInfo)obj;
return _eventId == eventTypeInfo.EventId;
}
/**//// <summary>
/// 获得对象的 hash 值
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
int hash = 100;
hash = 100 * _eventId.GetHashCode();
return hash;
}
/**//// <summary>
/// 实现 IComparable 接口的比较方法
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int CompareTo(object obj)
{
if (!(obj is EventTypeInfo))
{
throw new InvalidCastException("比较的对象不是 EventTypeInfo 的类型!");
}
EventTypeInfo eventTypeInfo = (EventTypeInfo)obj;
return _eventId.CompareTo(eventTypeInfo.EventId);
}
#endregion
}
}
// 模块编号:
// 文件名: SystemLogInfo.cs
// 描述: SystemLogInfo 实体类
// 作者:ChenJie
// 编写日期:2007-5-11
// Copyright 2007
//-----------------------------------------------------------------------------------------
using System;
using Novelty.Model.UserAccountBlcok;
namespace Novelty.Model.LogRecordBlcok
{
/**//// <summary>
/// <para>SystemLogInfo 类</para>
/// <para>操作日志表</para>
/// <para><see cref="member"/></para>
/// <remarks></remarks>
/// </summary>
public class SystemLogInfo : IComparable
{
内部成员变量#region 内部成员变量
private int _systemLogId;
private DateTime _operationTime;
private string _description = string.Empty;
private string _iPAddress = string.Empty;
private decimal _userSerial;
private EventTypeInfo _eventType;
#endregion
构造函数#region 构造函数
/**//// <summary>
/// 默认的构造函数
/// </summary>
public SystemLogInfo()
{
}
/**//// <summary>
/// 构造函数
/// </summary>
///<param name="systemLogId">日志编号</param>
///<param name="operationTime">操作时间</param>
///<param name="description">事件描述</param>
///<param name="iPAddress">计算机地址</param>
///<param name="userSerial">用户序号</param>
///<param name="eventType">事件对象</param>
public SystemLogInfo(int systemLogId, DateTime operationTime, string description,
string iPAddress, decimal userSerial, EventTypeInfo eventType)
{
_systemLogId = systemLogId;
_operationTime = operationTime;
_description = description;
_iPAddress = iPAddress;
_eventType = eventType;
_userSerial = userSerial;
}
#endregion
属性#region 属性
/**//// <summary>
/// 日志编号
/// </summary>
public virtual int SystemLogId
{
get
{
return _systemLogId;
}
set
{
if (_systemLogId == value)
return;
_systemLogId = value;
}
}
/**//// <summary>
/// 操作时间
/// </summary>
public virtual DateTime OperationTime
{
get
{
return _operationTime;
}
set
{
if (_operationTime == value)
return;
_operationTime = value;
}
}
/**//// <summary>
/// 事件描述
/// </summary>
public virtual string Description
{
get
{
return _description;
}
set
{
if (_description == value)
return;
_description = value;
}
}
/**//// <summary>
/// 计算机地址
/// </summary>
public virtual string IPAddress
{
get
{
return _iPAddress;
}
set
{
if (_iPAddress == value)
return;
_iPAddress = value;
}
}
/**//// <summary>
/// 用户序号
/// </summary>
public virtual decimal UserSerial
{
get
{
return _userSerial;
}
set
{
if (_userSerial == value)
return;
_userSerial = value;
}
}
/**//// <summary>
/// 事件类型对象
/// </summary>
public virtual EventTypeInfo EventType
{
get
{
return _eventType;
}
set
{
if (_eventType == value)
return;
_eventType = value;
}
}
#endregion
重载方法#region 重载方法
/**//// <summary>
/// 根据关键字重新载 Equals 方法
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public override bool Equals(object obj)
{
if (!(obj is SystemLogInfo))
{
throw new InvalidCastException("比较的对象不是 SystemLogInfo 的类型!");
}
SystemLogInfo systemLogInfo = (SystemLogInfo)obj;
return _systemLogId == systemLogInfo.SystemLogId;
}
/**//// <summary>
/// 获得对象的 hash 值
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
int hash = 100;
hash = 100 * _systemLogId.GetHashCode();
return hash;
}
/**//// <summary>
/// 实现 IComparable 接口的比较方法
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int CompareTo(object obj)
{
if (!(obj is SystemLogInfo))
{
throw new InvalidCastException("比较的对象不是 SystemLogInfo 的类型!");
}
SystemLogInfo systemLogInfo = (SystemLogInfo)obj;
return _systemLogId.CompareTo(systemLogInfo.SystemLogId);
}
#endregion
}
}
EventTypeInfo.hbm.xml:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Novelty.Model.LogRecordBlcok.EventTypeInfo, Novelty.Model" table="EventType">
<id name="EventId" column="EventId" type="Int32" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="EventParentId" type="Int32">
<column name="EventParentId" length="4" sql-type="int" not-null="true"/>
</property>
<property name="EventName" type="string">
<column name="EventName" length="32" sql-type="nvarchar" not-null="true"/>
</property>
<property name="Description" type="string">
<column name="Description" length="128" sql-type="nvarchar" not-null="false"/>
</property>
<bag name="SystemLogs" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="EventId"/>
<one-to-many class="Novelty.Model.LogRecordBlcok.SystemLogInfo, Novelty.Model"/>
</bag>
</class>
</hibernate-mapping>
SystemLogInfo.hbm.xml:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Novelty.Model.LogRecordBlcok.SystemLogInfo, Novelty.Model" table="SystemLog">
<id name="SystemLogId" column="SystemLogId" type="Int32" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="OperationTime" type="DateTime">
<column name="OperationTime" length="8" sql-type="datetime" not-null="true"/>
</property>
<property name="Description" type="string">
<column name="Description" length="128" sql-type="nvarchar" not-null="true"/>
</property>
<property name="IPAddress" type="string">
<column name="IPAddress" length="15" sql-type="nvarchar" not-null="false"/>
</property>
<property name="UserSerial" type="Decimal">
<column name="UserSerial" length="5" sql-type="decimal" not-null="true"/>
</property>
<many-to-one name="EventType" class="Novelty.Model.LogRecordBlcok.EventTypeInfo, Novelty.Model">
<column name="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
// 编写日期:2007-5-11
// Copyright 2007
//-----------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Novelty.Model.LogRecordBlcok;
using Novelty.CustomSystem;
using Novelty.CustomSystem.NHibernateOperation;
using Novelty.CustomSystem.NHibernateOperation.NHibernateModule;
namespace Novelty.CustomSystem.LogStrategy.LogRecordBlcok
{
/**//// <summary>
/// SystemLog表的数据层访问类
/// </summary>
internal class SystemLog
{
常量#region 常量
/**//// <summary>
/// 默认的数据库标识符
/// </summary>
private const string DEFAULT_DATABASE_IDENTIFIER = "SystemDatabase";
/**//// <summary>
/// HQL 查询语句
/// </summary>
private const string HQL_MAX_SYSTEM_LOG_ID = "SELECT MAX _MAX;(systemLog.SystemLogId) FROM SystemLogInfo AS systemLog";
#endregion
私有变量#region 私有变量
private readonly EntityControl<SystemLogInfo> entityControl;
#endregion
构造函数#region 构造函数
/**//// <summary>
/// 默认的构造函数
/// </summary>
public SystemLog()
{
entityControl = CommonDatabaseOperation<SystemLogInfo>.Instance.GetEntityControl("SystemDatabase");
}
#endregion
接口#region 接口
/**//// <summary>
/// 将日志写入到数据库中
/// </summary>
/// <param name="eventId">事件关编号</param>
/// <param name="userSerial">用户序号</param>
/// <param name="clientAddress">客户地址</param>
/// <param name="description">日志描述</param>
public void Insert(int eventId, decimal userSerial, string clientAddress, string description)
{
try
{
EntityControl<EventTypeInfo> eventTypeEntityControl = CommonDatabaseOperation<EventTypeInfo>.Instance.GetEntityControl(DEFAULT_DATABASE_IDENTIFIER);
EventTypeInfo eventType = eventTypeEntityControl.GetEntity(eventId);
int systemLogId = entityControl.GetDataFieldValue<int>(HQL_MAX_SYSTEM_LOG_ID, 0) + 1;
SystemLogInfo systemLogInfo =
new SystemLogInfo(systemLogId, DateTime.Now, description, clientAddress, userSerial, eventType);
entityControl.AddEntity(systemLogInfo);
}
catch (Exception exception)
{
//记录日志, 抛出异常, 不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
/**//// <summary>
/// 获得 SystemLogInfo 对象
/// </summary>
///<param name="systemLogId">日志编号</param>
/// <returns> SystemLogInfo 对象</returns>
public SystemLogInfo GetSystemLogInfo(int systemLogId)
{
return entityControl.GetEntity(systemLogId);
}
/**//// <summary>
/// 获得 SystemLogInfo 对象的列表
/// </summary>
/// <returns>SystemLogInfo 对象列表</returns>
public IList<SystemLogInfo> GetSystemLogInfos()
{
return entityControl.GetEntities();
}
/**//// <summary>
/// 获得 SystemLogInfo 对象的数据集
/// </summary>
/// <returns>SystemLogInfo 对象的数据集</returns>
public DataSet GetAll()
{
return entityControl.ConvertToDataSet(entityControl.GetEntities());
}
/**//// <summary>
/// 更新 SystemLogInfo 对象
/// </summary>
/// <param name="systemLogInfo">SystemLogInfo 对象</param>
public void Update(SystemLogInfo systemLogInfo)
{
try
{
entityControl.UpdateEntity(systemLogInfo, systemLogInfo.SystemLogId);
}
catch (Exception exception)
{
//记录日志, 抛出异常, 不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
/**//// <summary>
/// 删除满足条件的的 SystemLogInfo 对象
/// </summary>
/// <param name="userSerial">用户序号</param>
/// <returns>返回删除的记录数目数目</returns>
public int Delete(decimal userSerial)
{
int count = 0;
return count;
}
/**//// <summary>
/// 删除 SystemLogInfo 对象
/// </summary>
/// <param name="systemLogInfo">SystemLogInfo 对象</param>
public void Delete(SystemLogInfo systemLogInfo)
{
try
{
entityControl.DeleteEntity(systemLogInfo);
}
catch (Exception exception)
{
//记录日志, 抛出异常, 不包装异常
ExceptionFacade.LogAndThrowAndNoWrapPolicy(exception);
}
}
#endregion
}
}
NHibernate 配置文件的处理和使用多数据库的多层架构思路(第一部分)
http://www.cnblogs.com/scucj/archive/2007/05/15/747688.html
NHibernate 配置文件的处理和使用多数据库的多层架构思路(第三部分)
http://www.cnblogs.com/scucj/archive/2007/05/15/747698.html
转载于:https://www.cnblogs.com/scucj/archive/2007/05/15/747695.html
NHibernate 配置文件的处理和使用多数据库的多层架构思路(第二部分)相关推荐
- [转] 网站性能优化之------------- 数据库及服务器架构篇
转载自: http://blog.163.com/dangzhengtao@yeah/blog/static/7780087420098232213289/?fromdm&fromSearch ...
- Netlog 的数据库及 LAMP 架构
Database Sharding@Netlog 详细的描述了 Netlog 数据库架构的演变过程,文章浅显易懂,非常值得学习.本文数据.图片均来自:Database Sharding at Netl ...
- mysql 日志文件 自动_自动恢复MySQL数据库的日志文件思路分享及解决方案
如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据."mysqlbinlog:用 ...
- 基于Consul的数据库高可用架构【转】
几个月没有更新博客了,已经长草了,特意来除草.本次主要分享如何利用consul来实现redis以及mysql的高可用.以前的公司mysql是单机单实例,高可用MHA加vip就能搞定,新公司mysql是 ...
- 云数据库产品及架构设计背后的考量
摘要:在阿里云数据库技术峰会上,阿里云数据库高级产品专家萧少聪(铁庵)介绍了全体系阿里云数据库产品并对于阿里云数据库产品的实现架构进行了分享,帮助大家了解了阿里云全数据库产品体系能解决哪些实用场景的问 ...
- 开源分布式数据库中间件MyCat架构简介(一)——基于MyCat的分库分表,读写分离,水平切分和垂直切分实现原理
目录 前言 开源分布式数据库中间件MyCat架构简介--MyCat源起 一.数据库切分概述:OLTP和OLAP 二.关系型数据库和NoSQL数据库 三.关系型数据库和NoSQL数据库的特点及优缺点 1 ...
- sql server登录名、服务器角色、数据库用户、数据库角色、架构区别联系
原创链接:https://www.cnblogs.com/lxf1117/p/6762315.html sql server登录名.服务器角色.数据库用户.数据库角色.架构区别联系 1.一个数据库用户 ...
- MSSQL 2012 拒绝了对对象 'extended_properties' (数据库 'mssqlsystemresource',架构 'sys')的 SELECT 权限...
查看数据库的表的时候报如下错误: MSSQL 2012 拒绝了对对象 'extended_properties' (数据库 'mssqlsystemresource',架构 'sys')的 SELEC ...
- getprivateprofilestring读不到数据_电商系列(三)如何构建数据库的主从架构!
这段时间,一直在总结电商系统的相关基础技术和架构,写了很多东西.但是还是发现一个很重要,很基础的方面没有讲到,那就是数据库读写分离的主从架构.可能发展到大型成熟的公司之后,主从架构已经落伍了,取而代之 ...
最新文章
- SimpleDateFormat非线程安全
- ubuntu下python thrift安装
- 从今开始,好好学习一下算法!
- 如何执行shell脚本文件
- PyOpenCV 坐标系统
- 从像素坐标到相机坐标_【视觉知识】机器视觉几何坐标概论
- 学习Java之前的一些话
- python调包侠_sklearn调包侠之K-Means
- c235delc杂合变异遗传吗_血常规正常就真的没有地贫吗?
- 【微信支付开发流程】
- 计算机中丢失msvcr100.dll怎么办,Win7计算机中Msvcr100.dll丢失的解决方法
- 纵横算法之五:想学算法,时间不够怎么办
- Window环境下MQTT安装
- 目前流行的装修风格_2020最新装修风格,目前流行的装修风格,值得收藏!
- django基于python的平南盛世名城小区疫情防控系统--python-计算机毕业设计
- Html5新特性总览
- 关于cv::cuda::GpuMat与PtrStepSz
- 小森生活服务器维护到几点,小森生活几点开服上线 2021小森生活开服表大全[多图]...
- 计算机科学导论(6):操作系统
- linux系统安装fio工具步骤