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框架时,拦截器时时刻刻都在帮助我们处理很多事情. 包括: 文件上传 表单 ...
随机推荐
- 測試 battery capacity curve 的負載
昨天有同事問說, 他要測試 battery capacity curve, 並且負載要使用 33mA, 於是我想到有一個 apk 名稱為 快速放電 (最下方),可以控制 cpu 的 load, 他試了 ...
- 12-4 NSString
原文:http://rypress.com/tutorials/objective-c/data-types/nsstring NSString 在本教程的内容可能我们已经看到过很多次了,NSStri ...
- C++11——Use auto keyword in C++11
版权声明:本文系原创,转载请注明来源. Compile your program with: g++ -std=c++ -o target_name filen_ame.cpp or: g++ -st ...
- OpenCV利用矩阵实现图像旋转
利用OpenCV的矩阵操作实现图像的逆时针旋转90度操作 代码 Mat src = imread("C:\\Users\\fenggl\\Desktop\\测试.jpg",MREA ...
- linux命令(43):cal命令
cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal ...
- 四:ZooKeeper的集群,伪集群,单机的搭建
一:ZooKeeper服务安装包下载 第一步:打开zooKeeper官网
- python启停脚本的编写
先占个位置,打算记录一下启停python 的脚本start.sh,stop.sh的写法. 内容包括启动python脚本的方式,日志的重定向,获取进程id,以及杀掉进程. 参考文章: http://bl ...
- Python3通过汉字输出拼音
https://github.com/mozillazg/python-pinyin # pip install pypinyin from pypinyin import pinyin, lazy_ ...
- 基础平台为第三方应用接入提供oauth2认证接口
oauth2开放认证协议原理及案例分析 http://blog.csdn.net/volcan1987/article/details/7287605 谈谈基于OAuth 2.0的第三方认证 [上篇] ...
- Linux安全之密钥登录
我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器.但是,一般的密码方式登录,容易有密码被暴力破解的问题.所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者 ...