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

  作为被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();
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(,"张三"); //瞬态
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>();
Console.WriteLine(session.Contains(p)); //输出 ture 持久化状态
session.Close();
Console.WriteLine(sessionFactory.OpenSession().Contains(p)); //输出 false 脱管

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

NHibernate 之持久化类、拦截器 (第二篇)的更多相关文章

  1. 使用NHibernate(4)--拦截器和事件

    如果想在一个事务的开始.执行中.完成后等过程中执行一些自己的逻辑(比如记录日志.查看sql),拦截器(Interceptors)和事件(Event)就可以发挥作用了.两者所能完成的功能差不多. 1,拦 ...

  2. NHibernate官方文档中文版--拦截器和事件(Interceptors and events)

    对于应用程序来说,能够对NHibernate内部发生的事件做出响应式很有用的.这能够有助于实现一些类的功能或者扩展NHibernate的功能. 拦截器 IInterceptor接口提供了应用程序ses ...

  3. AspectCore动态代理中的拦截器详解(一)

    前言 在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来 ...

  4. Mybatis之拦截器原理(jdk动态代理优化版本)

    在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...

  5. Struts2(十四)拦截器实现权限管理

    一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截 ...

  6. 关于JFinal拦截器的理解

    这是波总的亲自总结,记录一下: 1:拦截器可以用在两个层面,一个是"控制层",另一个是"业务层",其中"业务层"是一种狭义的说法,更加合理的 ...

  7. 初学者易上手的SSH-struts2 05拦截器与自定义拦截器

    因为自己对于struts2也不是很了解,这章将是struts2的最后一章了.那么这一章主要介绍的是拦截器以及怎么样来自定义一个拦截器. struts2的拦截器位于struts2-core(核心包)-& ...

  8. Struts2拦截器和标签

    一.struts2拦截器 1.struts2是框架,封装了很多的功能,struts2里面封装的功能都是在拦截器里面. 2 struts2里面封装了很多的功能,有很多拦截器,不是每次这些拦截器都执行,每 ...

  9. Struts2之类范围拦截器和方法拦截器

    1.Struts2拦截器的体系结构 Struts2拦截器最大的特点是其透明性,即用户感觉不到它的存在,但我们在使用Struts2框架时,拦截器时时刻刻都在帮助我们处理很多事情. 包括: 文件上传 表单 ...

随机推荐

  1. WiderFace标注格式转PASCAL VOC2007标注格式

    #coding=utf-8 import os import cv2 from xml.dom.minidom import Document def create_xml(boxes_dict,ta ...

  2. yum安装的Apache的各种配置文件的位置

    //配置文件 /etc/httpd/conf /etc/httpd/conf.d /etc/httpd/conf.d/README /etc/httpd/conf.d/proxy_ajp.conf / ...

  3. leetcode之Ransom Note

    题目描述: 
Given
 an 
arbitrary
 ransom
 note
 string 
and 
another 
string 
containing 
letters from
 a ...

  4. 属性名、变量名与 内部关键字 重名 加&

    procedure TForm4.btn3Click(Sender: TObject); var MyQj: TQJson; MyPrinter: TPrinter; begin MyQj := TQ ...

  5. Asp.net网页中DataGridView数据导出到Excel

    经过上网找资料,终于找到一种可以直接将GridView中数据导出到Excel文件的方法,归纳方法如下: 1. 注:其中的字符集格式若改为“GB2312”,导出的部分数据可能为乱码: 导出之前需要关闭分 ...

  6. Highcharts创建一个简单的柱状图

    新建一个html文件,将highcharts引入到你的页面后,通过两个步骤我们就可以创建一个简单的图表了. 1.创建div容器 在页面的 body部分创建一个div,并指定div 的 id,高度和宽度 ...

  7. react初体验

    function Guest() { return ( <h1>pls login in</h1> ); } function User() { return ( <h1 ...

  8. Mayavi入门

    环境,win7/10 64位, python3.x 1,安装 Mayavi4.6 原装的pip下载奇慢,先更换一下源,豆瓣的更新要比清华的快 首先在window的文件夹窗口输入 : %APPDATA% ...

  9. Java学习笔记(十二)——eclipse和SVN配置,导入SVN服务器项目

    [前面的话] 北京的天气外加自己的不小心终于病了,在病的过程中,感觉身体好着真好,可以学习,可以吃好吃的,可以去运动,这一病了,干什么都感觉没有力气,身体好着真好. 这个文章的背景是:领导把项目最开始 ...

  10. Linux下几个命令的技巧

    Ctrl的组合键+a,移动到一行命令的首部+e,移动到一行命令的尾部+左右键,以单词为单位左右移动+u,删除光标之前的所有内容+k,删除光标之后的所有内容Alt+.为引用上一个命令的最后一个参数 还有 ...