使用代理模式模拟ORM实体的延时加载

作者:小菜 更新时间:2025-02-26 点击数:
简介:.NET中的Entity Framework 和 java里面的 Hibernate都是ORM框架,它们中间都用到延时加载,延时加载对于提高性能,减小服务器内存

【菜科解读】

.NET中的Entity Framework 和 java里面的 Hibernate都是ORM框架,它们中间都用到延时加载,延时加载对于提高性能,减小服务器内存压力有很大的作用。

所谓延时加载,就是只有在第一次调用某个实体的方法或属性时才初始化该实体。

延时加载适用于创建开销大的对象。

如下,我采用代理模式模拟了一个简单的延时加载的例子。

首先,我定义了一个接口,名为IOperation,定义如下:

1 public interface IOperation 3 /// 4 /// 声明一个描述类信息的方法,由子类实现。

5 /// 6 void Describe(); 7 /// 8 /// 声明一个销毁订单的操作,由子类操作 9 /// 10 void DestoryOrder();11 }

然后定义两个实体类,Product类和Order类,分别表示两个相互关联的实体,在Product类中注入Order类的变量用以在Product类中调用Order类的实例方法。

并且让Product类实现IOperate接口。

Product类定义如下:

1 public class Product : IOperation 3 private Order _order; 4 public Product() 6 Console.WriteLine(">>开始初始化Product类..."); 7 Stopwatch sw = new Stopwatch(); 8 sw.Start(); 9 this._order = new Order();10 sw.Stop();11 Console.WriteLine(">>初始化Product类完成。

耗时:{0}秒", sw.ElapsedMilliseconds / 1000);13 public void Describe()15 Console.WriteLine(">>Product描述:我的是Product类的实例,Describe方法执行完成。

");17 public void DestoryOrder()19 Console.WriteLine(">>Product.DestoryOrder()方法开始执行...");20 if (_order != null)22 //调用Order类的Destroy实例方法,销毁自己。

23 _order.Destroy();24 Console.WriteLine(">>Product.DestoryOrder()方法执行完成。

");27 }

Order类定义如下:

1 public class Order 3 public Order() 5 Console.WriteLine(">>开始初始化Order类..."); 6 System.Threading.Thread.Sleep(5000); 7 Console.WriteLine(">>初始化Order类完成。

");10 public void Destroy()12 Console.WriteLine(">> Order 已销毁。

");14 }

然后在主程序里面调用一下:

1 static void Main(string[] args) 3 Console.WriteLine("==========不使用代理类调用Describe()方法==============="); 4 Product p = new Product(); 5 p.Describe(); 6 Console.WriteLine("==========不使用代理类调用DestoryOrder()方法==============="); 7 Product p2 = new Product(); 8 p2.DestoryOrder(); 9 Console.ReadKey();10 }

测试结果如下:

从上图中,我们可以看出,调用Describe()方法初始化Product类用了5秒,这是不是有问题?再看看上面的Describe()方法的实现,只简单的输出了一句话,怎么会用5秒?再看Product的构造函数里面,在初始化Product类的实例的时候,把Order类也初始化了,但是我这个Describe()方法并没有调用Order类的任何方法和属性,所以这就造成了不必要的内存开销,而且初始化了的Order类的实例也没有使用,产生了垃圾对象。

怎么解决这个问题呢?所以这个地方就得用代理了,代理是个什么东西呢?代理简单来说,就是制造一个与被调对象具有相同功能(这个相同功能通常由接口去规范)的类,在这个类中可以调用被调对象的方法,也可以自定义新的方法供调用方使用。

下面就是代理类的创建。

首先,我创建一个代理类,名为ProxyProduct,让它也实现IOperate接口,定义如下:

1public class ProxyProduct : IOperation 3 private IOperation entity; 5 public ProxyProduct(IOperation entity) 7 Console.WriteLine(">>开始初始化ProxyProduct..."); 8 Stopwatch sw = new Stopwatch(); 9 sw.Start();10 this.entity = entity;11 sw.Stop();12 Console.WriteLine(">>初始化ProxyProduct完成。

耗时:{0}秒", sw.ElapsedMilliseconds / 1000);14 /// 15 /// 实现IOperation的方法16 /// 17 public void Describe()19 Console.WriteLine(">>ProxyProduct描述:我的是ProxyProduct类的实例,Describe()方法执行完成。

");21 /// 22 /// 实现IOperation的方法23 /// 24 public void DestoryOrder()26 Console.WriteLine(">>ProxyProduct.DestoryOrder()方法开始执行...");27 if (entity == null)29 entity = new Product();31 entity.DestoryOrder();32 Console.WriteLine(">>ProxyProduct.DestoryOrder()方法执行完成。

");34}

在主程序里面测试一下:

1 static void Main(string[] args) 3 Console.WriteLine("==========使用代理类调用Describe()方法==============="); 4 IOperation desc = new ProxyProduct(null) as IOperation; 5 if (desc != null) 7 desc.Describe(); 9 Console.WriteLine("==========使用代理类调用DestoryOrder()方法===============");10 IOperation desc2 = new ProxyProduct(null) as IOperation;11 if (desc2 != null)13 desc2.DestoryOrder();15 Console.ReadKey();16 }

测试结果如下:

从上图看出,调用Describe()方法时耗时0秒,调用DestoryOrder()方法时,初始化代理类用了0秒,初始化Product类用了5秒,所以执行DestroyOrder()方法一共花费了5秒。

这样的结果是令人满意的,使用代理类就实现了“调用谁的方法,就初始化谁;不调用不初始化”的想法。

这样的话,如果我永远只调Describe()方法,那么我花费的时间永远是0秒,而不会产生额外的开销,这对性能优化有很大的帮助。

总结:代理模式应用之一:对于某些创建时需要很大开销的对象,我们可以使用代理让这个对象在第一次调用它的方法或属性时才创建它的实例,不调用它的方法或属性则永远不创建它的实例。

好处:性能优化,减小内存开销。

==================================================================================================================如下是java代码实现:接口:IOperate

1 public interface IOperate { 2 /** 3 * 声明一个描述类信息的方法,由子类实现。

4 */ 5 void describe(); 6 /** 7 * 声明一个销毁订单的方法,由子类实现。

8 */ 9 void destroyOrder();10 }

实现类:ProductBean

1 public class ProductBean implements IOperate { 2 private OrdersBean ordersBean; 4 /** 5 * 初始化ProductBean类的实例 6 */ 7 public ProductBean() { 8 System.out.println(">>开始初始化ProductBean...."); 9 long startTime = System.currentTimeMillis();10 this.ordersBean = new OrdersBean();11 long endTime = System.currentTimeMillis();12 System.out.println(">>初始化ProductBean完成。

耗时:" + (endTime - startTime) / 1000 + "秒");15 public void describe() {16 System.out.println(">>describe描述:我是ProductBean类,执行了describe()方法。

");19 public void destroyOrder() {20 System.out.println(">>开始执行ProductBean.destroyOrder()方法...");21 if (this.ordersBean != null) {22 this.ordersBean.destroy();23 System.out.println(">>ProductBean.destroyOrder()方法执行完成。

");26 }

实体类:OrderBean

1 public class OrdersBean { 2 public OrdersBean() { 3 System.out.println(">>开始初始化OrderBean....."); 4 InitOrder(); 5 System.out.println(">>初始化OrderBean完成。

"); 8 /** 9 * 初始化订单10 */11 private void InitOrder() {12 try {13 // 加载订单数据,这里模拟耗时3秒。

14 Thread.sleep(5000);15 } catch (Exception e) {16 e.printStackTrace();20 public void destroy() {21 System.out.println(">> Order 已销毁。

");23 }

代理类:ProxyProductBean

1 public class ProxyProductBean implements IOperate { 2 private IOperate bean; 4 public ProxyProductBean(IOperate bean) { 5 System.out.println(">>开始初始化ProxyProductBean....."); 6 long startTime = System.currentTimeMillis(); 7 this.bean = bean; 8 long endTime = System.currentTimeMillis(); 9 System.out.println(">>初始化ProxyProductBean完成。

耗时:" + (endTime - startTime) / 1000 + "秒");12 public void describe() {13 System.out.println(">>describe描述:我是ProxyProductBean类,执行了describe()方法。

");16 public void destroyOrder() {17 System.out.println(">>开始执行ProxyProductBean.destroyOrder()方法...");18 if (bean == null) {19 bean = new ProductBean();20 bean.destroyOrder();21 System.out.println(">>执行ProxyProductBean.destroyOrder()方法完成。

");24 }

测试类:

1 public class Test { 2 public static void main(String[] args) { 3 System.out.println("==========不使用代理类调用describe()方法==============="); 4 ProductBean productBean = new ProductBean(); 5 productBean.describe(); 6 System.out.println("==========使用代理类调用describe()方法==============="); 7 IOperate description = (IOperate) (new ProxyProductBean(null)); 8 description.describe(); 9 System.out.println("==========不使用代理类调用cascadeOperate()方法===============");10 ProductBean productBean2 = new ProductBean();11 productBean2.destroyOrder();12 System.out.println("==========使用代理类调用cascadeOperate()方法===============");13 IOperate description2 = (IOperate) (new ProxyProductBean(null));14 description2.destroyOrder();16 }

测试结果输出如下:==========不使用代理类调用describe()方法===============>>开始初始化ProductBean....>>开始初始化OrderBean.....>>初始化OrderBean完成。

>>初始化ProductBean完成。

耗时:5秒>>describe描述:我是ProductBean类,执行了describe()方法。

==========使用代理类调用describe()方法===============>>开始初始化ProxyProductBean.....>>初始化ProxyProductBean完成。

耗时:0秒>>describe描述:我是ProxyProductBean类,执行了describe()方法。

==========不使用代理类调用cascadeOperate()方法===============>>开始初始化ProductBean....>>开始初始化OrderBean.....>>初始化OrderBean完成。

>>初始化ProductBean完成。

耗时:5秒>>开始执行ProductBean.destroyOrder()方法...>> Order 已销毁。

>>ProductBean.destroyOrder()方法执行完成。

==========使用代理类调用cascadeOperate()方法===============>>开始初始化ProxyProductBean.....>>初始化ProxyProductBean完成。

耗时:0秒>>开始执行ProxyProductBean.destroyOrder()方法...>>开始初始化ProductBean....>>开始初始化OrderBean.....

使用,代理,模式,模拟,ORM,实体,的,延时,加载,

社保卡如何供给家里人使用?能直接用家人的社保卡看病吗?(2025

公司社保就是我们日常说的五险,包括包括养老保险、医疗保险、失业保险、工伤保险和生育保险。

其中养老保险、医疗保险和失业保险,这三种险是由企业和个人共同缴纳的保费,工伤保险和生育保险完全是由企业承担的。

在比例方面,养老保险单位承担20%,个人承担8%,医疗保险单位承担6%,个人2%;失业保险单位承担2%,个人1%。

五险是法定的,是保证劳动者的条款之一,一般公司都会为员工购买的。

社保卡里的凭证到底怎么给家人使用?能直接用家人的社保卡看病吗?随新社通小编来了解一下:社保卡怎么给家人用?绑定流程及方法社保卡里的余额给家人使用,主要可以通过以下几种方式实现:一、电子社保卡亲情服务此外,还可以通过电子社保卡的亲情服务功能,为家人提供便捷的电子社保卡签发和应用服务。

具体步骤如下:打开电子社保卡首页,点击右上角“我的”-“亲情服务”。

点击“添加”,验证电子社保卡密码后,阅读并同意添加亲情账户告知书。

输入要开通人的姓名、社保号码、亲情关系,点击“添加亲情账户”并上传身份凭证(小于16岁需同时上传人脸正面照)。

亲情服务绑定对象进行人脸识别操作,认证通过后则开通亲情服务成功。

通过电子社保卡亲情服务,可以帮家人查询个人社保权益单、进行社保待遇资格认证、办理社保网上转移申请等,同时也可以使用社保卡里的余额。

二、社保卡绑定家人通过社保卡的家庭共享功能,可以将社保卡的余额绑定给家人使用。

具体操作步骤如下:社会保险服务个人网页自助办理:登陆个人网页,进入社保业务办理-医疗业务办理-个人账户家庭共享-新增绑定,输入亲属社保电脑号、亲属身份证号及亲属关系,提交保存,即完成绑定。

到社保分局医疗保险窗口申请办理:在社保部门医保现金报销窗口刷卡绑定,刷被使用人的社保卡,并录入使用人的社保卡号。

在定点医院医疗保险办公室办理:在医院医保办,通过“网上医院”刷卡绑定,刷被使用人的卡,并录入使用人的社保卡号。

完成绑定后,家人在就医时就可以使用社保卡里的余额进行支付了。

需要注意的是,社保卡里的余额属于个人所有,给家人使用时需确保符合要求,不得进行违法违规操作。

另外,不同地区的社保卡使用可能有所不同,具体操作方法还需根据当地而定。

什么是社保个人家庭账户共济?怎么理解的?自1998年建立以来,一直实行社会统筹和个人账户相结合的模式,职工医保个人账户资金可用于支付本人就医购药个人负担部分费用。

2021年,将职工医保个人账户使用范围从职工本人,扩大到其参加基本医保的“配偶、父母、子女”,即医保个人账户可共济给家人使用;今年7月,进一步将职工医保个人账户共济亲属的范围由“配偶、父母、子女”,扩大至其参加基本医保的“近亲属”。

根据《中华人民共和国民法典》,配偶、父母、子女、兄弟姐妹、祖父母、外祖父母、孙子女、外孙子女为近亲属。

自1998年建立以来,一直实行社会统筹和个人账户相结合的模式,职工医保个人账户资金可用于支付本人就医购药个人负担部分费用。

2021年,将职工医保个人账户使用范围从职工本人,扩大到其参加基本医保的“配偶、父母、子女”,即医保个人账户可共济给家人使用;今年7月,进一步将职工医保个人账户共济亲属的范围由“配偶、父母、子女”,扩大至其参加基本医保的“近亲属”。

根据《中华人民共和国民法典》,配偶、父母、子女、兄弟姐妹、祖父母、外祖父母、孙子女、外孙子女为近亲属。

目前首批开通个人账户跨省家庭共济的地区(统筹区)有哪些?1、河南省(郑州市、信阳市)2、四川省(省本级、成都市、广安市)3、安徽省(淮南市)4、山东省(德州市)5、重庆市(云阳县)6、甘肃省(临夏回族自治州)7、江苏省(苏州市)8、湖北省(襄阳市、黄冈市、咸宁市、随州市、恩施土家族苗族自治州、潜江市)9、河北省(石家庄市、唐山市、秦皇岛市、邯郸市、邢台市、保定市、张家口市、承德市、沧州市、廊坊市、衡水市、辛集市、定州市、雄安新区、省本级)共31个地区(统筹区)已开通个人账户跨省共济使用。

社保卡里的凭证到底如何给家人使用?余额能直接给家人看病用吗?(2025年4月19日)

社保具体指的是什么?社保是为特定人口提供收入或补偿的社会经济体系。

包括五种保险,各有保险功能。

它强制实施,以劳动者为对象、特殊事件为内容、保护基本生活为目的,对社会稳定、发展和劳动者权益意义重大。

社保卡怎么供给家里人使用随新社通小编来了解一下:社保卡里的职工个人账户如何共济给家人?社保卡里的余额给家人使用,需要怎么绑定呢,主要可以通过以下几种方式实现:一、电子社保卡亲情服务此外,还可以通过电子社保卡的亲情服务功能,为家人提供便捷的电子社保卡签发和应用服务。

具体步骤如下:打开电子社保卡首页,点击右上角“我的”-“亲情服务”。

点击“添加”,验证电子社保卡密码后,阅读并同意添加亲情账户告知书。

输入要开通人的姓名、社保号码、亲情关系,点击“添加亲情账户”并上传身份凭证(小于16岁需同时上传人脸正面照)。

亲情服务绑定对象进行人脸识别操作,认证通过后则开通亲情服务成功。

通过电子社保卡亲情服务,可以帮家人查询个人社保权益单、进行社保待遇资格认证、办理社保网上转移申请等,同时也可以使用社保卡里的余额。

二、社保卡绑定家人通过社保卡的家庭共享功能,可以将社保卡的余额绑定给家人使用。

具体操作步骤如下:社会保险服务个人网页自助办理:登陆个人网页,进入社保业务办理-医疗业务办理-个人账户家庭共享-新增绑定,输入亲属社保电脑号、亲属身份证号及亲属关系,提交保存,即完成绑定。

到社保分局医疗保险窗口申请办理:在社保部门医保现金报销窗口刷卡绑定,刷被使用人的社保卡,并录入使用人的社保卡号。

在定点医院医疗保险办公室办理:在医院医保办,通过“网上医院”刷卡绑定,刷被使用人的卡,并录入使用人的社保卡号。

完成绑定后,家人在就医时就可以使用社保卡里的余额进行支付了。

需要注意的是,社保卡里的余额属于个人所有,给家人使用时需确保符合要求,不得进行违法违规操作。

另外,不同地区的社保卡使用可能有所不同,具体操作方法还需根据当地而定。

什么是社保个人家庭账户共济?怎么理解的?自1998年建立以来,一直实行社会统筹和个人账户相结合的模式,职工医保个人账户资金可用于支付本人就医购药个人负担部分费用。

2021年,将职工医保个人账户使用范围从职工本人,扩大到其参加基本医保的“配偶、父母、子女”,即医保个人账户可共济给家人使用;今年7月,进一步将职工医保个人账户共济亲属的范围由“配偶、父母、子女”,扩大至其参加基本医保的“近亲属”。

根据《中华人民共和国民法典》,配偶、父母、子女、兄弟姐妹、祖父母、外祖父母、孙子女、外孙子女为近亲属。

自1998年建立以来,一直实行社会统筹和个人账户相结合的模式,职工医保个人账户资金可用于支付本人就医购药个人负担部分费用。

2021年,将职工医保个人账户使用范围从职工本人,扩大到其参加基本医保的“配偶、父母、子女”,即医保个人账户可共济给家人使用;今年7月,进一步将职工医保个人账户共济亲属的范围由“配偶、父母、子女”,扩大至其参加基本医保的“近亲属”。

根据《中华人民共和国民法典》,配偶、父母、子女、兄弟姐妹、祖父母、外祖父母、孙子女、外孙子女为近亲属。

目前首批开通个人账户跨省家庭共济的地区(统筹区)有哪些?1、河南省(郑州市、信阳市)2、甘肃省(临夏回族自治州)3、山东省(德州市)4、江苏省(苏州市)5、湖北省(襄阳市、黄冈市、咸宁市、随州市、恩施土家族苗族自治州、潜江市)6、河北省(石家庄市、唐山市、秦皇岛市、邯郸市、邢台市、保定市、张家口市、承德市、沧州市、廊坊市、衡水市、辛集市、定州市、雄安新区、省本级)7、重庆市(云阳县)8、安徽省(淮南市)9、四川省(省本级、成都市、广安市)共31个地区(统筹区)已开通个人账户跨省共济使用。

加入收藏
               

使用代理模式模拟ORM实体的延时加载

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录