一:表数据入口(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. Javassist学习总结

    今天在弄dubbo时出现了一个依赖缺少问题,就好奇研究一下,这个依赖是啥. javassist是一个字节码类库,可以用他来动态生成类,动态修改类等等 1.介绍Javassist 要想将编译时不存在的类 ...

  2. Java之路(四)数组初始化

    本文主要讲数组的初始化方法.可变参数列表以及可变参数列表对函数重载的影响. 1.数组初始化 定义数组的方式: int[] arr1; 或  int arr1[]; 数组初始化 通过上边的定义,我们只是 ...

  3. EntityManager的使用

    1.最基础的查询 CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<User> cq = cb. ...

  4. Django-Filter源码解析一

    Django Filter源码解析 最近在看Django-FIlter项目的源码,学习一下别人的开发思想: 整体介绍 首先,我从其中一个测试用例作为入口,开始了debug之路,一点一点的断点,分析它的 ...

  5. spring data redis的配置类RedisConfig

    package com.tz.config; import org.springframework.context.annotation.Bean; import org.springframewor ...

  6. java并发基础(四)--- 取消与中断

    <java并发编程实战>的第7章是任务的取消与关闭.我觉得这一章和第6章任务执行同样重要,一个在行为良好的软件和勉强运行的软件之间的最主要的区别就是,行为良好的软件能很完善的处理失败.关闭 ...

  7. IntraWeb XIV 类型速查表

    tkClass ================== IWUserSessionBase.TIWUserSessionBase < TDataModule < TComponent < ...

  8. 百度离线下载Tampermonkey脚本

    https://greasyfork.org/zh-CN/scripts/23635-%E7%99%BE%E5%BA%A6%E7%BD%91%E7%9B%98%E7%9B%B4%E6%8E%A5%E4 ...

  9. 解决Android LogCat 输出乱码的问题(转)

    Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的. 可以使用adb的logcat 命令来查看系统日志缓冲区的内容,但是在实际操作时,会发现在C ...

  10. Android签名详解

    1.什么是签名?      如果这个问题不是放在Android开发中来问,如果是放在一个普通的版块,我想大家都知道签名的含义.可往往就是将一些生活中常用的术语放在计算机这种专业领域,大家就开始迷惑了. ...