使用代理模式模拟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/04/03)

社保卡怎么供给家里人使用随新社通小编来了解一下:社保卡是什么意思社保卡是由人力资源和社保部统一规划,由各地人力资源和社保部门面向社会发行,用于人力资源和社保各项业务领域的集成电路(IC)卡。

面向城镇从业人员、失业人员和离退休人员发放的称为社保(个人)卡,面向用人单位发放的称为社保(用人单位)卡。

人社部表示将用5年左右时间,使社保卡普遍具有金融功能。

社保卡信息包含卡面基本信息和卡内信息。

其中卡面基本信息为持卡人姓名、卡号、公民身份号码、发卡日期、有效期等。

卡内记载了持卡人的个人状态(如就业、失业、退休等)、社会保险缴费情况、养老保险个人账户信息、医疗保险个人账户信息、职业资格和技能、就业经历、工伤及职业病伤残程度等信息。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

在哪里查社保缴费明细表,柳州如何查询个人参保信息、医保缴费记录、医保使用记录?

很多人不知道应该如何查询自己的社保缴费记录,所以会问起,下面对此进行了介绍,希望有所帮助。

在哪里查社保缴费明细表?柳州查询社保缴费明细表有几种方式:登录当地社保部门官网查询;用社保手机APP查询;到当地社保经办机构服务大厅查询;部分地区可通过社保自助服务终端查询,可按需选择查询方式。

具体详细内容和新社通app小编一起来看看。

一、柳州在哪里查社保缴费明细表通常可以通过以下几种方式查询社保缴费明细表:一是登录当地社保部门的官网,在网站的个人社保查询板块,输入个人社保账号、密码及验证码等信息后,即可查询到社保缴费明细。

二是通过社保部门推出的手机APP进行查询,下载并安装相应APP后,按照提示进行注册登录,在个人中心中找到社保缴费明细查询选项。

三是前往当地社保经办机构的服务大厅,在窗口办理社保查询业务,向工作人员提供个人相关信息,他们会协助查询并打印出社保缴费明细表。

四是一些地区还开通了社保自助服务终端,在社保经办机构或指定地点放置有这些终端,通过终端的操作页面可以查询社保缴费明细。

具体可根据当地实际情况选择合适的查询方式。

二、现在年轻人都交社保吗并非所有年轻人都交社保。

社保通常包括养老保险、医疗保险、失业保险、工伤保险和生育保险。

对于一些在正规企业或单位工作的年轻人,单位会按照规为其缴纳社保,这是企业的法定义务。

这些年轻人通常能较为规范地享受社保待遇。

然而,也有部分年轻人处于灵活就业状态,如自由职业者、个体工商户等,他们可能需要自行选择缴纳社保的方式和范围。

有些地方提供了灵活就业社保缴纳渠道,这些年轻人可以根据自身经济状况和需求选择缴纳养老保险和医疗保险等。

还有一些年轻人可能因各种原因未参加社保,比如对社保方案了解不足、经济压力较大等。

但从长远来看,参加社保对个人的养老、医疗等方面有重要保护作用,建议年轻人根据自身情况积极考虑参加社保。

加入收藏
               

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

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录