NHibernate 之持久化类、拦截器 (第二篇)
一、持久化类中成员标量的要求
作为被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 之持久化类、拦截器 (第二篇)的更多相关文章
- 使用NHibernate(4)--拦截器和事件
如果想在一个事务的开始.执行中.完成后等过程中执行一些自己的逻辑(比如记录日志.查看sql),拦截器(Interceptors)和事件(Event)就可以发挥作用了.两者所能完成的功能差不多. 1,拦 ...
- NHibernate官方文档中文版--拦截器和事件(Interceptors and events)
对于应用程序来说,能够对NHibernate内部发生的事件做出响应式很有用的.这能够有助于实现一些类的功能或者扩展NHibernate的功能. 拦截器 IInterceptor接口提供了应用程序ses ...
- AspectCore动态代理中的拦截器详解(一)
前言 在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来 ...
- Mybatis之拦截器原理(jdk动态代理优化版本)
在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...
- Struts2(十四)拦截器实现权限管理
一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截 ...
- 关于JFinal拦截器的理解
这是波总的亲自总结,记录一下: 1:拦截器可以用在两个层面,一个是"控制层",另一个是"业务层",其中"业务层"是一种狭义的说法,更加合理的 ...
- 初学者易上手的SSH-struts2 05拦截器与自定义拦截器
因为自己对于struts2也不是很了解,这章将是struts2的最后一章了.那么这一章主要介绍的是拦截器以及怎么样来自定义一个拦截器. struts2的拦截器位于struts2-core(核心包)-& ...
- Struts2拦截器和标签
一.struts2拦截器 1.struts2是框架,封装了很多的功能,struts2里面封装的功能都是在拦截器里面. 2 struts2里面封装了很多的功能,有很多拦截器,不是每次这些拦截器都执行,每 ...
- Struts2之类范围拦截器和方法拦截器
1.Struts2拦截器的体系结构 Struts2拦截器最大的特点是其透明性,即用户感觉不到它的存在,但我们在使用Struts2框架时,拦截器时时刻刻都在帮助我们处理很多事情. 包括: 文件上传 表单 ...
随机推荐
- 使用 ftrace 调试 Linux 内核,第 1 部分【转】
转自:http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1/index.html ftrace 是 Linux 内核中提供的一种调试工具.使用 ...
- selenium.webdriver.common.keys 模块中常用的变量
表11-5 selenium.webdriver.common.keys 模块中常用的变量属性 含义Keys.DOWN, Keys.UP, Keys.LEFT,Keys.RIGHT 键盘箭头键Keys ...
- 【bzoj3786】星系探索
ETT模版题. 真正的Eular-Tour-Tree维护的是树的欧拉序. 由于各种原因,没人知道怎么维护欧拉序,所以我写的是个假的,维护dfs序的. 本质还是用Splay维护序列. 然后因为我常数太差 ...
- Jquery屏蔽浏览器的F1-F12快捷键,在IE,GOOGLE下测试均无问题
在网上找了找,很多都是js实现的,东找西找,再加上自己的想法也勉强的完成了,直接看代码 <script type="text/javascript" src="Sc ...
- Iptables基础整理
Iptables基础框架
- 修改VNCSERVER 默认的分辨率的方法
vi /usr/bin/vncserver /1024 找到默认的1024*768修改为 :1680*1050 reboot 重启
- AC日记——[SDOI2017]相关分析 洛谷 P3707
[SDOI2017]相关分析 思路: 裸线段树: (玄学ac): 代码: #include <bits/stdc++.h> using namespace std; #define max ...
- 史上最全的web前端系统学习教程!
这份资料整理花了近7天,如果感觉有用,可以分享给更有需要的人. 在看接下的介绍前,我先说一下整理这份资料的初衷: 我的初衷是想帮助在这个行业发展的朋友和童鞋们,在论坛博客等地方少花些时间找资料,把有限 ...
- js表单提交回调函数
在研究表单的时候发现一个有意思的东西——在表单提交的时候如何保证数据全部提交完毕才会清空? 我们常用的<input type="reset" value="重置&q ...
- 9. Spark Streaming技术内幕 : Receiver在Driver的精妙实现全生命周期彻底研究和思考
原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/) Spark streaming 程序需要不断接收新数据,然后进行业务逻辑 ...