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框架时,拦截器时时刻刻都在帮助我们处理很多事情. 包括: 文件上传 表单 ...
随机推荐
- free函数在操作系统内存中的实现【转】
转自:http://www.2cto.com/kf/201210/160985.html 我一次性malloc十个单位节点的内存空间出来赋值给L, 现在我想一次性删除从第3个到第6个节点,我是这么做的 ...
- 64_g4
gnatcoll-2014-10.fc26.x86_64.rpm 28-Feb-2017 17:44 1738266 gnatcoll-devel-2014-10.fc26.i686.rpm 28-F ...
- Python 如何将字符串转为字典
在工作中遇到一个小问题,需要将一个 python 的字符串转为字典,比如字符串: user_info = '{"name" : "john", "ge ...
- Swift 特殊关键字 与符号
#available() 函数来检查API函数的可用性 // 判断当前版本是否 iOS8.0+,OSX10.10+以及以其他平台 if #available(iOS 8.0, OSX 10.10, * ...
- 如何设置static tableview的section区域高度
重写代理方法- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { i ...
- 2017百度春招<度度熊买帽子的问题>
题目: 度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同.度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少? 数组中找到第三小的数字 注意边界条件 用STL中的set来 ...
- linux命令(12):ping命令
1.ping网关:ping –b 192.168.1.1 2.ping指定次数:ping -c 10 192.168.1.100 3.时间间隔和次数限制的ping:ping -c 10 -i 0.5 ...
- hdu 1671(字典树判断前缀)
Phone List Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- python 实用命令
列表理解: list = [-1, -2, 1, 2] [item for item in list if item > 0] [1, 2] d = {'person': 2, 'cat': 4 ...
- react表单提交
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: ' ...