一:表数据入口(Table Data Gateway)

表数据入口提供了用于访问单个表或者视图(也包含了联表查询)的所有SQL,通常一个表一个类。其它代码通过它来实现对数据库的交互。基于这个特点,表数据入口和事务脚本代码以及表模块结合的很好。

在查询时候,表数据接口可以返回数据集 或者 DTO 或者 DTO列表。在 事务脚本 代码中已经阐述过了 DTO 以及 DTO 的列表这种形式。但是使用 DTO 这种形式,带来的一个问题是:到处衍生的 DTO,那么,如何减少到处衍生的 DTO 的,见这里《》。

在传统做法中,表数据入口和领域模型不一起使用,使用领域模型,一般使用数据映射器。

表数据入口的代码到处都是,如:

public class UserDal : SqlServerDal<User>
    {
        public override IList<User> GetList()
        {
            string sql = "select * from [EL_Organization].[User] where state=1";
            var ds = SqlHelper.ExecuteDataset(CommandType.Text, sql);

IList<User> oblist = new List<User>();
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                oblist.Add(new User{ Id = (string)row["Id"], Name = (string)row["Name"] });
            }

return oblist;
        }
       
        public override User FindOne(User t){ return null;}
   
        public override void Insert(User model) {}
       
        public override void Update(User t){}

public override void Delete(User t){}
    }

public class User
    {
        public string Id;
        public string Name;
    }

二:行数据入口(Row Data Gateway)

行数据入口,则表中的一行记录存在一个对象。

public class UserDal
    {
        public string Id;
        public string Name;
       
        public void Load(DataSet ds)
        {
            //根据 ds 得到自身,而这个 ds 有可能是从 UserFinderDal 得到的
        }
       
        public void Insert()
        {
            string sql = @"INSERT INTO [EL_Organization].[User] ('Id', 'Name') VALUES (" + this.Id + "," + this.Name + ")";
            var ds = SqlHelper.Execute(CommandType.Text, sql);
        }
       
        public void Update()
        {
            // update this;
        }

public void Delete()
        {
            // delete this;
        }
    }

public class UserFinderDal
    {
        public UserDal FindOne(string id)
        {
            string sql = "select * from [EL_Organization].[User] where id=" + id;
            var ds = SqlHelper.ExecuteDataset(CommandType.Text, sql);

foreach (DataRow row in ds.Tables[0].Rows)
            {
                return new UserDal {Id = (string)row["Id"], Name = (string)row["Name"]}; ;
            }
           
            return null;
        }
   
        public List<UserDal> FindList(string name)
        {
            return null;
        }
   
    }

可以看到,和表数据库入口比,查询数据库中的数据,表数据库入口只要一个类就可以了,而行数据入口则需要两个类,自身也被用做数据库实体,但是负责自身的 update insert delete,而要查询自身和集合或者是操作集合,则需要另外一个类来完成。

二:活动记录(Active Record)

活动记录 与 行数据入口 很类似。二者的差别是 行数据入口 只有数据库访问而 活动记录 是即有数据库访问又有领域逻辑。在 行数据入口 中,我们一般使用两个类,而在活动记录中,一般则无此限制,通常情况下,一个类可能会显得更清爽。

领域模型,一般和 活动记录 或者 数据映射器 协作。

在软件开发中,初级的做法是:事务脚本;

比较高级一点的做法是:活动记录。一般,当发现事务脚本的代码已经复杂到难以维护的时候,则可以逐步创建活动记录,然后慢慢为它们添加行为,即:把表包装成为活动记录,然后添加领域逻辑。

最复杂而高级的做法是:领域模型。

从以上的描述中,我们很容易知道如何修改本文中的 表数据入口 或者 行数据入口 的代码,继而让它成为 活动记录 的。

public class UserActiveRecord
    {
        public string Id;
        public string Name;
       
        public void Load(DataSet ds)
        {
            //根据 ds 得到自身,而这个 ds 有可能是从 UserFinderDal 得到的
        }
       
        public void Insert()
        {
            string sql = @"INSERT INTO [EL_Organization].[User] ('Id', 'Name') VALUES (" + this.Id + "," + this.Name + ")";
            var ds = SqlHelper.Execute(CommandType.Text, sql);
        }
       
        public void Update()
        {
            // update this;
        }

public void Delete()
        {
            // delete this;
        }
       
        public UserActiveRecord FindOne(string id)
        {
            string sql = "select * from [EL_Organization].[User] where id=" + id;
            var ds = SqlHelper.ExecuteDataset(CommandType.Text, sql);

foreach (DataRow row in ds.Tables[0].Rows)
            {
                return new UserActiveRecord {Id = (string)row["Id"], Name = (string)row["Name"]}; ;
            }
           
            return null;
        }
   
        public List<UserActiveRecord> FindList(string name)
        {
            return null;
        }
       
        public void SomeOtherLogic()
        {
        }
    }

从上面的代码来看,活动记录这种模式不在 业务逻辑层 和 数据访问层,因为它们是一体的。而事务脚本 或者 表数据入口 和 行数据入口,多多少少可以存在两层的概念。

架构模式数据源模式之:表数据入口(Table Data Gateway)、行数据入口(Row Data Gateway)、活动记录(Active Record)的更多相关文章

  1. Saiku设置展示table数据不隐藏空的行数据信息(二十六)

    Saiku设置展示table数据不隐藏空的行数据信息 saiku有个 非空的字段 按钮,点击这个后,会自动的把空的行数据信息给隐藏掉,这里我们来设置一下让其行数据不隐藏,为空的就为空. 主要更改两个文 ...

  2. 架构模式数据源模式之:数据映射器(Data Mapper)

    一:数据映射器 关系型数据库用来存储数据和关系,对象则可以处理业务逻辑,所以,要把数据本身和业务逻辑糅杂到一个对象中,我们要么使用 活动记录,要么把两者分开,通过数据映射器把两者关联起来. 数据映射器 ...

  3. 表表达式,Substring, CharIndex, 多行数据变同一行的用法

    参考: https://www.cnblogs.com/cnki/p/9561427.html https://www.cnblogs.com/johnwood/p/6386613.html 1.表1 ...

  4. 架构模式中的Active Record和Data Mapper

    架构模式中的Active Record和Data Mapper 概念 在简单应用中,领域模型是一种和数据库结构一致的简单结构,对应每个数据库表都有一个领域类,在这种情况下,有必要让每个对象负责数据库的 ...

  5. QTreeView处理大量数据(使用1000万条数据,每次都只是部分刷新)

    如何使QTreeView快速显示1000万条数据,并且内存占用量少呢?这个问题困扰我很久,在网上找了好多相关资料,都没有找到合理的解决方案,今天在这里把我的解决方案提供给朋友们,供大家相互学习. 我开 ...

  6. bootstrap-switch:记一次很坑的问题(连续相同状态的多行数据只有第一个显示按钮,其他行没有开关初始化)

    先上截图,第234行都是禁用状态,但是只有第2行显示了禁用开关,后面的都没有开关初始化 检查下代码: onLoadSuccess: function(data){ {#获取行数据的状态#} conso ...

  7. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle

    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3.  ...

  8. 使用pandas导出PostgreSQL 模式下的所有表数据并保存

    PostgreSQL PostgreSQL 是一个非常强大的数据库,它是一个免费的对象-关系数据库服务器(数据库管理系统).PostgreSQL支持大部分 SQL 标准, 在语句上也有很大的相似的地方 ...

  9. .NET应用架构设计—适当使用活动记录模式代替领域模型模式

    阅读目录: 1.背景介绍 2.简单介绍领域模型模式.活动记录模式 3.活动记录模式的简单示例及要点 4.总结 1.背景介绍 对软件开发方法论有兴趣的博友应该发现最近“领域驱动设计”慢慢的被人发现被人实 ...

随机推荐

  1. Netty---相关

    http://www.infoq.com/cn/articles/netty-million-level-push-service-design-points/ ChannelOption用到的soc ...

  2. Django-ContentType-signals 实现牛逼玩法

    一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...

  3. django-QueryDict 对象

    在 HttpRequest 对象中,属性 GET 和 POST 得到的都是 django.http.QueryDict 所创建的实例.这是一个 django 自定义的类似字典的类,用来处理同一个键带多 ...

  4. 【WIN10】移植opencc到WIN10-UWP,實現自己的繁簡轉換工具

    花了週末兩天時間,將opencc移植成WIN10-UWP可用的庫,並完成自己的繁簡轉換工具. 我的繁簡轉換工具下載地址為:https://www.microsoft.com/store/apps/9n ...

  5. UEditor 的使用

    UEditor 的使用 一.UEditor 的使用 官方网站:http://ueditor.baidu.com/website/ 下载地址:http://ueditor.baidu.com/websi ...

  6. Codeforces Round #258 (Div. 2) . Sort the Array 贪心

    B. Sort the Array 题目连接: http://codeforces.com/contest/451/problem/B Description Being a programmer, ...

  7. CocoaPods第三方库管理工具

    http://code4app.com/article/cocoapods-install-usage

  8. mysql|表row_format的静态与动态,Compact

    innodb 一般对应 Compact  ,MyISAM 一般对应静态与动态 mysql中若一张表里面存在varchar.text以及其变形.blob以及其变形的字段的话,那么这个表其实也叫动态表,即 ...

  9. HDU 4786 Fibonacci Tree (2013成都1006题)

    Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  10. RPM软件包管理的查询功能 转

    RPM软件包管理的查询功能: 命令格式 rpm {-q|--query} [select-options] [query-options] RPM的查询功能是极为强大,是极为重要的功能之一:举几个常用 ...