我的NHibernate之行(二):增删改

上一篇博客,通过一个小Demo来大致的介绍了NHibernate的使用过程。使用NHibernate,最根本还是“CRUD”(增删改查)。我们常常所说的一个工作单元,通常是执行1个或多个操作,对这些操作要么提交要么放弃/回滚。如果只查询数据,不改变它的值,就不需要提交(或者回滚)到数据库。对于查询操作,内容比较多,这次就不涉及。本文仅仅介绍一下增删改操作。

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

新建对象

    通过调用ISession.Save()方法,然后同步同步到数据库。

例子:在数CRUD.cs类中编写CreateCustomer()方法,把传过来的Customer对象保存在数据库中。

/// <summary>
/// 新建对象
/// </summary>
/// <param name="customer"></param>
/// <returns></returns>
public int CreateCustomer(Customer customer)
{
    int newid = (int)_session.Save(customer );
    _session.Flush();
    return newid;
}

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

/// <summary>
/// 创建测试
/// </summary>
[Test]
public void CreateCustomerTest()
{
    var customer = new Customer() { Firstname = "Lianhai", Lastname = "Zhang" };
    int newIdentity = _crud.CreateCustomer(customer);
    var testCustomer = _crud.GetCustomerById(newIdentity);
    Assert.IsNotNull(testCustomer);
}

    看一下测试效果图

    数据库中的结果

删除对象

    查出一个对象,调用ISession.Delete(),同步到数据库。

但是这种方法也有个问题,这种方法要先把这条记录查出来(SELECT),然后映射成实体,再把实体传回去执行删除操作(DELETE)。这样处理可能能够解决缓存与数据库同步等一系列问题。

HQL是NHibernate特有的操作语言,它能够理解,既然能理解那么就能正常处理与缓存的关系(未实测),不过跟踪了SQL语句,还是先查询后删除,唯一不同只是返回多了一个影响行数。

如果不使用NHibernate的缓存功能,可以考虑使用CreateSQLQuery的方式删除,在这里忽略了,后续博客将会介绍。

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

/// <summary>
/// 删除对象
/// </summary>
/// <param name="customer"></param>
public void DeleteCustomer(Customer customer)
{
    _session.Delete(customer);
    _session.Flush();
}

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

/// <summary>
/// 删除测试
/// </summary>
[Test]
public void DeleteCustomerTest()
{
    var coutomer = _crud.GetCustomerById(1);
    _crud.DeleteCustomer(coutomer);
    var testCustomer = _crud.GetCustomerById(1);
    Assert.IsNull(testCustomer);
}

不知为什么,测试结果Delete语句没出来,但是数据库中已经变化了。(下面的更新与保存更新同样没出来相应的语句,测试的图就暂时不贴了)直接看一下数据库中的结果吧。那条记录已经不在了。

更新对象

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

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

/// <summary>
/// 更新对象
/// </summary>
/// <param name="customer"></param>
public void UpdateCustomer(Customer customer)
{
    _session.Update(customer);
    _session.Flush();
}

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

/// <summary>
/// 更新测试
/// </summary>
[Test]
public void UpdateCustomerTest()
{
    var customer = _crud.GetCustomerById(2);
    customer.Firstname = "lh";
    _crud.UpdateCustomer(customer);
    var testCustomer = _crud.GetCustomerById(2);
    Assert.AreEqual("lh", customer.Firstname);
}

    看一下数据库中的结果,“Lianhai”改为“lh”了:

保存更新对象

你会不会想出这个问题?哪些是刚刚创建的对象,哪些是修改过的对象?对于刚刚创建的对象我们需要保存到数据库中,对于修改过的对象我们需要更新到数据库中。NHibernate能够做到自动判断是应该执行INSERT还是UPDATE。这就是SaveOrUpdate()方法,当我们执行这个方法的时候,NHibernate完成如下工作:

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

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

/// <summary>
/// 保存更新对象
/// </summary>
/// <param name="customer"></param>
public void SaveOrUpdateCustomer(IList<Customer> customer)
{
    foreach (var c in customer)
    {
        _session.SaveOrUpdate(c);
    }
    _session.Flush();
}

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

/// <summary>
/// 保存更新测试
/// </summary>
[Test]
public void SaveOrUpdateCustomerTest()
{
    IList<Customer> customers=new List<Customer>() ;

    var oldCustomer = _crud.GetCustomerById(2);
    oldCustomer.Lastname = "张";
    customers.Add(oldCustomer);

    var c1 = new Customer() { Firstname = "Lianhai", Lastname = "Zhang" };
    var c2 = new Customer() { Firstname = "Lianhai", Lastname = "Zhang" };
    customers.Add(c1);
    customers.Add(c2);

    _crud.SaveOrUpdateCustomer(customers);
}

看一下数据库,第一条数据是更新的,下面是新添加上的:

总结

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

时间: 2025-01-02 18:01:44

我的NHibernate之行(二):增删改的相关文章

extjs_03_grid(弹出框&amp;行编辑器 增删改数据)

1.弹出框(新增,删除) <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP "index

EasyUI----DataGrid行明细增删改操作

http://blog.csdn.net/huchiwei/article/details/7787947 本文实现的是EasyUI-DataGrid行明细的增删改操作.具体参考来自以下文章: 官方DEMO---- DataGrid ---- Master Detail 在easyui中利用DataGrid的行明细区域实现CRUD操作---- 作者:stworthy BuildCRUD Application with edit form in expanded row details jQue

mybatis入门(二):增删改查

mybatis的原理: 1.mybatis是一个持久层框架,是apache下的顶级项目 mybatis托管到googlecode下,目前托管到了github下面 2.mybatis可以将向prepareStatement中输入的参数自动进行输入映射,将查询结果集灵活的映射成java对象.(输出映射) mybatis的一般使用到的maven包: <dependency> <groupId>mysql</groupId> <artifactId>mysql-co

mybatis入门二-----增删改查

一.使用MyBatis对表执行CRUD操作--基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapp

利用sed命令行进行增删改查

sed主要用来自动编辑一个或多个文件:简化对文件的反复操作:非交互式编译文件 语法:sed [options] '[command]' [filename]options:-n 抑制自动(默认的) 输出(全部打印) 读取下一个输入行, -n 要读取的行号-e 执行多个sed指令-f 运行脚本-i 编辑文件内容-i.bak 编辑的同事创造.bak的备份-r 使用扩展的正则表达式 command:a 在匹配后追加i 在匹配后插入p 打印d 删除r/R 读取文件/一行w 另存s 查找c 替换y 替换h

ThinkPHP 数据库操作(二) : 增删改查

基本使用 可以直接使用数据库运行原生SQL操作了,支持 query (查询操作)和 execute (写入操作)方法,并且支持参数绑定. Db::query('select * from think_user where id=?',[8]); Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']); 也支持命名占位符绑定,例如: Db::query('select * from think_us

mybatis学习之二 增删改查

1.配置映射文件grilsMapper.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mappe

HBase命令(二) -- 增删改查

HBase数据库表操作 hbase shell> list //列出所有表 hbase shell> create 'mytable','col1','col2' //建表语句 create '表名','列簇名','列簇名','列簇名' hbase shell> scan 'mytable' //遍历表内容 hbase shell> describe 'mytable' //查看表的结构构造 hbase shell> get 'mytable','rowkey1' //获取表

数据库开发基础-SQl Server 控制数据库的服务+数据库的创建与管理(增删改查)

控制数据库的服务: 方法一: 1.Windows+R 打开运行  打开cmd 2.输入net start MSSQLserver 启动数据库服务 输入net stop MSSQLserver 关闭数据库服务 输入net pause MSSQLserver 暂停数据库服务 输入net continue MSSQLserver 继续数据库服务 数据库的创建与管理(增删改查): 打开SQL Server 2008 方法二: 1.打开控制面板→管理工具→服务 2.右键进行选择 数据库的创建与管理: 打开

mybatis之增删改查

一. 简介: Mybatis本是apache的一个开源项目ibatis, 2010年这个项目由apache software foundation迁移到了google code, 并且改名为Mybatis. Mybatis是一个基于Java的持久层框架. 二. 增删改查: 1. 代码结构图: 2. User实体类: /** * User实体类 */ public class User { private String id; private String uname; // 注意: 该字段名称与