NHbiernate映射工具连接MySQL的基本配置及使用
NHbiernate介绍
NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。
基本配置
NHbiernate基本配置
- 新建一个项目取名为NHibernateTest,项目中添加MySQL.Data和NHbiernate的引用。
- 在项目下创建一个XML文件,必须叫hibernate.cfg.xml ,因为NHbiernate会在根目录下找这个名字的xml文件,如果不叫这个名字会报错。并把该文件的属性设置 为始终复制。
在官网上找到以下代码,打开这个xml文件进行编辑:
官网是连的SQL Server, 这里连得是MySQL, 所以更改一下, 这里主要设置了第二行的MySQL5Dialect,和第三行的MySQLDataDriver,第四行的Server=localhost;Database=sikidb;User ID=root;Password=zzzzz; 注意一定把要访问的数据库名和用户名密码写正确。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.connection_string">Server=localhost;Database=sikidb;User ID=root;Password=zzzzz;</property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>
- 再新建一个Model文件夹,在这个文件夹下新建一个User类,把数据库中对应的表中的每行的数据名创建成每个变量,如下:
user表里有四列数据就写四个对应的变量,一定要是virtual 类型的,这是NHbiernate要求写法。
- 在项目下在创建一个Mappings文件夹,在这个文件夹下创建一个User.hbm.xml命名的xml文件,并把它的属性里的生成操作改为嵌入的资源。打开编辑一下代码:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateTest"
namespace="NHibernateTest.Model">
<class name="User" table ="users">
<id name="Id" column="id" type="Int32">
<generator class="native"></generator>
</id>
<property name="Username" column="username" type="String"></property>
<property name="Password" column="password" type="String"></property>
<property name="Registerdate" column="registerdate" type="Date"></property>
</class>
</hibernate-mapping>
这里主要是配置NHbiernate的映射,数据库里的表的每行数据名和类型都要正确填写,主键要多设置一行自动增长
到这里就基本配置完成了,下图是各个文件目录:
测试
在主函数里写下以下代码,测试一下NHbiernate连接MySql增加数据的功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NHibernateTest.Model;//引入自己创建的目录下的类
namespace NHibernateTest
{
class Program
{
static void Main(string[] args)
{
var config = new Configuration();
config.Configure();//开始解析文件hibernate.cfg.xml
config.AddAssembly("NHibernateTest");
ISessionFactory sessionFactory = null;
ISession session = null;
try
{
sessionFactory = config.BuildSessionFactory();
session = sessionFactory.OpenSession();//打开一个跟数据库的会话
User user = new User() { Username = "vvvv", Password = "121212" };
session.Save(user);//NHibernate里面的增加数据的方式,Session实例由ISessionFactory构建
//Session是Hibernate持久化操作的基础,提供了众多持久化方法,如save、update、delete等。通过这些方法,透明地完成对象的增加、删除、修改、查找等操作。
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
if (session != null)
{
session.Close();
}
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
Console.ReadKey();
}
}
}
运行前后对比
这张图是以上代码没有运行前数据库中的user表里的数据:
这个是运行后,数据库的数据,可以看到在最后增加了一条Username = “vvvv”, Password = “121212”,的数据:
注意
删除的不能直接使用session.Delete(user) ,百度了一下这段话: delete()方法用于从数据库中删除与Java对象对应的记录。如果传入的参数是持久化对象,Session就计划执行一个delete语句。如果传入的参数是游离对象,先使游离对象被Session关联,使它变为持久化对象,然后计划执行一个delete语句。值得注意的是,Session只有在清理缓存的时候的才执行delete语句。此外,只有当调用Session的close()方法时,才会从Session的缓存中删除该对象。需要先清理缓存,才可以执行删除:
try
{
sessionFactory = config.BuildSessionFactory();
session = sessionFactory.OpenSession();//打开一个跟数据库的会话
ITransaction transaction = session.BeginTransaction();//开启事务。删除的话需要写上这一句话,在提交事务时才可以删掉,不写的话,控制台不报任何错误,但是也没有删掉数据
User user = new User() {Id=18};
session.Delete(user);
transaction.Commit();// 提交事务,清理缓存,执行delete语句
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
if (session != null)
{
session.Close();
}
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
siki视频中的利用NHbiernate事务机制来增加和删除:
关于关闭这些需要注意,先开启的后关闭,后开启的先关闭
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NHibernateTest.Model;//引入自己创建的目录下的类
namespace NHibernateTest
{
class Program
{
static void Main(string[] args)
{
var config = new Configuration();
config.Configure();//开始解析文件hibernate.cfg.xml
config.AddAssembly("NHibernateTest");
ISessionFactory sessionFactory = null;
ISession session = null;
ITransaction transaction = null;
try
{
sessionFactory = config.BuildSessionFactory();
session = sessionFactory.OpenSession();//打开一个跟数据库的会话
transaction = session.BeginTransaction();//注册事务
User user = new User() { Username = "qwrrtu", Password = "131313" };
User user1 = new User() { Id = 26 }; //删除操作,只给主键值就可以了
session.Save(user);
session.Delete(user1);
transaction.Commit();//开启事务
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally //关于关闭这些需要注意,先开启的后关闭,后开启的先关闭
{
if (transaction != null)
{
transaction.Dispose();
}
if (session != null)
{
session.Close();
}
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
Console.ReadKey();
}
}
}
封装
以上就是基本写法,但是由于执行增删改查时频繁的使用ISessionFactory来创建会话,所以封装一个类来创建会话,需要执行这些操作的时候直接引用这个管理类里面的方法就可以了:
1.
首先添加一个类,命名为NHibernateHelper ,添加以下代码:(在这里进行创建会话,不用每次使用时都新开一个会话)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
namespace NHibernateTest
{
public class NHibernateHelper
{
private static ISessionFactory _sessionFactory;
public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var config = new Configuration();
config.Configure();//开始解析文件hibernate.cfg.xml
config.AddAssembly("NHibernateTest");
_sessionFactory = config.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
}
2.
在目录下创建一个叫Manager的文件夹,添加一个接口,命名为IUsermanager ,写入以下代码:
(这里定义了一些增删改查的方法,和通过ID查询用户数据的复杂查询方法,和验证用户名密码是否存在的方法)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernateTest.Model;
namespace NHibernateTest.Manager
{
public interface IUserManager
{
/// <summary>
/// 添加数据
/// </summary>
/// <param name="user">User表中的数据</param>
void Add(User user);
/// <summary>
/// 更新数据
/// </summary>
/// <param name="user">User表中的数据</param>
void Updata(User user);
/// <summary>
/// 删除某条指定数据
/// </summary>
/// <param name="user">User表中的数据</param>
void Delete(User user);
/// <summary>
/// 通过用户ID查询数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
User GetUserById(int id);
/// <summary>
/// 通过用户名查询数据
/// </summary>
/// <param name="username"></param>
/// <returns></returns>
User GetUserByUsername(string username);
/// <summary>
/// 查询表中所有数据
/// </summary>
/// <returns></returns>
ICollection<User> GetAllUsers();
/// <summary>
/// 验证用户名密码是否存在
/// </summary>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
/// <returns></returns>
bool VerifyUser(string username, string password);
}
}
3.
在这个文件夹下,再添加一个叫Usermanager的类,继承自IUsermanager这个接口,写入以下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernateTest.Model;
using NHibernate;
using NHibernate.Criterion;
namespace NHibernateTest.Manager
{
public class UserManager : IUserManager
{
public void Add(User user)
{
//第一种写法:
//ISession session = NHibernateHelper.OpenSession();
//session.Save(user);
//session.Close();
//第二种写法:
//Using语句意思是在大括号里的代码执行完以后释放小括号里面的资源
//使用using,定义范围,在该范围结束时回收资源。功能等同于try{ }Finally{ }。
using (ISession session = NHibernateHelper.OpenSession()) //下面的代码执行完会在这路关闭session
{
using(ITransaction transaction = session.BeginTransaction())
{
session.Save(user);
transaction.Commit();//开启事务,执行完以后才会在using里关闭
}
}
}
public void Delete(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Delete(user);
transaction.Commit();
}
}
}
public void Updata(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Update(user);
transaction.Commit();
}
}
}
public User GetUserById(int id)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
User user = session.Get<User>(id);
transaction.Commit();
return user;//获取到user里的id后返回
}
}
}
public ICollection<User> GetAllUsers()
{
using (ISession session = NHibernateHelper.OpenSession())
{
IList<User> users = session.CreateCriteria(typeof(User)).List<User>();//返回User里的多个值,就不能用UniqueResult了
return users;
}
}
public User GetUserByUsername(string username)
{
using(ISession session = NHibernateHelper.OpenSession())
{
//第一种写法:
//CreateCriteria方法是指定要查询哪个表格,接收类型参数,把user这个类型传给他就可以了
//ICriteria criteria = session.CreateCriteria(typeof(User));
//criteria.Add(Restrictions.Eq("Username", username));//Restrictions.Eq 等于的意思
//User user = criteria.UniqueResult<User>();//UniqueResult 这里只返回一个值
//第一种的简写方式:
User user = session.CreateCriteria(typeof(User)).Add(Restrictions.Eq("Username", username)).UniqueResult<User>();
return user;
}
}
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)) .UniqueResult<User>();
if (user == null)
{
return false;
}
return true;
}
}
}
}
4.
最后在主函数里进行测试这些封装的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NHibernateTest.Model;
using NHibernateTest.Manager;
namespace NHibernateTest
{
class Program
{
static void Main(string[] args)
{
//添加数据
//UserManager userManager = new UserManager();
//User user = new User { Username = "mmmm", Password = "00000" };
//userManager.Add(user);
//更新数据
//UserManager userManager = new UserManager();
//User user = new User { Id=29 , Username="哈哈",Password="0000123" };
//userManager.Updata(user);
//删除数据
//UserManager userManager = new UserManager();
//User user = new User { Id = 29};
//userManager.Delete(user);
//根据用户ID查询数据
//UserManager userManager = new UserManager();
//User user = userManager.GetUserById(11);
//Console.WriteLine(user.Username+" "+user.Password);
//根据用户名查询数据
//UserManager userManager = new UserManager();
//User user = userManager.GetUserByUsername("wer23");
//Console.WriteLine(user.Id + " " + user.Password);
//查询表里的所有数据
//UserManager userManager = new UserManager();
//ICollection<User> users = userManager.GetAllUsers();
//foreach (var item in users)
//{
// Console.WriteLine(item.Id+" "+item.Username+" "+item.Password);
//}
//验证用户名密码是否存在
UserManager userManager = new UserManager();
Console.WriteLine(userManager.VerifyUser("wer","123"));//如果存在返回true,不存在返回fasle
Console.ReadKey();
}
}
}
拓展
关于Restrictions的各种用法:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!