zoukankan      html  css  js  c++  java
  • NHibernate从入门到精通系列(5)——持久对象的生命周期(下)

      内容摘要

        持久化类

        持久化生命周期中的回调

        合法性验证回调

        一、持久化类(Persistent Classes)

          1.1 什么是持久化类

      回答这个问题之前先回答什么是持久化。所谓的持久化就是把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。然而持久化类就是持久化数据的载体,在应用程序中,用来实现业务问题实体的(如,在电子商务应用程序中的Customer和Order) 类就是持久化类。不能认为所有的持久化类的实例都是持久的状态——一个实例的状态也可能 是瞬时的或脱管的。 如果这些持久化类遵循一些简单的规则,NHibernate能够工作得更好,这些规则也被称作 简单传统CLR对象(POCO:Plain Old CLR Object)编程模型。

      之前用到的“Product”类,就是持久化类

    Product
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Domain
    {
        
    /// <summary>
        
    /// 商品
        
    /// </summary>
        public class Product
        {
            
    /// <summary>
            
    /// ID
            
    /// </summary>
            public virtual Guid ID { getset; }

            
    /// <summary>
            
    /// 编号
            
    /// </summary>
            public virtual string Code { getset; }

            
    /// <summary>
            
    /// 名称
            
    /// </summary>
            public virtual string Name { getset; }

            
    /// <summary>
            
    /// 规格
            
    /// </summary>
            public virtual string QuantityPerUnit { getset; }

            
    /// <summary>
            
    /// 单位
            
    /// </summary>
            public virtual string Unit { getset; }

            
    /// <summary>
            
    /// 售价
            
    /// </summary>
            public virtual decimal SellPrice { getset; }

            
    /// <summary>
            
    /// 进价
            
    /// </summary>
            public virtual decimal BuyPrice { getset; }

            
    /// <summary>
            
    /// 备注
            
    /// </summary>
            public virtual string Remark { getset; }
        }
    }

      然而持久化类须满足一定的规则。

          1.2持久化类的规则

    • 实现一个默认的(即无参数的)构造方法(constructor)
    • 提供一个标识属性(identifier property)(可选)
    • 使用非密封(non-sealed)类以及虚方法(virtual methods) (可选)

      二、持久化生命周期中的回调

      2.1 ILifecycle接口介绍

      持久化类可以实现ILifecycle接口,它可以提供一些用于回调的方法, 可以让持久化对象在Save或Load之后,或者在Delete或Update之前进行必要的初始化与清除步骤。

      让我们看一下ILifecycle接口 

    ILifecycle
        public interface ILifecycle
        {
            LifecycleVeto OnDelete(ISession s);
            
    void OnLoad(ISession s, object id);
            LifecycleVeto OnSave(ISession s);
            LifecycleVeto OnUpdate(ISession s);
        }

      其中ILifecycle接口的方法如下:

    (1)

    OnSave - 在对象即将被save或者insert的时候回调

    (2)

    OnUpdate - 在对象即将被update的时候回调(也就是对象被传递给ISession.Update()的时候)

    (3)

    OnDelete - 在对象即将被delete(删除)的时候回调

    (4)

    OnLoad - 在对象刚刚被load(装载)后的时候回调

      如果OnSave(), OnUpdate() 或者 OnDelete()返回LifecycleVeto.Veto,那么操作就被悄悄地取消了。 如果其中抛出了CallbackException异常,操作被取消,这个异常会被继续传递给应用程序。

      2.2 ILifecycle的demo

      实体:  

    Product
    /// <summary>
        
    /// 商品
        
    /// </summary>
        public class Product : ILifecycle
        {
            
    /// <summary>
            
    /// ID
            
    /// </summary>
            public virtual Guid ID { getset; }

            
    /// <summary>
            
    /// 编号
            
    /// </summary>
            public virtual string Code { getset; }

            
    /// <summary>
            
    /// 名称
            
    /// </summary>
            public virtual string Name { getset; }

            
    /// <summary>
            
    /// 规格
            
    /// </summary>
            public virtual string QuantityPerUnit { getset; }

            
    /// <summary>
            
    /// 单位
            
    /// </summary>
            public virtual string Unit { getset; }

            
    /// <summary>
            
    /// 售价
            
    /// </summary>
            public virtual decimal SellPrice { getset; }

            
    /// <summary>
            
    /// 进价
            
    /// </summary>
            public virtual decimal BuyPrice { getset; }

            
    /// <summary>
            
    /// 备注
            
    /// </summary>
            public virtual string Remark { getset; }


            
    public virtual LifecycleVeto OnDelete(NHibernate.ISession s)
            {
                Console.WriteLine(
    "您调用了Delete()方法!");
                
    return LifecycleVeto.NoVeto;
            }

            
    public virtual void OnLoad(NHibernate.ISession s, object id)
            {
                Console.WriteLine(
    "您调用了Load()方法!");
            }

            
    public virtual LifecycleVeto OnSave(NHibernate.ISession s)
            {
                Console.WriteLine(
    "您调用了Save()方法!");
                
    return LifecycleVeto.NoVeto;
            }

            
    public virtual LifecycleVeto OnUpdate(NHibernate.ISession s)
            {
                Console.WriteLine(
    "您调用了Update()方法!");
                
    return LifecycleVeto.NoVeto;
            }
        }

      单元测试:

    LifecycleTest
    [TestFixture]
        
    public class LifecycleTest
        {
            
    private ISessionFactory sessionFactory;

            
    private static readonly Guid s_id = Guid.NewGuid();

            [SetUp]
            
    public void Init()
            {
                var cfg 
    = new NHibernate.Cfg.Configuration().Configure("Config/hibernate.cfg.xml");
                sessionFactory 
    = cfg.BuildSessionFactory();
            }

            [Test]
            
    public void SaveTest()
            {
                
    using (ISession session = this.sessionFactory.OpenSession())
                {
                    
    using (ITransaction tran = session.BeginTransaction())
                    {
                        
    try
                        {
                            var product 
    = new Product
                            {
                                ID 
    = s_id,
                                BuyPrice 
    = 10M,
                                Code 
    = "ABC123",
                                Name 
    = "电脑",
                                QuantityPerUnit 
    = "20x1",
                                SellPrice 
    = 11M,
                                Unit 
    = ""
                            };

                            session.Save(product);

                            tran.Commit();
                        }
                        
    catch (Exception ex)
                        {
                            tran.Rollback();
                            
    throw ex;
                        }
                    }
                }
            }

            [Test]
            
    public void UpdateTest()
            {
                
    using (ISession session = this.sessionFactory.OpenSession())
                {
                    
    using (ITransaction tran = session.BeginTransaction())
                    {
                        
    try
                        {
                            var product 
    = session.Load<Product>(s_id);

                            product.BuyPrice 
    = 12M;
                            session.Update(product);

                            tran.Commit();
                        }
                        
    catch (Exception ex)
                        {
                            tran.Rollback();
                            
    throw ex;
                        }
                    }
                }
            }

            [Test]
            
    public void DeleteTest()
            {
                
    using (ISession session = this.sessionFactory.OpenSession())
                {
                    
    using (ITransaction tran = session.BeginTransaction())
                    {
                        
    try
                        {
                            var product 
    = session.Load<Product>(s_id);

                            session.Delete(product);

                            tran.Commit();
                        }
                        
    catch (Exception ex)
                        {
                            tran.Rollback();
                            
    throw ex;
                        }
                    }
                }
            }
        }

      运行SaveTest()方法的效果,如图2.2.1所示。

    图2.2.1

      运行UpdateTest()方法的效果,如图2.2.2所示。奇怪的是OnUpdate()回调没有工作,这是因为在NHibernate 1.x 以后的版本,ILifecycle接口已经不建议使用了。

    图2.2.2

      运行DeleteTest()方法的效果,如图2.2.3所示。

    图2.2.3

      三、合法性验证回调

      合法性验证(IValidatable)回调是在持久化类在保存其持久化状态前进行合法性检查的接口。

    public interface IValidatable
    {
            
    void Validate();
    }
      如果发现对象违反了某条规则,应该抛出一个ValidationFailure异常。在Validatable实例的Validate()方法内部不应该改变它的状态。

    ILifecycle接口的回调方法不同,Validate()可能在任何时间被调用。应用程序不应该把Validate()调用和商业功能联系起来。

      实现代码如下:

    代码
    public class Product : IValidatable
        {

            ....


            
    /// <summary>
            
    /// 进价
            
    /// </summary>
            public virtual decimal BuyPrice { getset; }


            
    public virtual void Validate()
            {
                
    if (this.BuyPrice >= 12M)
                {
                    
    throw new ValidationFailure("进货价格太高,无法受理!");
                }
            }
        }
        

      运行效果如图3.1所示

    图3.1

      总结:目前NHibernate 3.0版本中不建议使用ILifecycle和IValidatable接口。因为这样NHibernate框架就会对持久化类产生侵入性。

      代码下载

      出处:http://www.cnblogs.com/GoodHelper/archive/2011/02/18/nhibernate05.html

      欢迎转载,但需保留版权。

    作者:刘冬.NET 博客地址:http://www.cnblogs.com/GoodHelper/ 欢迎转载,但须保留版权
  • 相关阅读:
    摩拜单车--获地球卫士奖
    项目经理--读书静心的日子
    20165219 Exp1 PC平台逆向破解
    2018-2019-2 20165219《网络对抗技术》Exp0 Kali安装 Week1
    2018-2019-1 20165219《信息安全系统设计基础》实验五
    ### 2018-2019-1 20165219《信息安全系统设计基础》实验四
    实现mypwd
    mybash的实现
    2018-2019-1 20165219 实验三 实时系统
    2018-2019-1 20165219 《信息安全系统设计基础》第七周学习总结
  • 原文地址:https://www.cnblogs.com/GoodHelper/p/nhibernate05.html
Copyright © 2011-2022 走看看