我的BO

1-我的BO之强类型

2-我的BO之数据保护

3-我的BO之状态控制

4-我的BO之导航属性

数据需要导航

数据之间普遍存在关系,做业务处理时往往也是按照关系在数据之间查询和处理。业务处理可看作是各种检查和计算后,保存结果。而检查和计算往往意味着要查数据A,以及数据A相关的数据B,数据B相关的数据C……。

BO 与数据表相对应。一个 BO 类对应一个数据表,一个 BO 对象对应数据表中的一条记录。表间的关系,也是 BO 间的关系。典型的是一对多关系。比如 “买家-订单-订单明细”三者的关系是:一个买家可以拥有多个订单,一个订单对应多个订单明细;反过来,一个订单明细对应一个订单,一个订单对应一个买家。订单是买家的子对象,买家是订单的父对象。

当得到一个订单 BO 时,希望可以通过它的属性得到它的明细,明细是一个 BO 集合,希望可以通过它的另一个属性得到它的买家 BO。同理,当得到一个订单明细 BO,希望可以通过它的一个属性得到它的订单 BO。

通过 BO 的属性获取到另一个 BO 或 BO 的集合,这种属性叫做 BO 的导航属性。

对null值的处理

当父对象可能为null时,导航到父对象的属性有两个,一个是Xxx,另一个是XxxOrNull。比如一个学生一般是对应一个班级,但如果业务逻辑允许新生报到时暂未分配到班级,学生的班级属性就可能为null。为了准确地处理null值的问题,学生的班级对应两个属性:ClassClassOrNull。并规定,Class这个属性不返回null,学生当前没有对应班级时,则抛异常,如果希望返回null而非抛异常,则使用ClassOrNull。当父对象不允许为null时,则不提供XxxOrNull属性。

子对象一般表现为父对象的一个集合属性,若一个对象的子对象数量为零,则规定返回空(Empty)集合,而不是null

class 班级Bo extends BoBase {
public List<学生Bo> get学生List() {
Long id = this.getId();
return boProvider.list学生By班级Id(id); // 见说明1
}
} class 学生Bo extends BoBase {
public 班级Bo get班级() {
Long 班级Id = this.get班级Id();
return boProvider.get班级(班级Id);
}
public 班级Bo get班级OrNull() {
if (this.get班级Id() == null)
return null;
return this.get班级(); // 见说明2
}
}

说明:

  1. boProviderBoBase的属性,一切的 BO 对象都由boProvider产生。
  2. 如果班级Id不是null,却在数据库中找不到该班级数据,则还是会抛异常,也应该抛异常。
  3. 为了便于说明且不影响道理的表达,这里使用了中文命名,实际项目中并非如此。

优点

  • 导航属性让使用者方便地得到 BO 对象的相关对象,屏蔽了内部关系的细节,使用方便。
  • 导航属性包含了找不到时返回null还是抛异常的逻辑,避免了到处编写重复的代码,减少了对null值的处理不当导致空引用异常的风险。
  • 效果:只要得到一个 BO 对象,就可以得到与它相关的全部对象,使业务逻辑代码简洁、安全、灵活。

展望

目前的导航属性是只读的,这点不够面向对象(OO),只是因为实现起来简单。未来若有需要,可以提供修改导航属性同时修改关系的功能,用起来更加OO,可能有一些复杂的技术细节问题要解决。

目前通过导航属性获取(BO)对象,每次都从数据库装载,一定概率下会产生多余的查询。解决方法是在内存中统一缓存,通过ID判断若内存已有则不从数据库中取。这个方案一方面会增加一点内存开销,同时为了满足“就算内存中有,也要从数据库装载”的需求,需要设计复杂一点的机制。还需要解决前面的业务修改了的对象,后面的业务(同一个请求)获取是否应该获取修改后的这个对象版本的问题,我目前觉得应该获取修改后的版本,而不是数据库中那个。无论获取到的是哪个版本,会不会在业务处理上造成Bug,有待进一步研究。

系列导航

1-我的BO之强类型

2-我的BO之数据保护

3-我的BO之状态控制

4-我的BO之导航属性

我的BO之导航属性的更多相关文章

  1. 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...

  2. 《Entity Framework 6 Recipes》中文翻译系列 (23) -----第五章 加载实体和导航属性之预先加载与Find()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-2  预先加载关联实体 问题 你想在一次数据交互中加载一个实体和与它相关联实体. ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (25) ------ 第五章 加载实体和导航属性之加载完整的对象图和派生类型上的导航属性

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-5  加载完整的对象图 问题 你有一个包含许多关联实体的模型,你想在一次查询中, ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-7  在别的LINQ查询操作中使用Include()方法 问题 你有一个LINQ ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9  关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (28) ------ 第五章 加载实体和导航属性之测试实体是否加载与显式加载关联实体

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-11  测试实体引用或实体集合是否加载 问题 你想测试关联实体或实体集合是否已经 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-13  过滤预先加载的实体集合 问题 你想过滤预先加载的实体集合,另外,你想使用 ...

  8. 关系与导航属性(摘自微软MSDN)

    关系与导航属性 本主题概述实体框架如何管理实体间的关系.还对如何映射和操作关系提供了一些指南. 关系.导航属性和外键 在关系数据库中,表之间的关系(也称为关联)是通过外键定义的.外键 (FK) 是用于 ...

  9. EF架构~为导航属性赋值时ToList()的替换方案

    回到目录 今天在进行EF开发时,遇到一个问题,在进行join查询时,类中的一个集合类型的导航属性,在给它赋值时,将查询出来的结果ToList()后,出错了,linq to entity不支持这种操作, ...

随机推荐

  1. PHP 的闭包

    匿名函数 提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它.声明一个匿名函数是这样: 1 $func = function() { 2 3 }; //带结 ...

  2. 【转载】Windows检测到IP地址冲突

    今天在使用电脑的过程中,突然弹出个提示,Windows检测到IP地址冲突,此网络中的另一台计算机与该计算机的IP地址相同.联系你的网络管理员解决此问题,有关详细信息,请参阅Windows系统日志.查阅 ...

  3. 1+x证书学习日志——css常用属性

     ## css常用属性:             1:文本属性:                 文本大小:  font-size:18px;                 文本颜色    colo ...

  4. Elasticsearch vs Solr 搜索引擎对比和选型

    前言 全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选. 基于Lucene它可以快速地储存.搜索和分析海量数据.维基百科.Stack Overflow.Githu ...

  5. 【DevOps】在CentOS中安装DockerCE

    准备 安装好CentOS7,拥有root账号密码,使用客户端登录. 安装 启动进入root用户,复制以下代码执行即可 yum install -y yum-utils device-mapper-pe ...

  6. Mysql安装与问题合集

    下载mysql https://dev.mysql.com/downloads/mysql/ 下载历史版本 看这篇文章 https://www.cnblogs.com/reyinever/p/8551 ...

  7. 目录-java并发基础知识

    ====================== 1.volatile原理 2.ThreadLocal的实现原理(源码级) 3.线程池模型以及核心参数 4.HashMap的实现以及jdk8的改进(源码级) ...

  8. MyBatis3_[tp-26-27]_映射文件_select_返回List_记录封装Map:返回单个元素的Map或者整体Map集合

    笔记要点出错分析与总结工程组织 1.定义接口 public interface EmployeeMapper { //多条记录封装到一个map中: Map<Integer,Employee> ...

  9. 大数据之路week07--day04 (YARN,Hadoop的优化,combline,join思想,)

    hadoop 的计算特点:将计算任务向数据靠拢,而不是将数据向计算靠拢. 特点:数据本地化,减少网络io. 首先需要知道,hadoop数据本地化是指的map任务,reduce任务并不具备数据本地化特征 ...

  10. vueRouter history模式下 nginx配置

    对于VUE的router[mode: history]模式(这里主要是为了去除链接上的"#")开发的时候,一般都不出问题.是因为开发时用的服务器为node,Dev环境中已配置好了, ...