NHibernate 之持久化类、拦截器 (第二篇)

来源:互联网 发布:网络ip在哪里设置 编辑:程序博客网 时间:2024/04/29 04:31

一、持久化类中成员标量的要求

  作为被NHibernate使用的持久化类,必须满足以下几点要求:

  1、声明读写属性

    在NHibernate的使用中,持久化类的成员变量必须声明对应的属性,NHibernate支持public、internal、protected三种访问修饰符。

  2、提供标识属性

    持久化类必须提供一个标识属性,标识属性对应数据库的主键。

    当然这个是可选的,并非强制性,但是强烈建议这么做。这个标识属性可以叫任何名字,任何类型。

  3、属性必须是非密封的和虚的

    持久化类中所有的属性,必须声明为非密封的,也就是不能带有sealed。而且必须带有virtual关键字。

  继承持久化的类,如果想作为持久化类,也必须满足以上3点条件。

二、实现ILifecycle接口,实现回调(Callbacks)操作

  持久化类可以实现一个叫ILifecycle的接口,从而实现一些回调方法,比如可以让持久化对象在save、load之后,delete、update之前进行一些初始化或清除的工作。

  注意在实现接口的时候,方法也必须声明为virtual的和public/internal的。

  我们先来看看接口的代码:

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

  方法说明:

  OnSave:    对象即将被save或insert时调用。
  OnUpdate: 对象即将被update时调用。
  OnDelete:  对象即将被delete时调用。
  OnLoad:    对象被装载后,第一时间调用。

  示例:

复制代码
    public class PersonModel : ILifecycle    {        public virtual int Id        {            get;            set;        }        public virtual string Name        {            get;            set;        }        public virtual LifecycleVeto OnDelete(NHibernate.ISession s)        {            throw new NotImplementedException();        }        public virtual void OnLoad(NHibernate.ISession s, object id)        {            this.Name = "加载时修改姓名!";            Console.WriteLine("在加载时调用!");   //在这里可以初始化等操作        }        public virtual LifecycleVeto OnSave(NHibernate.ISession s)        {            throw new NotImplementedException();        }        public virtual LifecycleVeto OnUpdate(NHibernate.ISession s)        {            throw new NotImplementedException();        }    }
复制代码

  调用代码:

复制代码
        static void Main(string[] args)        {            PersonDao dao = new PersonDao();            PersonModel p = dao.GetPersonById(3);            Console.WriteLine(p.Id + " " + p.Name);            Console.ReadKey();        }
复制代码

  输出结果如下:

  

  如果OnSave(),OnUpdate或OnDelete返回了LifecycleVeto.veto,那么这些操作会被取消了。

三、持久化类实例的状态

  一个持久化类实例,可能处于以下3种状态。这三种状态与ISession实例有关。

  •   瞬态(transient)
  •   持久化(persistent)
  •   脱管(detached)

  1、瞬态

  该持久化实例未与任何ISession实例关联过,没有持久化标识。

  Person p = new Person();

  如上面这个p实例就是瞬态。

  2、持久化

  该持久化实例与ISession有关联,它拥有持久化标识。持久化标识与CLR标识(内存中的位置)等价。通常是指刚刚从数据库里读出来或是刚刚保存入数据库的对象实例。

  ISession session = sessionFactory.OpenSession();  Person p = session.Get<Person>(Id);

  如上面这个p,就是持久化状态。

  3、脱管

  实例曾经与ISession关联过,但是那个ISession关闭了。它拥有持久化标识,并且可能在数据库有与其对应的一条记录。如果此时,又与ISession关联上,它就转变为了持久化状态。

 ISession session = sessionFactory.OpenSession(); Person p = session.Get<Person>(Id); session.Close();

  在Close()之后,p对象就是脱管状态了。

  4、瞬态-持久化转变

  ISession session = sessionFactory.OpenSession();  Person p = new Person(10,"张三");      //瞬态  Console.WriteLine(session.Contains(p)); //输出 false  session.Save(p);  Console.WriteLine(session.Contains(p)); //输出true 现在p是持久化状态了

  5、持久化状态-脱管转变

 ISession session = sessionFactory.OpenSession(); PersonModel p = session.Get<PersonModel>(2); Console.WriteLine(session.Contains(p));    //输出 ture 持久化状态 session.Close(); Console.WriteLine(sessionFactory.OpenSession().Contains(p));    //输出 false 脱管

   了解持久化状态,对理解NHibernate缓存,离线查询等功能是必要的。

0 0
原创粉丝点击