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

  作为被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. 【模板】BZOJ 3685: 普通van Emde Boas树——Treap

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3685 据说神犇都是用zkw线段树水过的啊... 我蒟蒻只会写treap,加了fread之后8 ...

  2. FineReport——登录不到决策系统

    在不断的测试过程中,可能会造成缓存数据的累积,所以在登录过程中可能会出现登录不到决策系统,而是跳转到某一模板页面 解决方法就是清理缓存或者换一个浏览器测试.

  3. 查询 IDE 的版本 方便安装第三方的时候选择

    TMD 很多第三方软件 的版本 定义 与 delphi是不一致的. 1.有的是以这个为准.

  4. 微信小程序 - "锚点"功能的实现

    “锚点”功能在实际应用设计的好,可以提高用户体验.今天碰到一个类似下面功能: 由于页面数据比较多,除了做些上拉加载,下拉刷新等优化.还可以进行进行分类,如上图.功能要求:点击导航的菜单,相应页面的分类 ...

  5. AC日记——矩阵取数游戏 洛谷 P1005

    矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struc ...

  6. 走进 Akka.NET

    官方文档:https://getakka.net/index.html 官网:https://petabridge.com/ 一.Akka.NET 是什么? Akka 是一个构建高并发.分布式和弹性消 ...

  7. Jquery 学习之路(五)grid绑定模板

    最近在使用mvcpager时发现ajax分页需要使用Partial来实现,而且使用起来还是觉得不太方便.突然想自己做一个mvc的ajax分页,但是如果table直接用js输出就不好维护了. angul ...

  8. [Bootstrap]modal弹出框

    写在前面 在实际开发中,为了友好,更需要一种美观的弹出框,js原生的alert,很难满足需求.这里推荐一个bootstrap的弹出框. 一个例子 先看效果吧 代码: <!DOCTYPE html ...

  9. thinkphp的where方法的使用

    1.Thinkphp中where()条件的使用 总是有人觉得,thinkphp的where()就是写我要进行增加.查询.修改.删除数据的条件,很简单的,其实我想告诉你,where()是写条件语句的,但 ...

  10. POJ2912 Rochambeau [扩展域并查集]

    题目传送门 Rochambeau Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4463   Accepted: 1545 ...