• Nhibernate基础


     

    Nhibernate(英文冬眠的意思) 常用方法

     

    Contains

    Evict

    Clear

     在 NHibernate 中一切必须是 Virtual 的吗?

     http://www.cnblogs.com/aaa6818162/p/4675279.html

    http://blog.zhaojie.me/2009/09/my-view-of-nhibernate-2-virtually-everything.html

    因此,如果是你的话,在写Java代码的时候,是愿意使用getXxx()这样的方法,还是直接访问类中的私有字段?因此我认为,是Java语言的特性,导致Java开发人员倾向于直接访问类中的私有字段,从而导致Hibernate需要避免未加载的私有字段,进一步导致Hibernate的代理类会去覆盖所有的公开方法(只有方法,因为Java语言没有“属性”)——最终,由于NHibernate在“统一大业”上的策略,使得我们.NET开发人员也必须把所有成员标记为virtual,无论是方法还是属性。

     Nhibernate API

     

    http://www.cnblogs.com/aaa6818162/p/4639308.html

    下图描述了NHibernate的API在分层架构中的作用,下面将进行详细说明。

    image 

    NHibernate的接口大致分为四类:

    1.  被应用程序调用进行基本数据操作(增、删、改、查)的接口。这些接口是应用程序的业务逻辑层和控制层与NHibernate的主要交互点。ISession, ITransaction, IQuery和ICriteria属于此类。

    2. 被应用程序用来配置NHibernate的接口。Configuration就属此类。

    3. 回调接口。应用程序用回调接口来响应NHibernate中触发的事件。这类接口包括Interceptor, ILifecycle和IValidatable等。

    4. 用于扩展NHibernate的强大映射功能的接口。这类接口通常被应用程序的基础架构来实现。IUserType, ICompositeUserType, 和IIdentifierGenerator属于此类。

     NHibernate Interceptor机制

     nhibernate是如何自动生成sql语句的

    NHibernate 查看生成的sql语句:
    其实就是Interceptor的应用,  源码中Interceptor的默认实现是EmptyInterceptor,
    [Serializable]
    public class EmptyInterceptor : IInterceptor
    {   //前面省略n行代码
      public SqlString OnPrepareStatement搜索(SqlString sql)
      {
       return sql;
      }
    }  public class MyInterceptor : EmptyInterceptor
        {
           public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
            {
                return base.OnPrepareStatement(sql);
            }
        } 我们要做的就是继承EmptyInterceptor,重写OnPrepareStatement()方法,重写方法里面就是你大展拳脚的地方了,
    想写文件写文件,想输出到页面就输出到页面,什么都不做都可以,如上
    怎么用呢?
      public override void Update(Admin entity)
            {
                ISession session = HibernateTemplate.SessionFactory.OpenSession(new MyIntercepotr);
                session.Update(entity);
                session.Flush();
            }
    在你想要查看的操作中,打开session 的时候添加上自定义的拦截器就可以了,想给所有的操作都配置的话就要用到全局配置文件了。
    重写OnPrepareStatement()的时候一句话都不改,我只是在这里打一个断点而已,只要看看生成的sql语句就行了,然后去修改配置文件再来debug,确认怎么配置生产的sql最优。

    http://www.cnblogs.com/jiezhi/articles/87414.html

    http://www.cnblogs.com/JeffreyZhao/archive/2009/10/13/my-view-of-nhibernate-4-interceptor.html

     NHibernate中Session是线程不安全(多线程中Session不能被共享)  http://www.cnblogs.com/aaa6818162/p/4631412.html
     Nhibernate 设置派生属性

     http://www.cnblogs.com/cnjava/archive/2012/07/21/2602294.html

    映射属性

    作用

    <property>元素的insert属性

    如果为false,在insert语句中不包含该字段,表明该字段永远不能被插入。默认值为true

    <property>元素的update属性

    如果为false,update语句中不包含该字段,表明该字段永远不能被更新,默认值为true

    <class>元素的mutable属性

    如果为false,等价于所有的<property>元素的update属性为false,表示整个实例不能被更新,默认值为true

    <property>元素的dynamic-insert属性

    如果为true,表示当保存一个对象时,会动态生成insert语句,只有这个字段取值不能为null,才会把它包含到insert语句中。默认值为false

    <property>元素的dynamic-update属性

    如果为true,表示当更新一个对象时,会动态生成update语句,只有该字段取值不为null,才会把它包含到update语句中。默认值为false

    <class>元素的dynamic-insert属性

    如果为true,等价于所有的<property>元素的dynamic-insert属性为true,表示当保存一个对象时,会动态生成insert语句,insert语句中仅包含所有取值不为null的字段。默认值为false

    <class>元素的dynamic-update属性

    如果为true,等价于所有的<property>元素的dynamic-update属性为true,表示当保存一个对象时,会动态生成update语句,update语句中仅包含所有取值不为null的字段。默认值为false

     

    NHibernate主键生成方式   Key Generator

     关系数据库中的主键可分为 自然主键(具有业务含义)和代理主键(不具有业务含义)
     Nhibernate锁 数据并发 版本号   http://www.cnblogs.com/lyj/archive/2008/10/21/1316269.html

     

    Nhibernate 一级缓存

     
     NHibernate的Session管理策略   http://www.cnblogs.com/13yan/archive/2013/05/17/3083552.html

    1)在Web应用程序中 一个请求中第一次会打开一个Session并保存再web上下文,以后就不再新打开了

    2)在WinForm或单元测试中,使用另一种策略,每个线程用一个Session。

    修改hibernate.cfg.xml配置文件,加入一个属性<property name="current_session_context_class">web</property>,修改这个属性就可以修改Session策略。

    sessionFactory = new Configuration().Configure()
                    .SetProperty("current_session_context_class", currentSessionContextClass.ToString())
                    .BuildSessionFactory();

     NHibernate 怎么样去为我们的实体类设置一个通用的基类   http://www.cnblogs.com/aaa6818162/p/4631443.html
     hibernate session的flushMode的区别 

      

    http://blog.csdn.net/looyo/article/details/6309136

    http://stackoverflow.com/questions/3295169/nhibernate-flushmode-auto-not-flushing-before-find

    session.flushmode=auto
    1.手动调用flush()
    2.commit()时候
    3.查询前 (经过测试(oracle驱动),必须在事务内,不确定是否全部情形)

    /// <summary>
            ///  FlushMode.Auto  entity2返回值  list返回值
            /// FlushMode.Commit entity2 null  list null
            /// 调用Session的查询方法时,清理缓存,注意:这条规则必须保证显式开启的事务中,对于outside a transaction
            /// </summary>
            /// <returns></returns>
            public void FlushModeAutoTestMethod3()
            {
                ISession session = SessionFactoryManager.SessionFactory.OpenSession();
                session.FlushMode = FlushMode.Commit;
                var tx = session.BeginTransaction();
                Cardtype entity = new Cardtype() { Cardtypename = "33" };
                session.Save(entity);

                Cardtype entity2 = session
                        .CreateQuery("from Cardtype where Cardtypename = '33'")
                        .List<Cardtype>()
                        .FirstOrDefault();

                entity.Cardtypename = "66";
                var list = session.CreateQuery("from Cardtype where Cardtypename = '66'").List<Cardtype>().Count();
                session.Flush();
                tx.Commit();
            }

     NHibernate中Get和Load的区别  1.get()采用立即加载方式,而load()采用延迟加载;

      get()方法执行的时候,会立即向数据库发出查询语句,
       而load()方法返回的是一个代理(此代理中只有一个id属性),只有等真正使用该对象属性的时候,才会发出sql语句
    2.如果数据库中没有对应的记录,get()方法返回的是null.而load()方法出现异常ObjectNotFoundException

    如果加载一个对象的目的是威力访问它的属性,可以用get方法

    如果加载一个对象的目的是为了删除它,或者是为了建立于别的对象的关联,可以用load


     域对象在持久化层的三种状态   

    临时状态(Transient):当new一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存

     区域,如果没有变量引用这个对象,则会被jre垃圾回收机制回收。这个对象所保存的数据

     与数据库没有任何关系,除非通过Session的save或者SaveOrUpdate把临时对象与数据库

     关联,并把数据插入或者更新到数据库,这个对象才转换为持久对象。

     

    持久状态(Persistent): 持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对

    象进行delete操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再

    存在对应关系,持久化对象变成临时状态。持久化对象被修改变更后,不会马上同步到数

    据库,直到数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。

     

    游离状态(Detached):当Session进行了Close、Clear或者evict后,持久化对象虽然拥有持久化标识符和与数据

    库对应记录一致的值,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离

    状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有

    持久化标识。

     

    总结:我们现在系统默认取出来的对象一直在持久状态 因为session绑定的web上线文  只有请求结束才进行session的close

     protected void Application_BeginRequest(object sender, EventArgs e)
            {
                ISession session = SessionFactoryBizCom.GetInstance().OpenSession();
                session.FlushMode = FlushMode.Auto;
                CurrentSessionContext.Bind(session);
            }

            protected void Application_EndRequest(object sender, EventArgs e)
            {
                if (CurrentSessionContext.HasBind(SessionFactoryBizCom.GetInstance().GetessionFactory()))
                {
                    ISession session = CurrentSessionContext.Unbind(SessionFactoryBizCom.GetInstance().GetessionFactory());
                    //session.Flush();
                    //session.Close();
                    session.Dispose();
                }
            }

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

     

  • 相关阅读:
    三范式最简单最易记的解释
    Mysql添加用户错误:ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value解决方法
    mysql体系结构管理
    mysql的简单操作
    flush privileges刷新MySQL的系统权限相关表
    二进制安装mysql
    扩展一台mysql-5.6.40
    mysql5.6.40部署过程
    三剑客-awk
    三剑客-sed
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/4610136.html
Copyright © 2020-2023  润新知