ORM内核原理解析之:延迟加载
延迟加载(lazy load)也成为懒加载,基本用于ORM中数据对象的一种默认加载方式,简单点讲延迟加载机制是为了避免无所谓的性能开销而提出来的,所谓延迟加载就是当真正需要数据的时候,才真正的执行数据加载操作。可以简单的理解为,只有使用的时候,才会实例化对象。
最大的有点就是能够大大的提高系统的性能。
通过一个案例来讲解,举一个很大众的应用场景,在大多的B2C应用中会设计到到用户开店的情况,这样我们就设计一个会员表,一个店铺表,当然一个会员可以开很多歌店铺,也就是说这里面一对多的映射。
看一下类图:
两个实体类,聚合关系,下面看一下第一种代码结构:
using System;using System.Collections.Generic;namespace LazyLoadShop{class Program {static void Main(string[] args) { Users user = new Users("wu", "11"); Console.WriteLine("该用户所拥有的店铺有:"); Console.ReadKey();foreach (Shop shop in user.myShops) { Console.WriteLine(shop.ShopName); } Console.Read(); } }public class Users {public int UserID { get; set; }public string UserName { get; set; }public string PassWrod { get; set; }public List<Shop> myShops { get; set; }public Users(string _name, string _passWrod) {this.UserName = _name;this.PassWrod = "11"; //根据用户名从数据库提取密码 this.UserID = 123; Console.WriteLine("大家好,我是" + _name); if (this.PassWrod.Equals(_passWrod)) {///根据_UserID获取商户相信信息。赋值 myShops = new List<Shop>(); myShops.Add(new Shop(this.UserID)); } } } public class Shop {public Shop(int _UserID) {this.ShopID = 1;this.UserID = _UserID;this.ShopUrl = "www.ss.com";this.ShopName = "超人店铺"; }public int ShopID { get;set; }public int UserID { get;set; }public string ShopName { get; set; }public string ShopUrl { get; set; } } }
看一下运行结果:
这种结构应对一般的需求是没问题的,看一下上面的代码,可以看到,店铺(Shop)类是在用户(User)的构造函数中实现的实例化,也就是说我们在实例化用户(User)的时候,我们的店铺(Shop)类同样被实例化,当然,在这种应用场景下是没问题,但是假如应用场景变化了呢,一个用户对应N个店铺,也就是说,在我操作User的时候同样也在携带者店铺(Shop)这个类,显然这种方式会对性能有所损耗,尤其当我们只需要用户(User)不需要店铺(Shop)的时候,这简直就是一种内存浪费,我们想要达到的效果是:我们需要什么对象你给我实例化什么
根据这个需求,我们更改一下代码结构,我们只需要更改下用户类(User),第二版:
public class Users {public int UserID { get; set; }public string UserName { get; set; }public string PassWrod { get; set; }private List<Shop> myshops;public List<Shop> myShops {get {if (myshops != null)return myshops;else {///根据_UserID获取商户相信信息。赋值 myshops = new List<Shop>(); myShops.Add(new Shop(this.UserID));return myshops; }; } }public Users(string _name, string _passWrod) {this.UserName = _name;this.PassWrod = "11"; //根据用户名从数据库提取密码 this.UserID = 123; Console.WriteLine("大家好,我是" + _name); } }
我们在User类中公开了List<Shop>通过判断是否为空,而延迟实例化到店铺类(Shop)中,运行结果通第一版,其实延迟加载在ORM中很多成熟的框架已经采用这种思路,当然在.net中不能落伍的,在.net 4.0中微软已经为我们提供了专门用于延迟加载的类库Lazy<>类,我们看一下通过该类我们怎样实现店铺(Shop)类的延迟加载。
同样我们还是只需要更改用户类(User),第三版代码:
public class Users {public int UserID { get; set; }public string UserName { get; set; }public string PassWrod { get; set; }private readonly Lazy<List<Shop>> myshops;public List<Shop> myShops {get { myshops.Value.Add(new Shop(this.UserID));return myshops.Value; } }public Users(string _name, string _passWrod) {this.UserName = _name;this.PassWrod = "11"; //根据用户名从数据库提取密码 this.UserID = 123; Console.WriteLine("大家好,我是" + _name); myshops = new Lazy<List<Shop>> ( () =>(new List<Shop>()) ); } }
运行结果同上,这里需要注意点就是虽然我们在User中构造函数实现了Lazy<List<Shop>>类的实例,但是List<Shop>是未被实例化的,我们需要在Lazy的构造函数中指定他的回调函数。
还需注意的是上面的更改我们应用到了单例模式来实现List<Shop>是唯一的。
看以看出,Lazy<T>的引入使我们大大的简便了我们延迟初始化。
上传下源码
ORM内核原理解析之:延迟加载相关推荐
- Qt QComboBox内核原理解析
关于QComboBox内核是如何实现的,原理是如何的,分析如下: QComboBox是继承自QWidget重写的窗口,的111区是用QLineEdit实现的,源码如下: QLineEdit *line ...
- mybatis延迟加载原理解析
延迟加载前言: 在很多真实的实战的业务场景中,由于业务的复杂度,都会让我们进行过多的进行一些连接查询,在数据量少的时候,我们或许感受不到查询给我们带来的效率影响,在数据量和业务复杂的时候我们进行过多的 ...
- 2021年大数据Spark(二十二):内核原理
目录 Spark内核原理 RDD 依赖 窄依赖(Narrow Dependency) Shuffle 依赖(宽依赖 Wide Dependency) 如何区分宽窄依赖 ...
- 一篇不一样的docker原理解析 提高篇
在上一篇 一篇不一样的docker原理解析 - uncle creepy的文章 - 知乎专栏 中,主要讨论了容器和虚拟机的区别,在实现细节上并没有深入,只是点到即止,在这篇提高篇中,将详细讨论容器的实 ...
- SparkSQL 之 Shuffle Join 内核原理及应用深度剖析-Spark商业源码实战
本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客.版权声明:禁止转载,欢迎学习.QQ邮箱 ...
- linux内核深度解析_十年磨一剑,第一本龙芯平台的Linux内核书来了
<用"芯"探核:基于龙芯的Linux内核探索解析>是一本基于龙芯平台,结合源代码来探索和解析Linux-5.x内核的书. 市面上解析Linux 内核的经典书籍已有不少, ...
- 实验楼 linux内核原理与分析,《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- [转载] kprobe原理解析(一)
From: https://www.cnblogs.com/honpey/p/4575928.html kprobe原理解析(一) kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工 ...
- Merkle Tree(默克尔树)原理解析
Merkle Tree(默克尔树)原理解析 一.Merkle Tree 1.1 Merkle Tree的特点 二.Hash list 三.Merkle tree VS Hash list 四.Merk ...
最新文章
- SQL Server 2005自带的Service Broker功能
- 与善淘网一起做慈善商店
- life at University of Liverpool
- zabbix (二)安装
- 再谈如何写好技术文档?
- SSM实现会议室预约管理系统
- 大数据网站汇总(数据搜集、大数据竞赛、)
- 区块链(二)-形象的理解区块链和中心化的技术差异
- js QQ音乐歌词显示在浏览器标题
- 1个钟是多久_一个时辰是多久,一个时辰是几个小时?
- 美团3年阿里4年,我的坎坷进阶之路
- TRS的WCM历史漏洞
- 从营销的角度看宜家成功的秘诀
- vue文本框中禁止输入空格和使用enter键
- 瑞芯微rk356x板子快速上手
- 一文尽揽2018谷歌I/O大会:AI很酷 Android P拯救睡前玩手机综合症
- linux下使用tar命令解压.tar.gz文件是参数的说明
- android查看内存使用情况
- Bmob小程序模板消息
- 回顾Bob大叔的简洁架构
热门文章
- mvc源码解读(10)-ParameterDescriptor方法Action方法的参数描述对象
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(四):使用 命名空间 简化配置...
- Struts2中我所遇到的内存溢出(java.lang.OutOfMemoryError)异常错误介绍
- js中判断对象数据类型的方法
- android 自定义 打包文件类型,Android Studio配置打包生成自定义文件名
- java reader 方法_Java Reader reset()方法
- MySQL 函数 —— GROUP_CONCAT
- ABAP和Java单例模式的攻防
- 阿里巴巴获评《福布斯》全球最有投资价值公司
- OSGL 工具库 - 类型转换的艺术