NHibernate初学体验进阶篇

在上篇NHibernate初学体检记》中,我参照NHibernate官方快速指南写了两个示例项目,在示例2的源码中充斥了如下类似的代码:<?XML:NAMESPACE PREFIX = O />

            Configuration cfg = new Configuration();

            cfg.AddAssembly("NHibernate.Examples");

            ISessionFactory factory = cfg.BuildSessionFactory();

            ISession session = factory.OpenSession();

            ITransaction transaction = session.BeginTransaction();

 

如何解决这个问题呢?答案就是采用DAOData Access Object)模式。

 

一、编写DAO

DAO其实就是把对实体的基本CRUD(创建、读取、更新、删除)操作进行封装。在本示例中也就是把对User实体的持久化操作进行封装,看下代码就什么都清楚了(相比以前的简单代码,我又加入了异常处理部分J):

public class UserDAO

    {

        private ISession session;

        private ITransaction tx;

 

        public void Create(User newUser)

        {

            try

            {

                StartOperation();

                session.Save(newUser);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        public void Update(User newUser)

        {

            try

            {

                StartOperation();

                session.Update(newUser);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        public void Delete(User user)

        {

            try

            {

                StartOperation();

                session.Delete(user);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        public User Find(string id)

        {

            User user = null;

            try

            {

                StartOperation();

                user = session.Get<User>(id);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

 

            return user;

        }

 

        public IList FindAll()

        {

            IList userList = null;

            try

            {

                StartOperation();

                userList = session.CreateCriteria(typeof(User)).List();

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

            return userList;

        }

 

        //---------------------------------------------------

        private void StartOperation()

        {

            Configuration cfg = new Configuration();

            cfg.AddAssembly("NHibernate. Examples");

 

            ISessionFactory factory = cfg.BuildSessionFactory();

 

            session = factory.OpenSession();

            tx = session.BeginTransaction();

        }

 

        private void HandleException(HibernateException e)

        {

            tx.Rollback();

            throw e;

            //注:你可以在此写自己的异常处理,如记录日志...

        }

    }

 

有了UserDAO我们对User实体的操作简化为简单的两行代码(如下添加用户的示例):

User newUser = new User();

            newUser.Id = txtLogonID.Text.Trim();

            newUser.UserName = txtName.Text.Trim();

            newUser.Password = txtPassword.Text.Trim();

            newUser.EmailAddress = txtEmailAddress.Text.Trim();

            newUser.LastLogon = DateTime.Now;

            //----------------------------------------------------

            UserDAO userDAO = new UserDAO();

            userDAO.Create(newUser);

 

NHibernate的那些充斥期间的初始化和收尾代码不见了,DAO模式明显降低了应用程序与NHibernate的耦合度。看起来不错J,不过,这里有潜在的重复问题:我们的示例比较简单,只有一个User实体类,正常的项目中会有大量这样的的实体类,也就会有大量对应的DAO类,我们的“复制/粘贴”恶梦开始了,你要为所有的DAO类编写类似于UserDAO类的代码,这里面明显有很多的重复,我们再写其它的DAO类时,需要改变的仅仅是实体类,其余代码都是“复制/粘贴”来的。“复制/粘贴”----所有编程问题的根源!(摘自《Hibernate Quickly中文版》P149)。这时候我们就需要“抽象”了!(突然觉得“抽象”是不是“抽出那些相象的部分”之意,哈哈!)

 

二、抽象DAO

我们来创建一个抽象的DAOAbstractDAO,作为超类,让其它的DAO继承之。AbstractDAO封装那些“相象”的部分,以简化实体DAO的编写。看代码吧:

public abstract class AbstractDAO

    {

        private ISession session;

        private ITransaction tx;

 

        protected void Save(Object obj)

        {

            try

            {

                StartOperation();

                session.Save(obj);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        protected void Update(Object obj)

        {

            try

            {

                StartOperation();

                session.Update(obj);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        protected void Delete(Object obj)

        {

            try

            {

                StartOperation();

                session.Delete(obj);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

        }

 

        protected Object Find(System.Type clazz, Object id)

        {

            Object obj = null;

            try

            {

                StartOperation();

                obj = session.Get(clazz,id);

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

 

            return obj;

        }

 

        protected IList FindAll(System.Type clazz)

        {

            IList objList = null;

            try

            {

                StartOperation();

                objList = session.CreateCriteria(clazz).List();

                tx.Commit();

            }

            catch (HibernateException e)

            {

                HandleException(e);

            }

            finally

            {

                session.Close();

            }

 

            return objList;

        }       

 

       

 

        //---------------------------------------------------

        private void StartOperation()

        {

            Configuration cfg = new Configuration();

            cfg.AddAssembly("NHibernate. Examples");           

            ISessionFactory factory = cfg.BuildSessionFactory();

            session = factory.OpenSession();          

            tx = session.BeginTransaction();

        }

 

        private void HandleException(HibernateException e)

        {

            tx.Rollback();

            throw e;

            //注:你可以在此写自己的异常处理,如记录日志...

        }

    }

 

我们将通用的CRUD方法(包括save/update/delete/find)都放到了AbstractDAO类中,并将这些方法设为protected,这样只有子类可调用它们。看看我们现在继承自AbstractDAOUserDAO是不是简化了:

    public class UserDAO : AbstractDAO

    {

        public void Create(User newUser)

        {

            base.Save(newUser);

        }

 

        public void Update(User newUser)

        {

            base.Update(newUser);

        }

 

        public void Delete(User user)

        {

            base.Delete(user);

        }

 

        public User Find(string id)

        {

            return (User)base.Find(typeof(User), id);

        }

 

        public IList FindAll()

        {

            return (IList)base.FindAll(typeof(User));

        }            

 

    }

 

哈哈,UserDAO中该有的有,不该有的没有了,世界看起来清爽多了!呼吸下新鲜的空气吧,不用为写更多的实体DAO类发愁了(如果还有代码自动生成工具那就更好了----懒惰的程序员,呵呵J)!

不过,不要高兴的太早,还没完呢!

 

三、提高效率(引入单例模式)

看看AbstractDAO中每个CRUD方法都要调用的函数StartOperation()它包含创建ISessionFactory对象的核心代码,这个创建过程需要加载NHibernate映射文件信息,内存开销非常大,每个CRUD方法都要进行重复的创建,这还得了!还好我们有Singleton(单例模式)对付他!Singleton保证了一个类只被实例化一次,它将避免我们的重复加载映射文件信息的问题。以下是我们的实现:

public sealed class NHibernateFactory

    {

        private static volatile ISessionFactory factory;

        private static object syncRoot = new Object();

        private NHibernateFactory() { }

 

        public static ISessionFactory BuildIfNeeded()

        {

            if (factory == null)

            {

                lock (syncRoot)

                {

                    if (factory == null)

                    {

                        Configuration cfg = new Configuration();

                        cfg.AddAssembly("NHibernate. Examples");

                        factory = cfg.BuildSessionFactory();

                    }

                }

            }

            return factory;

        }

 

        //----------------------------------

        static public ISession OpenSession()

        {

            NHibernateFactory.BuildIfNeeded();

            ISession session = factory.OpenSession();

            return session;

        }

    }

 

(注:本实现参考了MSDNhttp://msdn2.microsoft.com/zh-cn/library/ms998558.aspx 《在 C# 中实现 Singleton》中的内容,有关Singleton或更多设计模式推荐阅读《大话设计模式》一书,很适合初学者的一本好书!)

有了单例的NHibernateFactory,我们的StartOperation()将变为:

private void StartOperation()

        {

            session = NHibernateFactory.OpenSession();

            tx = session.BeginTransaction();

        }

 

啊哈,恭喜你成功进阶!

 

听说SpringHibernate有更好的封装,那么Spring.NET中应该也有对NHibernate的封装吧,有空再说J

 

注:本文内容参考了《Hibernate Quickly中文版》P144-154.

文中内容不妥之处,敬请各位高手指教!

 

本文示例源码下载:/Files/bluesky521/NHibernateQuickStart3.rar

测试环境:单机安装Win2003SP2 + SQL2000 + .NET2.0 + VS2005

转载于:https://www.cnblogs.com/yangjunwl/articles/1112482.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/380128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse快捷键

Java开发工具(Eclipse的视窗和视图概述) A:视窗 每一个基本的窗体被称为视窗 PackageExplorer 显示项目结构&#xff0c;包&#xff0c;类&#xff0c;及资源Outline 显示类的结构&#xff0c;方便查找&#xff0c;识别&#xff0c;修改Console 程序运行的结果在该窗口显示Hie…

【汇编语言】除法(DIV/IDIV)

除法&#xff08;DIV/IDIV&#xff09; 目录除法&#xff08;DIV/IDIV&#xff09;DIV(unsigned divide)无符号数除法IDIV(signed divide)有符号数除法DIV(unsigned divide)无符号数除法 格式&#xff1a;DIV SRC 操作&#xff1a; SRCSRCSRC为字节时&#xff0c;(AL)←(AX)/…

java 方法 示例_Java集合syncedSortedSet()方法与示例

java 方法 示例集合类SynchronizedSortedSet()方法 (Collections Class synchronizedSortedSet() method) synchronizedSortedSet() method is available in java.util package. java.util软件包中提供了sharedSortedSet ()方法 。 synchronizedSortedSet() method is used to …

远控免杀专题(17)-Python-Rootkit免杀

免杀能力一览表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全家桶…

项目管理软件应用浅析(转)

项目管理是在一定的约束条件下&#xff0c;以高效率地实现项目业主的目标为目的&#xff0c;以项目经理个人负责制为基础和以项目为独立实体进行经济核算&#xff0c;并按照项目内在的逻辑规律进行有效的计划、组织、协调、控制的系统管理活动。项目管理的核心技术是网络计划技…

斜视角的讨论(转)

http://school.ogdev.net/listshow.asp?page4&typeid0&categoryid5&id0&ListType2 目 录 1.1 地图和地表 1.2 斜视角游戏中的视角 1.3 Tile图片的拼接 1.4 不同地表间的过渡 1.5 地图数据结构的定义 --------------------------------------------------…

计算机网络(湖科大教书匠)

计算机网络&#xff08;湖科大教书匠&#xff09; 本文档为教学视频【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili】的摘录 目录计算机网络&#xff08;湖科大教书匠&#xff09;一、绪论1.2 因特网概述1.2.1 网络、互连网&#xff08;互联…

经纬度

题目描述 给定地球的两个经纬度坐标&#xff0c;问这两个点的直线距离。假设地球为球体&#xff0c;半径为6371009米。 输入描述: 第一行一个整数T表示数据组数。 接下来n行&#xff0c;每行四个数lat1, lng1, lat2, lng2分别表示两个点的经纬度。 正数表示北纬和东经。 …

远控免杀专题(18)-ASWCrypter免杀

免杀能力一览表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全家桶…

Hibernate 笔记4 实现对数据库的增删改查

1 准备 首先在mysql数据库中建表User,并添加相关信息。 user表结构如下。 ---------------------------------------------------------| Field | Type | Null | Key | Default | Extra |------------------------------------------------…

Direct3D中的绘制(3)

立方体——只比三角形稍微复杂一点&#xff0c;这个程序渲染一个线框立方体。 这个简单的绘制和渲染立方体的程序的运行结果如下图所示&#xff1a; 源程序&#xff1a; /************************************************************************************** Renders a …

远控免杀专题(19)-nps_payload免杀

免杀能力一览表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全家桶…

VS2005中使用WebDeploymentProject的问题

近来做Web项目&#xff0c;VS2005中发布网站时默认发布大批的程序集&#xff0c;这给升级网站时造成很大麻烦&#xff0c;所以偶从MS下载了个WebDeploymentProject的插件&#xff08;下载地址http://download.microsoft.com/download/c/c/b/ccb4877f-55f7-4478-8f16-e41886607a…

操作系统中的多级队列调度

多级队列调度 (Multilevel queue scheduling) Every algorithm supports a different class of process but in a generalized system, some process wants to be scheduled using a priority algorithm. While some process wants to remain in the system (interactive proce…

编写一程序,输入一个字符串,查找该字符串中是否包含“abc”。

import java.lang.String.*;//这里调用java.long.String.contains()方法&#xff1b; import java.util.Scanner; public class shit {public static void main(String[] args) {Scanner wsq new Scanner(System.in);String str wsq.next();boolean status str.contains(&qu…

显示消息提示对话框(WebForm)

1: /// <summary>2: /// 显示消息提示对话框。3: /// Copyright (C) Maticsoft4: /// </summary>5: public class MessageBox6: { 7: private MessageBox()8: { 9: }10: 11: …

借助格式化输出过canary保护

0x01 canary保护机制 栈溢出保护是一种缓冲区溢出攻击缓解手段&#xff0c;当函数存在缓冲区溢出攻击漏洞时&#xff0c;攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后&#xff0c;函数开始执行的时候会先往栈里插入cookie信息&#xff0c;当函数真…

什么叫灰度图

任何颜色都有红、绿、蓝三原色组成&#xff0c;假如原来某点的颜色为RGB(R&#xff0c;G&#xff0c;B)&#xff0c;那么&#xff0c;我们可以通过下面几种方法&#xff0c;将其转换为灰度&#xff1a; 1.浮点算法&#xff1a;GrayR*0.3G*0.59B*0.11 2.整数方法&#xff1a;Gra…

各抓包软件的之间差异_系统软件和应用程序软件之间的差异

各抓包软件的之间差异什么是软件&#xff1f; (What is Software?) Software is referred to as a set of programs that are designed to perform a well-defined function. A program is a particular sequence of instructions written to solve a particular problem. 软件…

输入一字符串,统计其中有多少个单词(单词之间用空格分隔)(java)

import java.util.*; class Example3{public static void main(String args[]){Scanner sc new Scanner(System.in);String s sc.nextLine();//这里的sc.nextLine&#xff08;&#xff09;空格也会记数&#xff1b;StringTokenizer st new StringTokenizer(s," ")…