本节内容

  • 操作数据概述
  • 1.新建对象
  • 2.删除对象
  • 3.更新对象
  • 4.保存更新对象
  • 结语

操作数据概述

我们常常所说的一个工作单元,通常是执行1个或多个操作,对这些操作要么提交要么放弃/回滚。想想使用LINQ to SQL,一切的东西都在内存中操作,只有调用了DataContext.SubmitChanges()方法才把这些改变的数据提交到数据库中,LINQ to SQL那么提交要么回滚。

我们使用NHibernate也一样,如果只查询数据,不改变它的值,就不需要提交(或者回滚)到数据库。

注意:这节,我们在上一节源代码的基础上,在数据访问层中新建CRUD.cs类用于编写操作方法,在数据访问的测试层新建一CRUDFixture.cs类用于测试。

1.新建对象

简单描述:新建一个对象;调用ISession.Save();同步ISession。

例子:在数据访问层编写CreateCustomer()方法,把传过来的Customer对象保存在数据库中。

public int CreateCustomer(Customer customer)
{
int newid = (int)_session.Save(customer);
_session.Flush();
return newid;
}

我们测试这个方法,新建一个Customer对象,调用CreateCustomer()方法返回新插入的CustomerId,再次根据CustomerId查询数据库是否存在这个对象。

[Test]
public void CreateCustomerTest()
{
var customer = new Customer() { Firstname = "YJing", Lastname = "Lee" };
int newIdentity = _crud.CreateCustomer(customer);
var testCustomer = _crud.GetCustomerById(newIdentity);
Assert.IsNotNull(testCustomer);
}

2.删除对象

简单描述:获取一个对象;调用ISession.Delete();同步ISession。

说明:使用ISession.Delete()会把对象的状态从数据库中移除。当然,你的应用程序可能仍然持有一个指向它的引用。所以,最好这样理解:Delete()的用途是把一个持久化实例变成临时实例。 你也可以通过传递给Delete()一个NHibernate 查询字符串来一次性删除很多对象。删除对象顺序没有要求,不会引发外键约束冲突。当然,有可能引发在外键字段定义的NOT NULL约束冲突。

例子:在数据访问层编写DeleteCustomer()方法,从数据库中删除Customer对象。

public void DeleteCustomer(Customer customer)
{
_session.Delete(customer);
_session.Flush();
}

我们测试这个方法,在数据库中查询CustomerId为2的Customer对象,调用DeleteCustomer()方法删除,再次根据CustomerId查询数据库是否存在这个对象。

[Test]
public void DeleteCustomerTest()
{
var coutomer = _crud.GetCustomerById(2);
_crud.DeleteCustomer(coutomer);
var testCustomer = _crud.GetCustomerById(2);
Assert.IsNull(testCustomer);
}

3.更新对象

简单描述:获取一个对象;改变它的一些属性;调用ISession.Update();同步ISession。

例子:在数据访问层编写UpdateCustomer()方法,修改Customer对象。

public void UpdateCustomer(Customer customer)
{
_session.Update(customer);
_session.Flush();
}

测试这个方法,在数据库中查询CustomerId为1的Customer对象并修改它的Firstname属性值,调用UpdateCustomer()方法更新,再次查询数据库中CustomerId为1的Customer对象的Firstname值为修改之后的值。

[Test]
public void UpdateCustomerTest()
{
var customer = _crud.GetCustomerById(1);
customer.Firstname = "liyongjing";
_crud.UpdateCustomer(customer);
var testCustomer = _crud.GetCustomerById(1);
Assert.AreEqual("liyongjing", customer.Firstname);
}

4.保存更新对象

你会不会想出这个问题?哪些是刚刚创建的对象,哪些是修改过的对象?对于刚刚创建的对象我们需要保存到数据库中,对于修改过的对象我们需要更新到数据库中。

幸好,ISession可以识别出这不同的对象,并为我们提供了ISession.SaveOrUpdate(object)方法

ISession.SaveOrUpdate(object)方法完成如下工作:

  • 检查这个对象是否已经存在Session中。
  • 如果对象不在,调用Save(object)来保存。
  • 如果对象存在,检查这个对象是否改变了。
  • 如果对象改变,调用Update(object)来更新。

看看下面例子说明了这种情况,在数据访问层编写SaveOrUpdateCustomer()方法,保存更新Customer对象列表,依次遍历列表中的Customer对象,调用ISession.SaveOrUpdate(object)方法保存更新每个Customer对象。

public void SaveOrUpdateCustomer(IList<Customer> customer)
{
foreach (var c in customer)
{
_session.SaveOrUpdate(c);
}
_session.Flush();
}

测试这个方法,先在数据库中查询Firstname为YJing的Customer对象并修改它的Lastname属性值,这些对象是数据库中存在的,并改变了,然后新建2个Customer对象,这两个对象在数据库中不存在,是新创建的。调用SaveOrUpdateCustomer()方法保存更新对象,即更新前面修改的对象和保存了后面新创建的2个对象。再次查询数据库中Firstname为YJing,Lastname为YongJing的Customer对象是否一致了。

[Test]
public void SaveOrUpdateCustomerTest()
{
IList<Customer> customers = _crud.GetCustomersByFirstname("YJing");
foreach (var c in customers)
{
c.Lastname = "YongJing";
}
var c1 = new Customer() { Firstname = "YJing", Lastname = "YongJing"};
var c2 = new Customer() { Firstname = "YJing", Lastname = "YongJing"};
customers.Add(c1);
customers.Add(c2);
int initiaIListCount = customers.Count; _crud.SaveOrUpdateCustomer(customers); int testListCount = _crud.GetCustomersByFirstnameAndLastname("YJing", "YongJing").Count;
Assert.AreEqual(initiaIListCount, testListCount);
}

结语

当然,这一节操纵对象操作,在NHibernate中涉及了对象的状态, 对象对一个特定的ISession来说,有三种状态分别是:瞬时(transient)对象、持久化(persistent)对象、游离(detached)对象。这一节没有说到了,以后在讨论Session的时候再介绍。

[转]NHibernate之旅(5):探索Insert, Update, Delete操作的更多相关文章

  1. LINQ体验(9)——LINQ to SQL语句之Insert/Update/Delete操作

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Insert/Update/Delete操作.这个在我们的程序中最为常用了.我们直接看例子. Insert/Update/Delete操作 插入( ...

  2. 基于SQL Server日志链查看数据库insert/update/delete操作(一)

    在MSSQLServer2008下的语句 不同版本可能语句会有微小差别 SELECT [Slot ID], [Transaction ID], Operation, AllocUnitName, [C ...

  3. 关于MyBatis mapper的insert, update, delete返回值

    这里做了比较清晰的解释: http://mybatis.github.io/mybatis-3/java-api.html SqlSession As mentioned above, the Sql ...

  4. PHP5: mysqli 插入, 查询, 更新和删除 Insert Update Delete Using mysqli (CRUD)

    原文: PHP5: mysqli 插入, 查询, 更新和删除  Insert Update Delete Using mysqli (CRUD) PHP 5 及以上版本建议使用以下方式连接 MySQL ...

  5. mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干

    1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...

  6. [Hive - LanguageManual] DML: Load, Insert, Update, Delete

    LanguageManual DML Hive Data Manipulation Language Hive Data Manipulation Language Loading files int ...

  7. insert update delete 语法 以及用法

    insert update delete 被称为 数据定义语句语句 也就是数据的增加 修改 删除 其中不包括查询 譬如: create database -创建数据库 alter database - ...

  8. sql中同一个Trigger里同时包含Insert,Update,Delete

    sql中同一个Trigger里同时包含Insert,Update,Delete SQLServer是靠Inserted表和Deleted表来处理的,判断一下就可以了,只不过比ORACLE麻烦一点 cr ...

  9. mybatis select/insert/update/delete

    这里做了比较清晰的解释: http://mybatis.github.io/mybatis-3/java-api.html SqlSession As mentioned above, the Sql ...

随机推荐

  1. oc文件基本读写及操作

    代码: #import <Foundation/Foundation.h> //NSString 写文件 void stringWriteToFile(){ NSString *path ...

  2. (转)iOS学习之 plist文件的读写

    在做iOS开发时,经常用到到plist文件, 那plist文件是什么呢? 它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件.属性列表文件的扩展名为.plist ...

  3. Entity Framework 的事务 DbTransaction

    事务代码实现如下: public static void Transaction() { myitEntities entity = null; DbTransaction tran = null; ...

  4. 【CMD】findstr命令

    findstr用来搜索匹配字符串的文件. FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [ ...

  5. java 各种排序算法

    各种排序算法的分析及java实现   排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说 ...

  6. 如何让U盘支持大于4G的文件

    U盘通常是FAT(*)格式,不能支持大于4G的文件.为了实现这个目的,通常可以把U盘格式化成NTFS或者exFAT,这两种文件系统都支持大于4G的文件. 一.格式化成NTFS第一步首先我们把优盘插入电 ...

  7. c# .net使用SqlDataReader注意的几点

    转自:http://blog.knowsky.com/258608.htm 1.当SqlDataReader没有关闭之前,数据库连接会一直保持open状态,所以在使用SqlDataReader时,使用 ...

  8. javascript之事件

    客户端javascript程序采用了异步事件驱动编程模型. 相关事件的几个概念: 事件类型(event type):用来说明发生什么类型事件的字符串: 事件目标(event target):发生事件的 ...

  9. MyEclipse10.6导出war包出错

    在右键选中项目->export->java ee ->war 的时候,一点就报错SECURITY ALERT:INTEGRITY CHECK ...,之后自动关闭 这个问题是因为用的 ...

  10. const char * 的终结贴(看完无需其他任何文章,从此不再蛋疼)

    我之前也是以为我对const char *ptr 这种形式的写法是掌握了的,真的,不就是说一个指针是不可改变的吗? 那么问题就来了,到底是ptr指针本身不能改变,还是ptr执行的值不能改变呢? 从网上 ...