zoukankan      html  css  js  c++  java
  • 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)
     
  • 相关阅读:
    sql 查出一张表中重复的所有记录数据
    几种常见SQL分页方式效率比较
    Redis命令参考之复制(Replication)
    Redis-benchmark使用总结
    redis压力测试详解
    c#:ThreadPool实现并行分析,并实现线程同步结束
    C#多线程学习 之 线程池[ThreadPool]
    [C#基础]ref和out的区别
    C#:ref和out的联系及区别。
    生产环境中使用Docker Swarm的一些建议
  • 原文地址:https://www.cnblogs.com/tianboblog/p/3860846.html
Copyright © 2011-2022 走看看