博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ORM内核原理解析之:延迟加载
阅读量:7210 次
发布时间:2019-06-29

本文共 3781 字,大约阅读时间需要 12 分钟。

   延迟加载(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
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
(); 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
myshops; public List
myShops {
get {
if (myshops != null) return myshops; else {
///根据_UserID获取商户相信信息。赋值 myshops = new List
(); 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
> myshops; public List
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
> ( () =>(new List
()) ); } }

运行结果同上,这里需要注意点就是虽然我们在User中构造函数实现了Lazy<List<Shop>>类的实例,但是List<Shop>是未被实例化的,我们需要在Lazy的构造函数中指定他的回调函数。

还需注意的是上面的更改我们应用到了单例模式来实现List<Shop>是唯一的。

看以看出,Lazy<T>的引入使我们大大的简便了我们延迟初始化。

上传下

转载地址:http://zrrum.baihongyu.com/

你可能感兴趣的文章
《二叉树》学习心得
查看>>
【基础】CSS实现多重边框的5种方式
查看>>
Eclipse下把jar包放到工程lib下和通过buildpath加载有什么不同(解决找不到类的中级方法)...
查看>>
gradle新建工程,多项目依赖,聚合工程
查看>>
变量命名神器Codelf
查看>>
iBase4J部署总结
查看>>
IASetIndexBuffer Offset
查看>>
TeamLab安装及使用
查看>>
很安逸的离线API文档查询工具Dash和Zeal
查看>>
ICAP: 互换客户端地址协议
查看>>
Nginx-rtmp 直播媒体实时流实现
查看>>
C++ const 理解
查看>>
Linux进程管理 (7)实时调度
查看>>
基于鲁棒图进行概念架构设计
查看>>
Permission denied: exec of '/var/www/html/bugzilla/index.cgi' failed
查看>>
LESS CSS 框架简介与使用
查看>>
2014.09线上课堂报名帖:敏捷个人手机应用使用
查看>>
C# 重启exe
查看>>
Web 服务器 之 简易WWW服务器的架设
查看>>
一种电子病历系统软件框架思想
查看>>