Related Posts Plugin for WordPress, Blogger...

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:

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();
            ICollection users = 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跟建立資料。

留言