6-10 Creating Manager Class And NHibernate CRUD Manipulation
本章要來撰寫NHibernate完整的CRUD操作,意即Create, Read, Update, Delete。我額外撰寫了一個Manager類,用來處理所有跟Users相關的資料庫操作,以及一個Helper類用來處理資料庫連接的操作。比起前一個章節把所有的程式碼都大雜燴放在一起清楚多了,設計上應盡量符合單一職責原則。
首先,Helper類內部放的是產生SessionFactory的方法,由於資料庫連線是一件容易拖累程式碼速度的環節,一般來說建立連線後會使用Connection Pool的方式把連線保留下來,並在以後遇到資料庫操作時合理分配事先建立好的Connection物件。NHibernate的ISessionFactory便已經實作了Connection Pool的功能,每次取Session時都是從Pool中取得連線。
接著是撰寫UserManager.cs,我撰寫了Add、Delete、Update、GetById、GetByAccount、GetAllUsers、VerifyUser等方法。
以下提供原始碼,由於我已經撰寫註解了,就不再贅述:
NHibernateHelper.cs:
UserManager.cs:
那我們要如何使用UserManager呢?如Create的時候,我們新增一個Users類別,填入參數,用manager.Add方法放進去即可。
Update也是,由於Id是主鍵,所以NHibernate會以Id當作Where條件查找,然後更新該筆資料。大家可能會想問如果我的Update想要同時修改多筆呢?第一種,ORM就是要以OOP的角度操作資料庫,只要類別的資料有變動都會更新進去,所以大家可以採用OOP的方式(For, While, if else等等)修改。第二種,可以使用HQL(Hibernate Query Language),或者也能使用自訂的SQL,這部分以後的章節會再跟大家介紹。
Delete的時候只要指名Id即可。
好的,以下提供NoliahFantasyServer.cs的原始碼:
程式碼修改好後,執行看看吧,從Log中可以看見確實有查詢到資料。
然後實際到資料庫中搜尋,發現也有確實Update跟建立資料。
首先,Helper類內部放的是產生SessionFactory的方法,由於資料庫連線是一件容易拖累程式碼速度的環節,一般來說建立連線後會使用Connection Pool的方式把連線保留下來,並在以後遇到資料庫操作時合理分配事先建立好的Connection物件。NHibernate的ISessionFactory便已經實作了Connection Pool的功能,每次取Session時都是從Pool中取得連線。
接著是撰寫UserManager.cs,我撰寫了Add、Delete、Update、GetById、GetByAccount、GetAllUsers、VerifyUser等方法。
以下提供原始碼,由於我已經撰寫註解了,就不再贅述:
NHibernateHelper.cs:
using System; using NHibernate; using NHibernate.Cfg; namespace NoliahFantasyServer { public class NHibernateHelper { private static ISessionFactory sessionFactory; private static void InitFactory(){ if (sessionFactory == null) { Configuration conf = new Configuration(); // 解析hibernate.cfg.xml conf.Configure(); // 輸入Application的名稱,並自動解析Mappings文件 conf.AddAssembly(typeof(NoliahFantasyServer).Assembly); sessionFactory = conf.BuildSessionFactory(); } } public static ISession OpenSession(){ InitFactory(); return sessionFactory.OpenSession(); } } }
UserManager.cs:
using System; using System.Collections.Generic; using NoliahFantasyServer.Model; using NHibernate; using NHibernate.Criterion; namespace NoliahFantasyServer.Manager { public class UserManager { public void Add(Users users) { using(ISession session = NHibernateHelper.OpenSession()){ using(ITransaction transaction = session.BeginTransaction()){ session.Save(users); transaction.Commit(); } } } public void Delete(Users users) { using (ISession session = NHibernateHelper.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.Delete(users); transaction.Commit(); } } } public void Update(Users users) { using (ISession session = NHibernateHelper.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.Update(users); transaction.Commit(); } } } public Users GetById(int id) { using (ISession session = NHibernateHelper.OpenSession()) { Users users = session.Get(id); return users; } } public Users GetByAccount(string account) { using (ISession session = NHibernateHelper.OpenSession()) { // 使用Criteria建立查詢 // Add Restrictions代表增加查詢條件 // UniqueResult取得查詢結果 Users users = session.CreateCriteria(typeof(Users)) .Add(Restrictions.Eq("Account", account)) .UniqueResult (); return users; } } public ICollection GetAllUsers() { using (ISession session = NHibernateHelper.OpenSession()) { // 使用Criteria建立查詢,使用List取得多個查詢結果 // 由於此功能要取得所有用戶,所以不需要使用查詢條件 IList users = session.CreateCriteria(typeof(Users)) .List (); return users; } } public bool VerifyUser(string account, string pwd){ using (ISession session = NHibernateHelper.OpenSession()) { // 查詢帳號跟密碼是否正確 Users users = session.CreateCriteria(typeof(Users)) .Add(Restrictions.Eq("Account", account)) .Add(Restrictions.Eq("Pwd", pwd)) .UniqueResult (); if (users == null){ return false; }else{ return true; } } } } }
那我們要如何使用UserManager呢?如Create的時候,我們新增一個Users類別,填入參數,用manager.Add方法放進去即可。
Update也是,由於Id是主鍵,所以NHibernate會以Id當作Where條件查找,然後更新該筆資料。大家可能會想問如果我的Update想要同時修改多筆呢?第一種,ORM就是要以OOP的角度操作資料庫,只要類別的資料有變動都會更新進去,所以大家可以採用OOP的方式(For, While, if else等等)修改。第二種,可以使用HQL(Hibernate Query Language),或者也能使用自訂的SQL,這部分以後的章節會再跟大家介紹。
Delete的時候只要指名Id即可。
好的,以下提供NoliahFantasyServer.cs的原始碼:
using System; using System.IO; using System.Collections.Generic; using Photon.SocketServer; using ExitGames.Logging; using ExitGames.Logging.Log4Net; using log4net.Config; using NHibernate; using NHibernate.Cfg; using NoliahFantasyServer.Model; using NoliahFantasyServer.Manager; namespace NoliahFantasyServer { public class NoliahFantasyServer : ApplicationBase { public static readonly ILogger logger = LogManager.GetCurrentClassLogger(); public NoliahFantasyServer() { } // 當Client端發出Request的時候 protected override PeerBase CreatePeer(InitRequest initRequest) { return new MyClientPeer(initRequest); } // Server端啟動的時候初始化 protected override void Setup() { LoggerInit(); Create(); Read(); Update(); Delete(); GetUserByAccount(); GetAllUsers(); VerifyUser(); } // Server端關閉的時候 protected override void TearDown() { } void LoggerInit() { // 日誌初始化 log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "bin_Win64", "log"); FileInfo loggerConfig = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config")); if (loggerConfig.Exists) { // 設置使用log4net的Log功能 LogManager.SetLoggerFactory(ExitGames.Logging.Log4Net.Log4NetLoggerFactory.Instance); // 讓log4net讀取config XmlConfigurator.ConfigureAndWatch(loggerConfig); } logger.Info("Setup Log4Net Compeleted!"); } void Create(){ Users users1 = new Users() { Account = "abcd12", Pwd = "dsa" }; UserManager manager = new UserManager(); manager.Add(users1); } void Read(){ UserManager manager = new UserManager(); Users users = manager.GetById(15); logger.Info("Get Users By ID(15):" + users.Account); logger.Info("Get Users By ID(15):" + users.Pwd); logger.Info("Get Users By ID(15):" + users.Registerdate); } void Update(){ // 更新時以Id當Where條件,其他值為更新值 Users users = new Users() { Id= 11, Account = "3215543", Pwd = "nnnnnnnn", Registerdate = DateTime.Now }; UserManager manager = new UserManager(); manager.Update(users); } void Delete(){ // 刪除時指定Id,代表以Id當Where條件 Users users = new Users() { Id = 12 }; UserManager manager = new UserManager(); manager.Delete(users); } void GetUserByAccount(){ UserManager manager = new UserManager(); // 依指定帳號讀取帳號資訊 Users users = manager.GetByAccount("3215543"); logger.Info("Get Users By Account(3215543):" + users.Account); logger.Info("Get Users By Account(3215543):" + users.Pwd); logger.Info("Get Users By Account(3215543):" + users.Registerdate); } void GetAllUsers(){ UserManager manager = new UserManager(); ICollectionusers = manager.GetAllUsers(); foreach(Users user in users){ logger.Info("Get All User:" + user.Account + ", " + user.Pwd + ", " + user.Registerdate); } } void VerifyUser(){ UserManager manager = new UserManager(); bool hasUser = manager.VerifyUser("3215543", "nnnnnnnn"); logger.Info("Verify User(3215543,nnnnnnnn):" + hasUser); } } }
程式碼修改好後,執行看看吧,從Log中可以看見確實有查詢到資料。
然後實際到資料庫中搜尋,發現也有確實Update跟建立資料。
留言
張貼留言