Nhibernate连接oracle数据库,主键ID用序列生成时连接数据库IO次数分析

本来打算主键ID用触发器生成,因为程序只需要一次IO就能插入一条数据。

图在下面,这里assigned不能改为native,从配置中看,是程序来生成ID,但实际oracle接受到插入消息后,触发器自动用序列替换了ID,因此遇到一个问题,就是程序不能获取到刚才插入的实体的主键ID,于是改为配置文件中指定序列创建ID,为了看它生成的sql和连接数据库的IO次数,我用NHibernateProfiler和sql server profiler进行了检测,oracle没找到好的检测连接sql的工具,因此用mssql的检测工具检测了下。用NHibernateProfiler检测生成sql时,迷惑了我,由于一系列的执行我共享了session,该工具都只显示一个session,并且列出它生成了哪些sql,让我以为它只是一个IO就把整个查询和操作弄好了,nhibernate的默认延时加载好像是如果同一个session中没有相同对象,然后从数据库获取对象,但该对象内部的其他对象会延时加载,并且他检测出的sql,并不是真正数据库获取到查询sql,比如查询都参数化了,但NHibernateProfiler没有很细的说明查询的值是什么参数,这在我查询序列的创建和传递给插入实体对象的sql时没看明白,我用sql server profiler才证实这点。

配置文件如下: 

ExpandedBlockStart.gif TestSeq.hbm.xml
<? xml version="1.0" encoding="utf-8"  ?>
< hibernate-mapping  xmlns ="urn:nhibernate-mapping-2.2"  assembly ="DomainModel"  namespace ="DomainModel" >
  
< class  name  ="DomainModel.Entities.TestSeq,DomainModel"  table ="TESTSeq" >
    
< id  name ="ID"  column ="ID"  type ="int" >
      
< generator  class  ="assigned" ></ generator >
    
</ id >
    
< property  name ="NAME"  column ="NAME"  type ="string" />

  
</ class >
</ hibernate-mapping >

 

该为指定序列生成ID后的配置文件如下:

ExpandedBlockStart.gif TestSeq.hbm.xml
<? xml version="1.0" encoding="utf-8"  ?>
< hibernate-mapping  xmlns ="urn:nhibernate-mapping-2.2"  assembly ="DomainModel"  namespace ="DomainModel" >
  
< class  name  ="DomainModel.Entities.TestSeq,DomainModel"  table ="TESTSeq" >
    
< id  name ="ID"  column ="ID"  type ="int" >
      
< generator  class ="sequence" >
        
< param  name ="sequence" > TestSeq1 </ param >
      
</ generator >
    
</ id >
    
< property  name ="NAME"  column ="NAME"  type ="string" />

  
</ class >
</ hibernate-mapping >

 

程序c#代码执行数据库语句如下:

 

            var c  =  domainService.AddTestSeq( new  DomainModel.Entities.TestSeq() { NAME  =  DateTime.Now.ToString() });
            var a 
=  domainService.GetTestById( " 002 " );
            var b 
=  domainService.GetTestById( " 003 " );

 

用NHibernateProfiler检测如下:

看不到参数化的sql,能看到执行的sql,但看不出连接数据库的次数。于是我改为连接sql server,用sql server profiler检测了下连接的sql,由于mssql没有序列的说法,因此只能看共享同一个session生命周期时,所有操作数据库的sql,数据库这边检测到的sql查询次数,

配置文件如下:

    <id name="Id" column="Id" type="Int32" unsaved-value="0">
      <generator class ="native"></generator>
    </id>

其他都一样,

c#代码如下:

 

            var a  =  domainService.GetTestById3( 1 );
            var a2 
=  domainService.GetTestById3( 1 );
            var b 
=  domainService.GetTestById3( 2 );
            
object  o2  =  domainService.AddTest( new  DomainModel.Entities.Test() { name  =   " ab "  });

 

用NHibernateProfiler检测如下:

用sql server profiler检测如下:

能明显看到有3次数据库的打开关闭操作,因此我判断虽然nhibernate共享一个session,部分操作感觉像是一个整体的执行,而且只是查询操作时,NHibernateProfiler会把所有查询操作的sql完了或者有插入数据库操作时,才在界面上显示查询的几次sql记录,但NHibernateProfiler实际上还是对界面short sql中的每行记录都有一次连接和关闭数据库的查询操作,配置用序列创建主键ID时,从NHibernateProfiler显示也是两次数据库的查询操作。

对NHibernate还不够熟,李永京的nhibernate系列文章还不错,要多学习学习,NH3又多了些特征和功能,但我对NHibernate的二级缓存扩展还比较感兴趣,因为这个直接影响到最终用户,希望以后可以多熟悉这块。

转载于:https://www.cnblogs.com/Lawson/archive/2010/12/05/1897085.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值