[NHibernate]存储过程的使用(一)-阿里云开发者社区

开发者社区> shy丶gril> 正文

[NHibernate]存储过程的使用(一)

简介:
+关注继续查看

目录

写在前面

文档与系列文章

Nhibernate中使用存储过程

一个例子

总结

写在前面

上篇文章一个小插曲,分析了延迟加载是如何解决N+1 select查询问题的。这篇开始介绍在nhibernate中如何使用存储过程,同时也介绍如何使用代码生成器,提高开发效率。

文档与系列文章

[Nhibernate]体系结构

[NHibernate]ISessionFactory配置

[NHibernate]持久化类(Persistent Classes)

[NHibernate]O/R Mapping基础

[NHibernate]集合类(Collections)映射 

[NHibernate]关联映射

[NHibernate]Parent/Child

[NHibernate]缓存(NHibernate.Caches)

[NHibernate]NHibernate.Tool.hbm2net

[NHibernate]Nullables

[NHibernate]Nhibernate如何映射sqlserver中image字段

[NHibernate]基本配置与测试 

[NHibernate]HQL查询 

[NHibernate]条件查询Criteria Query

[NHibernate]增删改操作

[NHibernate]事务

[NHibernate]并发控制

[NHibernate]组件之依赖对象

[NHibernate]一对多关系(级联删除,级联添加)

[NHibernate]一对多关系(关联查询)

[NHibernate]多对多关系(关联查询)

[NHibernate]延迟加载

[NHibernate]立即加载

[NHibernate]视图处理

[NHibernate]N+1 Select查询问题分析

Nhibernate中使用存储过程

这里使用MyGeneration Code来生成针对TB_Customer数据表的增删改的存储过程。MyGeneration Code是一款开源的代码生成器,下载地址MyGeneration Code

安装完成后,打开MyGeneration,如果第一次使用MyGeneration会自动弹出“默认设置”对话框,需要你对MyGeneration设置数据库连接字符串、模板语言、数据库驱动、模板存放路径等信息。

然后选择“save”对默认配置进行保存。然后MyGenration主界面就会弹出。如图

展开Microsoft SQL Server节点,找到“Script Insert/Update/Delete Procedures for SQL Server”模板,右击选择执行,我们利用这个模板为Customer表生成增删改存储过程。

打开后,这个模板界面如下,选择输出路径和数据库表,这里我输入路径为桌面,选择TB_Customer表,点击OK。截图如下:

此时在桌面“C:\Users\Wolfy\Desktop\Customer”中就会生成sql_procs_TB_Customer.sql文件,打开数据库,然后执行该文件中的sql脚本。

 sql_procs_TB_Customer.sql

我使用的是sql server2012的版本,在执行脚本的时候,生成添加Customer的存储过程,有问题

将NewId()函数去掉。修改后的存储过程

复制代码
 1 USE [Shop]
 2 GO
 3 --|--------------------------------------------------------------------------------
 4 --| [TB_CustomerInsert] - Insert Procedure Script for TB_Customer
 5 --|--------------------------------------------------------------------------------
 6 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id (N'[dbo].[TB_CustomerInsert]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1) DROP PROCEDURE [dbo].[TB_CustomerInsert]
 7 GO
 8 
 9 CREATE PROCEDURE [dbo].[TB_CustomerInsert]
10 (
11     @CustomerID uniqueidentifier OUTPUT,
12     @CustomerName nvarchar(16) = NULL,
13     @CustomerAddress nvarchar(128) = NULL,
14     @Version int
15 )
16 AS
17     SET NOCOUNT ON
18 
19     INSERT INTO [TB_Customer]
20     (
21         [CustomerID],
22         [CustomerName],
23         [CustomerAddress],
24         [Version]
25     )
26     VALUES
27     (
28         NEWID(),
29         @CustomerName,
30         @CustomerAddress,
31         @Version
32     )
33 
34     RETURN @@Error
复制代码

生成的存储过程如下:

一个例子

在NHibernate的映射文件中,在Class元素中提供了<sql-delete>、<sql-insert>、<sql-update>元素用于删除、新建、更新对象,注意这三个元素顺序唯一,就是下图显示的顺序,在根元素提供了<sql-query>元素用来查询对象,下图显示在Class元素中的增删改存储过程元素。

删除对象

修改映射文件添加存储过程,打开Customer.hbm.xml映射文件,在Class元素下添加<sql-delete>节点,调用TB_CustomerDelete存储过程,TB_CustomerDelete存储过程有一个CustomerID参数,这里用一个问号表示:

    <!--存储过程,check参数:none/rowcount/param-->
    <sql-delete>exec TB_CustomerDelete ?</sql-delete>

测试

复制代码
 1         /// <summary>
 2         /// 通过存储过程方式删除客户信息
 3         /// </summary>
 4         /// <param name="customer"></param>
 5         /// <returns></returns>
 6         public bool DeleteCustomerByIDWithProcedure(Customer customer)
 7         {
 8             var session = NHibernateHelper.GetSession();
 9             using (ITransaction trans = session.BeginTransaction())
10             {
11                 try
12                 {
13                     session.Delete(customer);
14                     session.Flush();
15                     trans.Commit();
16                     return true;
17                 }
18                 catch (Exception)
19                 {
20                     trans.Rollback();
21                     throw;
22                 }
23             }
24         }
复制代码

此时会有一个异常“Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Wolfy.Shop.Domain.Entities.Customer#b0720295-9541-40b3-9994-610066224db8]”。这个错误是存储过程写法错误,我们修改TB_CustomerDelete存储过程,去掉SET NOCOUNT ON,代码片段如下:

复制代码
 1 ALTER PROCEDURE [dbo].[TB_CustomerDelete]
 2 (
 3     @CustomerID uniqueidentifier
 4 )
 5 AS
 6     --SET NOCOUNT ON
 7 
 8     DELETE 
 9     FROM   [TB_Customer]
10     WHERE  
11         [CustomerID] = @CustomerID
12 
13     RETURN @@Error
复制代码

再次运行进行测试,测试成功,查看生成的sql语句

你会发现在sql语句里面多了一个@p1的参数。这个参数为之前添加的Version参数,nhibernate中乐观并发控制添加的。

如何解决?

修改存储过程,将版本号添加上。

复制代码
 1 ALTER PROCEDURE [dbo].[TB_CustomerDelete]
 2 (
 3     @CustomerID uniqueidentifier,
 4     @Version int
 5 )
 6 AS
 7     --SET NOCOUNT ON
 8 
 9     DELETE 
10     FROM   [TB_Customer]
11     WHERE  
12         [CustomerID] = @CustomerID and [Version]=@Version
13 
14     RETURN @@Error
复制代码

不要忘了,此时的存储过程有两个参数了,版本号在映射文件中已经处理了,存储过程中已经帮咱们自动添加上了,如果是其他的参数可在映射文件通过"?,?..."添加多个参数。

    <!--存储过程,check参数:none/rowcount/param-->
    <sql-delete check="rowcount" >exec TB_CustomerDelete ?</sql-delete>

再次运行进行测试,成功,生成的sql语句

exec sp_executesql N'exec TB_CustomerDelete @p0',N'@p0 uniqueidentifier,@p1 int',@p0='3727A133-C079-4DF9-B31E-7625B03F95DF',@p1=1

当然了,如果你不想使用存储过程,也可以直接在<sql-delete>中写SQL语句,像这样,照样用。

  <sql-delete>DELETE FROM [TB_Customer] WHERE [CustomerID] = ? and [Version] =?</sql-delete>

生成的sql语句为

exec sp_executesql N'DELETE FROM [TB_Customer] WHERE [CustomerID] = @p0 and [Version] =@p1',N'@p0 uniqueidentifier,@p1 int',@p0='64C35DEE-84D9-4C2D-ABAF-7D53631E3EAA',@p1=1

总结

这篇文章主要介绍了代码生成器的简单使用及nhibernate中使用存储过程删除数据的过程。

参考文章:http://www.cnblogs.com/lyj/archive/2008/11/03/1325291.html

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/4085314.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Castle.ActiveRecord 使用 存储过程 返回实体类
Castle,ActiveRecord,使用,存储过程,实体类 这几日就在研究这个问题 寻遍网上,也没找到个解决方法只有在NHibernate里执行存储过程 里面操作NHibernate的一点方法 于是动手写成了以下这个类 当然,只能保证测试可以通过,可能还有很多问题,要一个一个解决  1namespace ChAlumna.
723 0
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
8384 0
JDBC调用存储过程,以及存储过程 事务的使用.....
在JDBC中调用存储过程 首先就要在数据库中存在 要调用的过程  ,存储过程是一组SQL语句的集合,我们吧实现某一功能的 SQL语句集合在一起来使用,方便了用户,不光是这样,存储过程可以预编译,也就是说只要调用了一次存储过程,那么下次在调用存储过程的时候 就不需要进行再次编译了  。
821 0
Sql Server 存储过程使用技巧
1、创建带Try。。。Catch的存储过程模板   Copy下面的代码,然后新建查询,就可以写sql语句,执行完后,一个你自己的存储过程就建立好了! USE [DB]--设定对应的数据库 GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER O...
683 0
8系列TEE-Lite异常中断向量表和服务程序的存储结构
本次介绍主要介绍和异常,中断相关的几种存储方式,在传统的处理器设计中,中断和异常是需要通过异常/中断向量表作为索引的,根据不同的应用场景会出现一张或者多张一场异常/中断向量表。
286 0
+关注
1878
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载