NHibernate 映射基础(第三篇) 简单映射、联合主键
NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源。
一、简单映射
下面先来一个简单的例子,然后随着不断地对这个例子修修改改,从而真正了解映射文件。具体的资料可以查看http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html
先来看一张表:
映射文件Product.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Model.ProductModel, Model" table="Product">
<id name="ProductId" column="ProductId" type="Int32">
<generator class="native"/>
</id>
<property name="ProductName" column="ProductName" type="String"/>
<property name="ProductPrice" column="ProductPrice" type="float"/>
<property name="ProductDiscount" column="ProductDiscount" type="float"/>
<!--这个属性没有与之对应的列,其列为ProductPrice * ProductDiscount相乘得来-->
<property name="ActualPrice" formula="ProductPrice * ProductDiscount" type="float"/>
</class>
</hibernate-mapping>

PersonModel.cs:

namespace Model
{
public class ProductModel
{
public virtual int ProductId { get; set; }
public virtual string ProductName { get; set; }
public virtual float ProductPrice { get; set; }
public virtual float ProductDiscount { get; set; }
public virtual float ActualPrice { get; set; } //数据库里并没有这个字段
}
}

在这里要注意下最后一个字段,数据库里并没有这个字段。
ProductDao.cs:

public class ProductDao
{
public ProductModel GetProduct(int Id)
{
ISession NSession = NHibernateHelper.GetSession();
return NSession.Get<ProductModel>(Id);
}
}

Program.cs:
static void Main(string[] args)
{
ProductDao dao = new ProductDao();
ProductModel pm = dao.GetProduct(1);
Console.WriteLine(pm.ProductId + " " + pm.ProductName + " " + pm.ProductPrice + " " + pm.ProductDiscount + " " + pm.ActualPrice);
}
显示结果如下:
你可能奇怪,为什么最后一个字段数据库没有,但是为什么也能够查询出结果呢?答案在于配置里面的
formula="ProductPrice * ProductDiscount"
这个属性配置之后,允许某字段的值从其他字段计算获得。
我们来看看生成的SQL代码

exec sp_executesql N'SELECT productmod0_.ProductId as ProductId4_0_, productmod0_.ProductName as ProductN2_4_0_, productmod0_.ProductPrice as ProductP3_4_0_,
productmod0_.ProductDiscount as ProductD4_4_0_, productmod0_.ProductPrice * productmod0_.ProductDiscount as formula0_0_ FROM Product productmod0_ WHERE productmod0_.ProductId=@p0',N'@p0
int',@p0=1
--以上SQL代码相当于
SELECT ProductId,ProductName,ProductPrice,ProductDiscount, ProductPrice * ProductDiscount AS formula FROM Product

其实,这是NHibernate根据我们的配置,帮我们生成了SQL语句,计算出另外的字段并绑定的对应的属性当中。
下面我们开始来不断更改,以了解更多的NHibernate配置的作用。
我们将Product.hbm.xml的第一行加上下面这一句:
select-before-update="true"
<class name="Model.ProductModel, Model" table="Product" select-before-update="true">
然后PersonDao.cs增加此方法:
public void UpdateProduct(ProductModel product)
{
ISession NSession = NHibernateHelper.GetSession();
NSession.Update(product);
NSession.Flush();
}
用于更新一个Product。
Program.cs:
static void Main(string[] args)
{
ProductDao dao = new ProductDao();
ProductModel pm = dao.GetProduct(1);
dao.UpdateProduct(pm);
}
对于此操作,SQL Server Profiler检测到执行了如下语句:

exec sp_executesql N'SELECT productmod0_.ProductId as ProductId4_0_, productmod0_.ProductName as ProductN2_4_0_, productmod0_.ProductPrice as ProductP3_4_0_,
productmod0_.ProductDiscount as ProductD4_4_0_, productmod0_.ProductPrice * productmod0_.ProductDiscount as formula0_0_ FROM Product productmod0_ WHERE productmod0_.ProductId=@p0',N'@p0
int',@p0=1
--相当于如下语句
SELECT ProductId,ProductName,ProductPrice,ProductDiscount FROM Product WHERE ProductId = 1

而当我们去掉
select-before-update
或者将其值设置为flase时,就会直接执行UPDATE语句。select-before-update的作用在于,控制在UPDATE语句之前是否先执行一次查询,以检查对象是否有变化,当数据发生变化之后才UPDATE,否则不UPDATE。
二、联合主键
新建一张表如下:
以上3列数据都是NVarchar()类型。
下面来看配置映射文件:
Composite.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Model.CompositeModel, Model" table="Composite">
<composite-id name="Pk" class="Model.PKModel, Model"> //name为主实体类的属性名
<key-property name="Id1" type="String" column="Id1"/>
<key-property name="Id2" type="String" column="Id2"/>
</composite-id>
<property name="Name" column="Name" type="String"/>
</class>
</hibernate-mapping>

CompositeModel.cs
public class CompositeModel
{
public virtual PKModel Pk { get; set; }
public virtual string Name { get; set; }
}
PKModel.cs

public class PKModel
{
public virtual string Id1 { get; set; }
public virtual string Id2 { get; set; } /// <summary>
/// 判断两个对象是否相同,这个方法需要重写
/// </summary>
/// <param name="obj">进行比较的对象</param>
/// <returns>真true或假false</returns>
public override bool Equals(object obj)
{
if (obj is PKModel)
{
PKModel pk = obj as PKModel;
if (this.Id1 == pk.Id1 && this.Id2 == pk.Id2)
{
return true;
}
}
return false;
} public override int GetHashCode()
{
return base.GetHashCode();
}
}

操作:

class Program
{
static void Main(string[] args)
{
ISessionFactory _sessionFactory = new Configuration().Configure().BuildSessionFactory();
using(ISession NSession = _sessionFactory.OpenSession())
{
IList<CompositeModel> ListComposite = NSession.Query<CompositeModel>().ToList();
foreach (var c in ListComposite)
{
Console.WriteLine(c.Name);
} //查询单条
PKModel pk = new PKModel();
pk.Id1 = "01";
pk.Id2 = "1";
CompositeModel m = NSession.Get<CompositeModel>(pk);
Console.WriteLine(m.Name);
}
Console.ReadKey();
}
}

输出:
要点:1、联合主键提取出来作为一个类
2、要重写两个方法
NHibernate 映射基础(第三篇) 简单映射、联合主键的更多相关文章
- NHibernate 组件基础 (第六篇)
NHibernate 组件基础 (第六篇) 一.组件简介 组件(Component)可以理解为被一个对象所包含的对象而持久化,而并非一个实体.简单说来,假如数据库有FirstName,LastName ...
- Hibernate注解映射联合主键的三种主要方式
今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...
- 联合主键用Hibernate注解映射的三种方式
第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主 ...
- Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/A ...
- hibernate 注解 联合主键映射
联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解 ...
- Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)
Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessio ...
- Hibernate联合主键映射
1.联合主键的映射规则 1) 类中的每个主键属性都对应到数据表中的每个主键列. Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法, ...
- Hibernate笔记③--集合映射、组合映射、联合主键、查询案例
lazy 懒加载 默认为proxy 继承映射 discriminant column="type" type="string" 集合映射 生成表的语句: ...
- hibernate里联合主键composite-id映射,查询单个主键的问题
今天项目中遇到这个问题,搞了大半天,现在记录下来hibernate里联合主键配置(多个字段一起作为主键) <class name="com.cskj.hibernate.map.BbW ...
随机推荐
- Reverse Words in a String II -- LeetCode
Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...
- iptables实现IP地址重定向(转发)
iptables不单只防火墙这么简单,NAT转发这些都很强大.但是市面上iptables的教程基本都是围绕着CentOS 6来展开的,而对于CentOS 7和Ubuntu又不一样的写法,尤其是Ubun ...
- C语言的运算符、位操作
+ - * / (加 减 乘 除) > >= < <= (大于 大于等于 小于 小于等于) == != (测试等于 测试不等于) && || ! (逻辑与 逻辑 ...
- ostu进行遥感图像的分割
城市地区道路网的简单的阈值分割.采用的是单ostu(最佳阈值分割)算法,废话少说,如果不太清楚该算法,请参考文献[1]中的图像分割这一章的介绍.程序直接运行的效果如下.
- 怎样设计REST中间件---中间件JSON对数据库数据的组织
怎样设计REST中间件---中间件JSON对数据库数据的组织 SQL查询语句有:select SQL非查询语句有:insert, update, delete 三种 中间件JSON对数据库数据的组织也 ...
- easyUI样式之easyui-switchbutton
HTML文件 <tr> <th>是否发送短信:</th> <td> <input id="sendTxt" name=&quo ...
- Linux用户配置sudo权限(visudo)
sudo的工作过程如下: 1,当用户执行sudo时,系统会主动寻找/etc/sudoers文件,判断该用户是否有执行sudo的权限 2,确认用户具有可执行sudo的权限后,让用户输入用户自己的密码确认 ...
- 排序算法的实现(冒泡,选择,插入 O(N*N)--理解方法实现
以前也看过很多排序算法的原理,每次都想自己实现一下,一直都再拖,现在着牛课网学习算法课程,希望自己能够坚持练习. //对于一个int数组,请编写一个选择冒泡算法,对数组元素排序. //给定一个int数 ...
- Attribute 和 Parameter 的区别
Attribute 和 Parameter 的区别 (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为 ...
- Filter及FilterChain的详解
一.Filter的介绍及使用 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中.但是与其他web应用程序组件不同的是,过滤器是"链&quo ...