一、什么是NHibernate?
NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。
NHibernate官网:http://nhibernate.info/
NHibernate文档:http://nhibernate.info/doc/tutorials/first-nh-app/your-first-nhibernate-based-application.html
二、实战说明
1.上官网下载全新版本的NHibernate压缩包,就是那个Download Noew NHX.x-x.点击后下载,然后解压到一个没有中文的目录下(防止出现因中文路径导致的错误),进入 Required_Bins文件夹,找到NHibernate.dll,这个就是我们要引入的程序集。
2.打开VS,创建工程,选择Visual C#,控制台应用程序,解决方案名称:NHibernateMySql,名称:ConnectMysql(自己随意起就OK了)
3.保证启动Mysql,ctrl+alt+.按出任务管理提-点击服务菜单,看到有MySQL什么的正在启动就OK。若没有百度一下^_^
4.创建数据库test,表User,表中有【主键:Id(int),Username(varchar)】,Password(varchar)。
5.右击工程,点击属性,修改工程的默认命名空间为:NHMsql,程序集名称
6.创建Model文件夹,Mappings文件夹
5. 使用NHibernate完成类与数据库的映射关系流程如下:
1) 配置NHibernate映射数据库
2) 加载映射文件
3) 创建会话工厂
4) 打开会话
5) 使用会话进行业务操作
6.代码
6.1 配置NHibernate映射数据库
首先,新建NHibernate配置文件hibernate.cfg.xml (XML文件),命名一定要写hibernate.cfg.xml
hibernate.cfg.xml内容:<?xml version="1.0" encoding="utf-8" ?>
NHibernate.Connection.DriverConnectionProvider
NHibernate.Dialect.MySQL5Dialect
NHibernate.Driver.MySqlDataDriver
Server=localhost;Database=test;User ID=root;Password=root;
true
注意:MySql版本要设置好,如何查看自己的MySql版本?百度^_^. 还有,如果是MySql 5.X.x的,那么就是MySql5版本,如果是其他版本,只需要把那个5修改即可,我上面的是5号版本。
而且该文件的属性-高级,必须设置成:始终复制到输出目录
6.2 在Model文件夹下,新建User类using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NHMysql.Model
{
class User
{
public virtual int Id { get; set; }
public virtual string Username { get; set; }
public virtual string Password { get; set; }
}
}
6.3 配置User映射文件 (User.hbm.xml) (对后缀有要求,即后缀一定要写成.hbm.xml) 放入Mappings文件夹<?xml version="1.0" encoding="utf-8" ?>
assembly="NHMysql"
namespace="NHMysql.Model">
注意:该文件必须修改属性-高级:嵌入的资源
解释说明:
assembly="MHMysql" 指定程序集是MHMysql,这个程序集下的namespace="NHMysql.Model"命名空间,因为这个程序集下的命名空间有我们映射的类,也就是User类。
name指定了User类,table指定User类对应的是test数据库中的User表
这样,User类 与 User表就产生了一个映射关系。
下面的、都是设置类 与 表的 属性映射关系,name指定类的属性(Id,Username,Password),column指定表的字段(列)(Id,Username,Password)
而放在内是表明那个属性是主键映射关系,其他都是普通的属性映射。
(这里,有个错误没补全,那就是Username也是主键,而这里没放在 中,各位可以试试改为会不会出错。)
6.4 创建会话工厂
因为我们的程序需要不断地使用[会话]来进行业务操作,所以我们可以创建一个类专门处理[会话工厂]的创建以及打开[会话],便于我们获取会话对象,且减少代码冗余。
新建一个类NHibernateHelper,内容如下:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
namespace NHMysql
{
class NHibernateHelper
{
private static ISessionFactory _sessionFactory;//这就是会话工厂
private static ISessionFactory SessionFactory
{
get {
if (_sessionFactory == null)
{ //新建一个Configuration对象,用它来配置我们的映射环境,最终构建出一个会话工厂!
var configuration = new Configuration();
//配置映射数据库 即这个方法必定去解析名为:hibernate.cfg.xml的文件,该文件属性高级:始终复制到输出目录(这一步必须做,不然解析失败)
configuration.Configure();
//加载NHMysql程序集的映射文件 这些映射文件即 .hbm.xml后缀的,必须嵌入到程序集,即设置 属性->高级:嵌入的资源
configuration.AddAssembly("NHMysql");
//Session工厂,这个工厂就是处理由Configure配置的数据库操作,加载映射文件是为了能够将数据库上的表映射到相应的Model文件下的类
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
//打开会话
public static ISession OpenSession()
{
//返回一个Session会话对象,由外部关闭
return SessionFactory.OpenSession();
}
}
}
6.5 创建Manager管理类
因为我们业务操作的基本操作都需要增、删、改、查,所以我们新建一个接口interface,名为IBaseManager,它带一个泛型T,我们的所有Manager管理类都会继承它,而泛型T就是用于区分不同的管理类的。
IBaseManager接口:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NHMysql.Manager
{
interface IBaseManager
{
void Add(T user);
void Update(T user);
void Remove(T user);
T GetById(int id);
T GetByUsername(string username);
ICollection GetAllUser();
bool VerifyUser(string username, string password);
}
}
新建UserManager类:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Criterion;
using Sikiedu.Model;
namespace NHMysql.Manager
{
class UserManager:IBaseManager
{
#region IUserManager 成员
public void Add(Model.User user)
{
//using ()里面创建的对象会在using结构体中产生作用,并且在using结构体结束时候释放session资源
using (ISession session = NHibernateHelper.OpenSession())//打开会话
{
//同样,创建一个业务 也需要使用using 因为业务也要释放
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(user);//保存这个user进入数据库test的User表,为什么用session.Save 程序就会自动把这个user放入对应的表呢?那就是我们之前做的映射环境的作用啦.
transaction.Commit();//执行这一步,真正地执行保存操作
}
}
}
public void Update(Model.User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Update(user);
transaction.Commit();
}
}
}
public void Remove(Model.User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Delete(user);
transaction.Commit();
}
}
}
public Model.User GetById(int id)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
User user = session.Get(id);//这种获取方式最简单,通过主键Id获取User
transaction.Commit();
return user;
}
}
}
public Model.User GetByUsername(string username)
{
using (ISession session = NHibernateHelper.OpenSession())
{
//CreateCriteria(typeof(User))是代表从User表查询
//Add(Restrictions.Eq("Username", username)),Add相当于加条件,条件内容是Username==username,(Eq)是相等条件
//UniqueResult()是查询出的内容封装为User对象
return session.CreateCriteria(typeof (User)).Add(Restrictions.Eq("Username", username)).UniqueResult();
//关于Restrictions的使用http://nhibernate.info/doc/nh/en/index.html,搜Restrictions可看到相关例子
}
}
//注意返回值是ICollection
public ICollection GetAllUser()
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session.CreateCriteria(typeof (User)).List();//查询User表所有数据,返回一个User集合
}
}
#endregion
#region IUserManager 成员
//验证用户存在与否
public bool VerifyUser(string username, string password)
{
using (ISession session = NHibernateHelper.OpenSession())
{
User user = session.CreateCriteria(typeof(User))
.Add(Restrictions.Eq("Username", username))
.Add(Restrictions.Eq("Password",password)) //这样相当于where Username==username&&Password==password,也有另一种写法,用And来把它们2个相同条件封装起来
.UniqueResult();
if(user==null)
return false;
return true;
}
}
#endregion
}
}
Program.cs代码:
测试方法: IBaseManager userManager = new UserManager(); 然后用这个userManager里面的方法对test数据库User表进行增、删、改、查