NHibernate考察实例:简单映射
建立一个Company类用来测试,对应的表为TBLCOMPANY。
1. 下载NHibernate(版本1.2.0.CR1),将NHibernate \bin\net-2.0下面的文件拷贝到lib目录。
2. 为实体建立Class Library的Domain工程。为工程添加\lib\Iesi.Collections.dll文件的引用(以后用)。
3. Company类的代码如下
using System;
using Iesi.Collections.Generic;
namespace NH12.MyExample.Domain
{
#region Company
public class Company
{
private string _companyID;
private string _companyName;
public Company(string id, string name)
{
_companyID = id;
_companyName = name;
}
public Company()
{
}
public virtual string CompanyID
{
get { return _companyID; }
set { _companyID = value; }
}
public virtual string CompanyName
{
get { return _companyName; }
set { _companyName = value; }
}
#region override
public override bool Equals(object obj)
{
if (this == obj) return true;
if (obj == null || obj.GetType() != this.GetType())
return false;
Company company = obj as Company;
return company != null && company.CompanyID == _companyID;
}
public override int GetHashCode()
{
return _companyID.GetHashCode();
}
public override string ToString()
{
return _companyID;
}
#endregion
}
#endregion
}
4. 将NHibernate源代码中的nhibernate-mapping.xsd文件拷贝到Domain工程的目录下,也可以拷贝到VS 2005的系统目录,这是因为映射文件使用这个xsd进行校验、输入提示等。为Domain工程添加Company.hbm.xml映射文件,在文件的属性->Build Action中选择Embedded Resource,文件内容如下
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NH12.MyExample.Domain" assembly="Domain">
<class name="Company" table="TBLCOMPANY">
<id name="CompanyID" >
<column name="COMPANY_ID" sql-type="nvarchar" length="4" not-null="true"/>
<generator class="assigned" />
</id>
<property name="CompanyName">
<column name="COMPANY_NAME" length="70" sql-type="nvarchar" not-null="true" />
</property>
</class>
</hibernate-mapping>
5. 添加一个Console Application的NHTest工程。为工程添加\lib\Iesi.Collections.dll、\lib\NHibernate.dll文件的引用,添加Domain项目引用。
6. 将NHibernate源代码中的nhibernate-configuration.xsd文件拷贝到NHTest工程的目录下,也可以拷贝到VS 2005的系统目录,这是因为配置文件使用这个xsd进行校验、输入提示等。
在NHTest的App.config文件中添加如下配置:
<configSections>
<section
name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"
/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.connection_string">Server=localhost;initial catalog=NH;user id=sa;password=123</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="use_proxy_validator">False</property>
<mapping assembly="Domain" />
</session-factory>
</hibernate-configuration>
数据库连接字符串信息改成自己的。注意1.2版本中配置信息不再支持方式,而改用property元素,相应的name只需要把原来name值中的nhibernate.这个前缀去掉就可以,value的方式没有发生变化。
7. 写代码测试。测试代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using NH12.MyExample.Domain;
using NHibernate;
using NHibernate.Cfg;
using Iesi.Collections.Generic;
namespace NH12.MyExample.Test
{
class Program
{
static void Main(string[] args)
{
ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
ISession session = null;
ITransaction trans = null;
try
{
session = sessionFactory.OpenSession();
trans = session.BeginTransaction();
Company company = new Company("1000", "BenQ Guru Co., Ltd.");
session.Save(company);
Console.WriteLine("company 1000 has been created");
Company company2 = new Company("2000", "test company 2");
session.Save(company2);
Console.WriteLine("company 2000 has been created");
Company company3 = session.Get("1000");
Console.WriteLine("Company : id: {0} name: {1}", company3.CompanyID, company3.CompanyName);
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
}
finally
{
session.Close();
}
sessionFactory.Close();
Console.ReadLine();
}
}
}
现在可以运行这个最简单的映射示例,运行完之后可以在TBLCOMPANY表中查询到记录。
即使是最简单的例子,我们也可以发现一些东西。
如果你一边单步执行,一边打开SQL Server的SQL Profiler进行监控(监控的Event为Stored Procedures中的RPC:Completed),可以发现,在两个session.Save()方法以及session.Get<>()方法处,并没有产生任何跟数据库进行交互的SQL语句,而只有在trans.Commit()的时候,才会产生下面这样两条SQL:
exec sp_executesql N'INSERT INTO TBLCOMPANY (COMPANY_NAME, COMPANY_ID) VALUES (@p0, @p1)',
N'@p0 nvarchar(19),@p1 nvarchar(4)',
@p0 = N'BenQ Guru Co., Ltd.', @p1 = N'1000'
exec sp_executesql N'INSERT INTO TBLCOMPANY (COMPANY_NAME, COMPANY_ID) VALUES (@p0, @p1)',
N'@p0 nvarchar(14),@p1 nvarchar(4)',
@p0 = N'test company 2', @p1 = N'2000' 这是因为NHibernate在同一个session内会做对象的状态管理和缓存,对对象属性的修改被缓存起来,直到事务提交的时刻才将所有数据库更新操作应用到数据库上;在session.Get()获取对象时,先从当前session的缓存中查找是否已经存在该对象,如果有,则直接取出这个对象,而不会产生一条SQL查询。所以上面的测试只有两个INSERT语句。
在上面测试的基础上,运行如下的测试代码
ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
ISession session = null, session2=null;
ITransaction trans = null;
try
{
session = sessionFactory.OpenSession();
session2 = sessionFactory.OpenSession();
trans = session.BeginTransaction();
Company company = session.Get("2000");
company.CompanyName = "My Test Company ...";
Company company2 = session2.Get("2000");
session.Update(company);
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
}
finally
{
session.Close();
session2.Close();
}
sessionFactory.Close();
Console.ReadLine(); 执行的SQL语句如下:
exec sp_executesql
N'SELECT company0_.COMPANY_ID as COMPANY1_0_0_, company0_.COMPANY_NAME as COMPANY2_0_0_
FROM TBLCOMPANY company0_ WHERE company0_.COMPANY_ID=@p0',
N'@p0 nvarchar(4)', @p0 = N'2000'
exec sp_executesql
N'SELECT company0_.COMPANY_ID as COMPANY1_0_0_, company0_.COMPANY_NAME as COMPANY2_0_0_
FROM TBLCOMPANY company0_ WHERE company0_.COMPANY_ID=@p0',
N'@p0 nvarchar(4)', @p0 = N'2000'
exec sp_executesql N'UPDATE TBLCOMPANY SET COMPANY_NAME = @p0 WHERE COMPANY_ID = @p1',
N'@p0 nvarchar(19),@p1 nvarchar(4)', @p0 = N'My Test Company ...', @p1 = N'2000' 其中第1、2句分别在session.Get()和session2.Get()调用时产生,因为这是两个不同的session,并且缓存中都还没有要取的company对象。第3句是在trans.Commit()时产生的。 www.lefeng123.com
另外一点需要注意,NHibernate不允许修改主键值,如果有修改,在事务提交时会丢出一个异常。这个特性在使用业务上有意义的字段作为主键时可能会面临一些问题,不过从另一个方面看,就算这种情况下NH允许修改主键,因为其它对象可能已经根据这个主键值引用该对象,所以修改同样会造成问题。至少目前我接触的项目中,对象的业务主键是不允许修改的。托福答案
NHibernate考察实例:简单映射的更多相关文章
- NHibernate 映射基础(第三篇) 简单映射、联合主键
NHibernate 映射基础(第三篇) 简单映射.联合主键 NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源. 一.简单映射 下面先来 ...
- NHibernate变的简单
前言 这篇文章出自于我尝试学习使用Nhiberbnate的挫败感.我发现好像Nhibernate全部的介绍材料不是很模糊就是太详细.我所需要的就是一个简单直接的教程,能让我尽快对NHibernate熟 ...
- Fluent Nhibernate code frist简单配置
Fluent Nhibernate code frist简单配置 前言 在以前的项目开发过程中使用nhibernate做完orm映射工具需要编写大量的xml映射文件,项目过程中往往会因为一个字段等 ...
- vue.js之生命周期,防止闪烁,计算属性的使用,vue实例简单方法和循环重复数据
摘要:今天是比较糟糕的一天没怎么学习,原因是学校的wifi连不上了~~.今天学习一下vue的生命周期,如何防止闪烁(也就是用户看得到花括号),计算属性的使用,vue实例简单方法,以及当有重复数据时如何 ...
- redis5.0.3单实例简单安装记录
redis5.0.3单实例简单安装记录 日常需要测试使用,索性记录下来,免得临时又麻烦的找资料. yum -y install make gcc-c++ cmake bison-devel ncurs ...
- vue教程2-04 vue实例简单方法
vue教程2-04 vue实例简单方法 vue实例简单方法: vm.$el -> 就是元素 vm.$data -> 就是data <!DOCTYPE html> <htm ...
- NHibernate初入门之映射文件配置说明(三)
转载逆心http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 1. hibernate-mapping 这个元素包括以下可选 ...
- [NHibernate] 入门实例 NHibernate 3.3 GA + VS2010 +MySQL
题外话: 中国的技术论坛要赶上stackoverflow的水平.至少还需35年.中国程序猿笔者的特点是:太浮躁,太easy下总结.太自得其乐,虽说写的是为了让别人更好的看.却也演变成了一种" ...
- NHibernate多对多关联映射的实现
上次用EF演示了数据库多对多关系的操作,这次我们还是引用上次的案例,来演示如何在C#当中使用NHibernate. 首先介绍一下NHibernate框架的来源.熟悉Java编程的读者肯定知道Hiber ...
随机推荐
- 【HDOJ】2428 Stars
先排序后二分. #include <iostream> #include <cstdio> #include <cstring> #include <algo ...
- 牛逼的bootcss之buttons
css源码 /*! @license * * Buttons * Copyright 2012-2014 Alex Wolfe and Rob Levin * * Licensed under the ...
- phpMyAdmin 多个跨站脚本漏洞
漏洞名称: phpMyAdmin 多个跨站脚本漏洞 CNNVD编号: CNNVD-201307-649 发布时间: 2013-08-09 更新时间: 2013-08-09 危害等级: 中危 漏洞类 ...
- Java---获得系统窗口的分辨率
//获得系统屏幕分辨率 //得到当前屏幕的分辨率:Toolkit.getDafaultToolkit().getScreenSize() Toolkit t = Toolkit.getDefaultT ...
- Python 实时日志平台 Sentry
原文地址:http://www.oschina.net/p/sentry Sentry 是一个实时的事件日志和聚合平台,基于 Django 构建. Sentry 可以帮助你将 Python 程序的所有 ...
- First Record
今天我在博客园安家了! R Python Scala hadoop Spark MachineLearning
- 使用string
public class UsingString { public static void testFindStr(String str) { System.out.p ...
- tessilstrona
Untitled Document
- Solr系列二:Solr与mmseg4j的整合
mmseg4j是一个很好的中文分词器,solr与mmseg4j的整合也非常简单.如下: 第一步:下载mmseg4j的jar包,网上搜索一下有很多下载地址,如下是csdn上的一个连接:http://do ...
- Linux 和 Windows 下对long long的输出
以前一直用__int64来识别windows还是Linux,可是发现HDU好像不认 看到wzy用的UNIX可以. UNIX是Linux下定义的,具体是什么可以去百度. 那么就可以 #ifdef UNI ...