Fork me on GitHub

NHibernate学习系列一

NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。

优点:

(1)NHibernate不仅仅管理.NET类到数据库表的映射(包括.NET 数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和ADO.NET处理数据的时间。

(2)面向对象:NHiberante的使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想。

(3)透明持久化:是他们正与(仅仅一个)Session相关联。一旦这个Session被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。

缺点:

(1)内存消耗:直接使用“SqlHelper、DAL、BLL”无疑是最省内存的。使用NHibernate后,内存开销比较大,这点是毋庸置疑的。

(2)批量数据库的处理:由于NHibernate是基于面向对象的ORM框架,处理数据库的方式是针对单个对象的。对数据库的增、删、改都是正对一条记录而言。对于批量修改、删除数据,不适合用NHiberante。这也是所有OR框架弱点。

(3)表关系比较混乱时也不适合使用NHiberante。NHibernate只适合于表与表的关系比较明确的环境中。如本应该建立外键的,没有建立外键。这时使用NHiberante不仅没有减少工作量,反而增加了工作量。

 

使用NHiberante做一个简单实例:

(1)添加引用程序集:

(2)编写一个持久化类:

public class Classes
    {
        public Classes()
        {
        }
        #region Classes属性定义
        private int _CID;
        /// <summary>
        /// 班级表ID
        /// </summary>
        public virtual int CID
        {
            get
            {
                return _CID;
            }
            set
            {
                _CID = value;
            }
        }
        private string _CName;
        /// <summary>
        /// 班级名称
        /// </summary>
        public virtual string CName
        {
            get
            {
                return _CName;
            }
            set
            {
                _CName = value;
            }
        }
        private int _CCount;
        /// <summary>
        /// 班级人数
        /// </summary>
        public virtual int CCount
        {
            get
            {
                return _CCount;
            }
            set
            {
                _CCount = value;
            }
        }
        private string _CImg;
        /// <summary>
        /// 班级Logo图片
        /// </summary>
        public virtual string CImg
        {
            get
            {
                return _CImg;
            }
            set
            {
                _CImg = value;
            }
        }
        private bool _CIsDel;
        /// <summary>
        /// 删除标志
        /// </summary>
        public virtual bool CIsDel
        {
            get
            {
                return _CIsDel;
            }
            set
            {
                _CIsDel = value;
            }
        }
        private DateTime _CAddTime;
        /// <summary>
        /// 录入时间
        /// </summary>
        public virtual DateTime CAddTime
        {
            get
            {
                return _CAddTime;
            }
            set
            {
                _CAddTime = value;
            }
        }
        #endregion
    }

  NHibernate对属性使用的类型不加任何限制。所有的.NET类型和原始类型(比如string,char和DateTime)都可以被映射,也包括.Net 集合(System.Collections)中的类。你可以把它们映射成为值,值集合,或者与其他实体类相关联。Id是一个特殊的属性,代表了这个类的数据库标识符(主键)。为了让上面提到运行时类增强功能生效,NHibernate持久化类的所有的public的属性必须声明为virtual。

(3)编写xml文件映射:xml文件必须以“类名.hbm.xml”格式命名;创建解决方案文件夹放入文件如下,则编写xml时就会有智能提示:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="HeiMaNH" assembly="HeiMaNH">
    <class name="HeiMaNH.Classes,HeiMaNH" table="Classes">
        <id name="CID" column="CID" type="Int32">
            <generator class="identity" />
        </id>
        <property name="CName" column="CName" type="String" length="50"  />
        <property name="CCount" column="CCount" type="Int32" length="4"  />
        <property name="CImg" column="CImg" type="String" length="40"  />
        <property name="CIsDel" column="CIsDel" type="Boolean" length="1"  />
        <property name="CAddTime" column="CAddTime" type="DateTime" length="8" />
        
    </class>
</hibernate-mapping>

(4)使用NHibernate的ISession(持久化管理器), 我们通过ISession来从数据库中存取数据

 protected void Page_Load(object sender, EventArgs e)
        {
            //1.创建 会话 工厂(是可以被共享使用的, 是线程安全的)
            ISessionFactory factory = new Configuration().Configure().BuildSessionFactory();
            //2.创建 会话(非共享使用,非线程安全,但是如果针对当前请求里的每个数据库操作都创建 会话,则极度浪费资源,所以,最好是 针对每次请求 只创建一个 会话)
            ISession sess = factory.OpenSession();
            //HttpContext.Current.Items.Add("nfsession", sess);
            //3.创建查询对象  (hql-hibernate query language)
            IQuery query = sess.CreateQuery("from Classes  c where c.CIsDel = false");
            //3.2更加面向对象化的查询方式
            //ICriteria crit = sess.CreateCriteria(typeof(Classes));
            //crit.Add(Restrictions.Eq("CIsDel", false));
            //crit.Add(Restrictions.Eq("CName", "刘德华2"));
            //IList<Classes> list = crit.List<Classes>();
            //4.获得查询结果
            IList<Classes> list = query.List<Classes>();
            rptList.DataSource = list;
            rptList.DataBind();
        }


对象状态:

瞬时(transient)
数据库中没有数据与之对应,超过作用域会被垃圾回收.
其实 一般就是 new出来 且与 ISession没有关联的对象;
 
持久(persistent)
数据库中有数据与之对应,当前与ISession关联,并且相关联的isession也没有关闭,事物没有提交:持久对象状态发生改变,在事务提交时会影响到数据库(nhibernate能检测到改变);
 
脱管(detached-脱离了nh的管理)
数据库中有数据与之对应,但当前没有session与之关联;脱管对象状态发生改变,nhibernate不能检测到;
 
HQL和Criteria
 
HQL(Hibernate Query Language)
面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了C#类和属性其他部分不区分大小写);
HQL中查的是对象而不是表,并且支持多态;
HQL主要通过Query来操作,Query的创建方式:
IQuery q = sess.CreateQuery(hql);
from Person
from User u where u.name=:name
from User u where u.name=:name and u.birthday<:birthday
 
Criteria
Criteria 是一种比HQL更面向对象的查询方式;
ICriteria crit = sess.CreateCriteria(typeof(User));
简单属性条件如:crit.Add(Restrictions.eq(proName,value));
crit.Add(Restrictions.eqProperty(proName,otherProName));

 

使用NHibernate进行关联映射

 

(1)多对一(Student - Classes)
(2)一对多(Classes-Student)
(3)一对一(Student-IdCard)
(4)多对多(Student-Subject)
(5)集合映射(Set, List, Map, Bag)
(6)级联:Cascade(Classes-Student)
 
posted @ 2014-07-22 16:27  迁梦余光  阅读(211)  评论(0编辑  收藏  举报