一:表数据入口(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. 关于 contentWindow, contentDocument

    没有永恒的技术只有变态的需求,没有好说的客户只有无奈的开发者, 如果iframe的出现是一个错误的话,iframe里边在来一个iframe那是错上加错,神话没有在远古的尘嚣中消失,却在怀具的今天不断上 ...

  2. UEditor插入视频,Object Iframe等标签被过滤问题处理

    UEditor插入视频由于兼容性问题,需要再处理一个视频代码,但是新版ueditor不支持Objec IFrame标签,所以要加入// xss过滤白名单 名单来源: https://raw.githu ...

  3. # Java反射2——获取实体所有属性和方法,并对属性赋值

    1.一个普通的实体Person: private int id; private String name; private Date createdTime; ... //其它字段 // get se ...

  4. 洛谷P3964 [TJOI2013]松鼠聚会 [二分答案,前缀和,切比雪夫距离]

    题目传送门 松鼠聚会 题目描述 草原上住着一群小松鼠,每个小松鼠都有一个家.时间长了,大家觉得应该聚一聚.但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理. 每个小松鼠的家可以用一个点x,y表示, ...

  5. Netty---相关

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

  6. webpack1.x环境配置与打包基础【附带各种 "坑" 与解决方案!持续更新中...】

    首先介绍传统模块化开发的主流方案: 1.基与CMD的sea.js,玉伯提出的解决方案,据说原来京东团队在使用.用时才定义,就近加载. 2.基于AMD的require.js,之前在用.提前声明与定义.国 ...

  7. Centos 7.4下 部署openstack Queens 计算节点qemu高版本问题

    sed -i 's/$contentdir/centos/g' /etc/yum.repos.d/CentOS-QEMU-EV.repo 这样既可正常安装compute服务

  8. 8.7 正睿暑期集训营 Day4

    目录 2018.8.7 正睿暑期集训营 Day4 A 世界杯(贪心) B 数组(线段树) C 淘汰赛 考试代码 A B C 2018.8.7 正睿暑期集训营 Day4 时间:5h(实际) 期望得分:. ...

  9. android 获取系统默认路径

    Environment.getDataDirectory().getPath() : /dataEnvironment.getDownloadCacheDirectory().getPath()  : ...

  10. Hadoop化繁为简(一)-从安装Linux到搭建集群环境

    简介与环境准备 hadoop的核心是分布式文件系统HDFS以及批处理计算MapReduce.近年,随着大数据.云计算.物联网的兴起,也极大的吸引了我的兴趣,看了网上很多文章,感觉还是云里雾里,很多不必 ...