共计 4586 个字符,预计需要花费 12 分钟才能阅读完成。
0. 前言
上一篇《C# 数据操作系列 – 11 NHibernate 配置和结构介绍》介绍了 Nhibernate 里的配置内容。这一篇将带领大家了解一下如何使用 NHIbernate。之前提到 NHibernate 继承了 Hibernate 的一些传统:使用 XML 文件进行配置,这一点也是备受争议。不过,有社区爱好者开发了一个名为《Fluent NHibernate》的项目,用来支持 NHibernate 的流式配置。当然,NHibernate 本身也提供了 NHibernate.Mapping.ByCode
模式。不过这一篇暂且略过,留待下文。
1. NHibernate 映射文件
对于 NHibernate 的映射文件有个约定的名字:
< 类名 >.hbm.xml
这里先为大家介绍一下映射文件的格式:
1.1 hibernate-mapping 的说明
<hibernate-mapping
schema="schemaName" (1)
default-cascade="none|save-update" (2)
auto-import="true|false" (3)
assembly="Eg" (4)
namespace="Eg" (5)
default-access="field|property|field.camecase..." (6)
default-lazy="true|false" (7)
/>
- schema: 数据库 schema 的名称
- default-cascade:可选项,默认是 none,一种默认的级联风格
- auto-import:明确是否可以在查询中使用非限定类名。
- assembly:指定映射对象所在的 assembly,一般情况指的是项目名称
- namespace:所在命名空间
- default-access:可选的,默认是 property,表示 NHibernate 的读取数据列的策略,默认情况从 Property 中读取
- default-lazy:可选的,默认是 true,是否启动延迟加载
1.2 class 的配置
一般情况下,class 节点只需要指定 name 和 table 就可以了。接下来,让我们探索 class 如何映射成的。
1.2.1 id
任何一个映射都必须声明一个数据表的主键,大多数类也必须有一个唯一标示字段用来区分不同的实例。
这里介绍一下 id 节点的配置:
<id
name="PropertyName"
type="typename"
column="column_name">
<generator class="generatorClass"/>
</id>
- name : 对应的属性名
- type:对应的 NHibernate 类型
- column:列名
- generator:主键生成器,如果不需要参数可以直接在 id 节点处添加,最常用的是 native。
1.2.2 property
映射一个普通属性就简单多了,只需要进行以下配置即可:
<property
name="propertyName"
column="column_name"
type="typename"
/>
- name:类里的属性名
- column:对应数据表的列名
- type:数据库中的类型
1.2.3 many-to-one
在 Nhibernate 中,多对一的配置是在一的一端,表示该类有一个外键导航。
<many-to-one
name="PropertyInOne"
class="ManyClass"
column="Column"
></many-to-one>
1.2.4 one-to-one
一对一的关系与多对一的关系比较相似,不同的地方在于一对一需要在双方的映射关系里均要维护,在有外键的表 / 实体中 添加 constrained=“true”。
示例如下:
<one-to-one name="Person" class="Person"/>
<one-to-one name="Employee" class="Employee" constrained="true"/>
2. 增删改查
Nhibernate 的每次操作都基于一个 Session,所以我们在操作数据库的时候最好先持有一个可用的 Session。接下来,我们就一个通用数据库操作类为基础,向大家分享一下我的想法。
首先,创建一个泛型模板类,并约束泛型为类:
public class Repository<T> where T: class
{}
添加一个 ISession 属性,用来后续访问操作,并由构造方法赋值:
public Repository(ISession session)
{Session = session;}
public ISession Session {get;}
2.1 新增
现在我们写一下新增方法:
public object Add(T entity)
{var key= Session.Save(entity);
return key;
}
public void Add(params T[] entities)
{foreach (var entity in entities)
{Session.Save(entity);
}
}
查了下,Save 会返回当前持久化对象插入时生成的主键。
2.2 修改
NHibernate 的修改与 EF 类似,也是由 ISession 监控了修改,不用做过多的操作。
2.3 删除
NHibernate 的删除也十分简单,直接通知 ISession 删除某个持久化对象。
public void Delete(T entity)
{Session.Delete(entity);
}
public void Delete(params T[] entities)
{foreach (var entity in entities)
{Session.Delete(entity);
}
}
2.4 查询
通常情况下,查询需要结合实际业务来进行开发,当然为了通用,我在这里选择给调用方开放一个查询对象:
public IQueryable<T> IqQueryable()
{return Session.Query<T>();
}
其中 IQueryable 是一个接口,表示这是一个可查询对象,通过 Linq 可以快捷的查询。
3. 总结
嗯,NHibernate 基础使用篇到这里可以暂告一段落了。后续的内容有机会再深挖,当然并不代表 EF Core 就没有了。嗯嗯,没毛病。下一篇就让我来先替大伙看看 SugarSQL 是什么情况吧。
不过在本篇内容完结之前,先补充一个 NHibernate 的 SqlDialect 选值:
数据库 | Dialect | 备注 |
---|---|---|
DB2 | NHibernate.Dialect.DB2Dialect | |
DB2 for iSeries(OS/400) | NHibernate.Dialect.DB2400Dialect | |
Firebird | NHibernate.Dialect.FirebirdDialect | 需要设置 driver_class 为 NHibernate.Driver.FirebirdClientDriver |
Informix | NHibernate.Dialect.InformixDialect | |
Informix 9.40 | NHibernate.Dialect.InformixDialect0940 | |
Informix 10.00 | NHibernate.Dialect.InformixDialect1000 | |
Ingres | NHibernate.Dialect.IngresDialect | |
Ingres 9 | NHibernate.Dialect.Ingres9Dialect | |
Microsoft SQL Server 7 | NHibernate.Dialect.MsSql7Dialect | |
Microsoft SQL Server 2000 | NHibernate.Dialect.MsSql2000Dialect | |
Microsoft SQL Server 2005 | NHibernate.Dialect.MsSql2005Dialect | |
Microsoft SQL Server 2008 | NHibernate.Dialect.MsSql2008Dialect | |
Microsoft SQL Azure Server 2008 | NHibernate.Dialect.MsSqlAzure2008Dialect | |
Microsoft SQL Server 2012 | Hibernate.Dialect.MsSql2012Dialect | |
Microsoft SQL Server Compact Edition | NHibernate.Dialect.MsSqlCeDialect | |
Microsoft SQL Server Compact Edition 4.0 | NHibernate.Dialect.MsSqlCe40Dialect | |
MySQL 3 or 4 | NHibernate.Dialect.MySQLDialect | |
MySQL 5 | NHibernate.Dialect.MySQL5Dialect | |
MySQL 5 InnoDB | NHibernate.Dialect.MySQL5InnoDBDialect | |
MySQL 5.5 | NHibernate.Dialect.MySQL55Dialect | |
MySQL 5.5 Inno DB | NHibernate.Dialect.MySQL55InnoDBDialect | |
Oracle | NHibernate.Dialect.Oracle8iDialect | |
Oracle 9i | NHibernate.Dialect.Oracle9iDialect | |
Oracle 10g, Oracle 11g | NHibernate.Dialect.Oracle10gDialect | |
Oracle 12c | NHibernate.Dialect.Oracle12cDialect | |
PostgreSQL | NHibernate.Dialect.PostgreSQLDialect | |
PostgreSQL 8.1 | NHibernate.Dialect.PostgreSQL81Dialect | 支持 8.1 的 FOR UPDATE NOWAIT |
PostgreSQL 8.2 | NHibernate.Dialect.PostgreSQL82Dialect | 在 DROP TABLE 和 DROP SEQUENCE 语句中支持 IF EXISTS 关键字 |
PostgreSQL 8.3 | NHibernate.Dialect.PostgreSQL83Dialect | 支持 XML 类型 |
SQLite | NHibernate.Dialect.SQLiteDialect | 设置 driver_class 为 NHibernate.Driver.SQLite20Driver |
Sybase Adaptive Server Anywhere 9 | NHibernate.Dialect.SybaseASA9Dialect | |
Sybase Adaptive Server Enterprise 15 | NHibernate.Dialect.SybaseASE15Dialect | |
Sybase SQL Anywhere 10 | NHibernate.Dialect.SybaseSQLAnywhere10Dialect | |
Sybase SQL Anywhere 11 | NHibernate.Dialect.SybaseSQLAnywhere11Dialect | |
Sybase SQL Anywhere 12 | NHibernate.Dialect.SybaseSQLAnywhere12Dialect |
更多内容烦请关注我的博客《高先生小屋》