學習資料
- http://www.sikiedu.com/course/51/task/891/show
- https://www.codeproject.com/Articles/26123/NHibernate-and-MySQL-A-simple-example
Visual Studio新建一個C#控制台程序,設為啟動項,在項目屬性中設置目標框架為.NET Framework4.5。
添加兩個DLL引用:MySQL.Data.dll和NHibernate.dll。后者在NHibernate官網中下載或者直接從Nuget安裝。
新建一個文件hibernate.cfg.xml。該配置文件的內容復制於NHibernate文檔(搜Configure NHibernate)。因為文檔中連接的是SqlServer,而我們要用的是MySQL,所以要做如下修改。配置文檔的寫法參考NHibernate連接MySQL案例。
<?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=mygamedb;User ID=root;Password=root</property> <!-- 端口號缺省值為3306 --> <property name="show_sql">true</property> <!-- 是否打印執行的SQL語句 --> <!-- 坑點:如果當前解決方案下有多個項目,一定要指定程序集! --> <mapping assembly="NHibernateConnectMySQL"/> </session-factory> </hibernate-configuration>
已知MySQL數據庫中的表和內容如下圖:
項目根目錄新建Model文件夾,在該文件夾下新建User.cs類。內容如下:
namespace NHibernateConnectMySQL.Model { public class User { public virtual int Id { get; set; } public virtual string UserName { get; set; } public virtual string UserPwd { get; set; } public virtual DateTime UserRegisterTime { get; set; } } }
項目根目錄新建Mappings文件夾,在該文件夾下新建User.hbm.xml文件(命名習慣上與要關聯的User.cs類命名一致)。寫法同樣參考官方文檔(搜The complete mapping file)。
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="FirstSolution" namespace="NHibernateConnectMySQL.Model"> <!-- 項目所在的程序集;該配置文件所關聯的User.cs類所在的名稱空間 --> <class name="User" table="user"> <!-- 指定名稱空間下的User類,要與數據庫中的user表映射 --> <id name="Id" column="user_id" type="Int32"> <!-- 配置主鍵。類中的Id屬性映射表中的user_id列 --> <generator class="native" /> <!-- 主鍵自增。使用數據庫自帶的生成器 --> </id> <property name="UserName" column="user_name" type="String"/> <!-- 只有主鍵用id,其他字段都用property --> <property name="UserPwd" column="user_pwd" type="String"/> <!-- 是NHibernate定義的類型,查看文檔http://nhibernate.info/doc/nhibernate-reference/index.html搜索type --> <property name="UserRegisterTime" column="user_register_time" type="Date"/> </class> </hibernate-mapping>
在【屬性】窗體修改hibernate.cfg.xml的【復制到輸出路徑】為【始終復制】。修改User.hbm.xml的【生成操作】為【嵌入的資源】。然后生成項目。可以在Debug目錄下看到hibernate.cfg.xml文件直接被復制過來了,而User.hbm.xml的內容被集成到了exe文件中。
寫代碼完成NHibernate初始化操作,就是解析數據庫鏈接配置文件(即hibernate.cfg.xml)和各種表映射文件(User.hbm.xml等等)。通常在項目的主函數中執行。
測試插入一條紀錄,代碼如下:
using NHibernate; using NHibernate.Cfg; using NHibernateConnectMySQL.Model; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NHibernateConnectMySQL { class Program { static void Main(string[] args) { // ---- NHibernate初始化 ---- var conf = new Configuration(); // 解析hibernate.cfg.xml conf.Configure(); // 參數為文件,缺省值就是hibernate.cfg.xml // 解析表映射文件(User.hbm.xml等),表映射文件已被集成到程序集中(嵌入的資源) //conf.AddAssembly("NHibernateConnectMySQL"); // 參數為文件所在的程序集,已在hibernate.cfg.xml中聲明 // ---- 完成初始化 ---- // ---- 連接數據庫 ---- ISessionFactory sessionFactory = null; ISession session = null; ITransaction transaction = null; try { // 連接數據庫的會話工廠 sessionFactory = conf.BuildSessionFactory(); // 打開一個跟數據庫的會話 session = sessionFactory.OpenSession(); // 開啟事務 transaction = session.BeginTransaction(); User user1 = new User() { UserName = "jjssag2", UserPwd = "4606519" }; User user2 = new User() { UserName = "jjssag3", UserPwd = "46064519" }; session.Save(user1); session.Save(user2); // 提交事務 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(); } } }
完善增刪改查
項目目錄如下:
由於每次操作都要開啟一個會話Session,都要使用事務Transaction,所以考慮將重復的內容進行封裝,寫一個NHibernateHelper.cs工具類。
using NHibernate.Cfg; using NHibernate; namespace NHibernateConnectMySQL { class NHibernateHelper { private static ISessionFactory _sessionFactory; public static ISessionFactory SessionFactory { get { if (_sessionFactory == null) { var conf = new Configuration(); conf.Configure(); conf.AddAssembly("NHibernateConnectMySQL"); _sessionFactory = conf.BuildSessionFactory(); } return _sessionFactory; } } public static ISession OpenSession() { return SessionFactory.OpenSession(); } } }
Manager文件夾下是各個類的增刪改查操作實現。
using System.Collections.Generic; using NHibernateConnectMySQL.Model; using NHibernate; using NHibernate.Criterion; namespace NHibernateConnectMySQL.Manager { class UserManager : IUserManager { // 插入一條紀錄 public void Add(User user) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.Save(user); transaction.Commit(); } } } // 刪除一條紀錄 public void Delete(User user) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.Delete(user); transaction.Commit(); } } } // 更新一條紀錄 public void Update(User user) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.Update(user); transaction.Commit(); } } } // 查詢一條紀錄 public User GetUserByID(int id) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { // 查詢不會對數據進行操作,可以不用事務 User user = session.Get<User>(id); return user; } } // 查詢一條紀錄 public User GetUserByUserName(string userName) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { //ICriteria criteria = session.CreateCriteria(typeof(User)); // 添加查詢條件為傳入的參數等於實體類中的屬性 //criteria.Add(Restrictions.Eq("UserName", userName)); //User user = criteria.UniqueResult<User>(); User user = session .CreateCriteria(typeof(User)) .Add(Restrictions.Eq("UserName", userName)) .UniqueResult<User>(); return user; } } // 查詢多條紀錄 public ICollection<User> GetAllUsers() { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { IList<User> list = session.CreateCriteria(typeof(User)).List<User>(); return list; } } // 校驗登錄 public bool VerifyUser(string userName, string password) { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { User user = session .CreateCriteria(typeof(User)) .Add(Restrictions.Eq("UserName", userName)) .Add(Restrictions.Eq("UserPwd", password)) .UniqueResult<User>(); if (user == null) return false; else return true; } } } }
在主函數中調用增刪改查方法。
using NHibernateConnectMySQL.Manager; using System; namespace NHibernateConnectMySQL { class Program { static void Main(string[] args) { UserManager userManager = new UserManager(); // 插入數據 //User user = new User() { UserName = "3643uhyrjut", UserPwd = "123453143" }; //UserManager userManager = new UserManager(); //userManager.Add(user); // 查詢單條紀錄 //User user = userManager.GetUserByUserName("agr43"); //Console.WriteLine(user.UserPwd); // 查詢多條紀錄 //ICollection<User> list = userManager.GetAllUsers(); //foreach (User item in list) //{ // Console.WriteLine(item.UserPwd); //} // 驗證登錄 //Console.WriteLine(userManager.VerifyUser("jjssag1", "4606519")); Console.ReadKey(); } } }
坑點
- 如果當前解決方案下有多個項目,在總的配置文件中(hibernate.cfg.xml)一定要指定是哪個程序集,或者代碼中用conf.AddAssembly()指定!否則報錯如下圖: