基于PHOTON(光子)的服务器端开发I

NHibernate与数据库(MySQL)连接

花了半年多时间终于完成了整个服务器端的开发(虽然好像有一半时间都在摸鱼orz),心情万分激动,紧接着开发客户端,完成游戏与服务器连接,上号进行测试,结果————他喵的本地测试延迟已经高到爆表(还是经过优化的),这还开发个锤子的联机游戏(躺
话是这么说,但做项目到底还是为了学习,所以还是应该沉下心来做一做开发总结,这么长时间的摸鱼过程还是学到了不少东西的,然后游戏开发的话可能得另辟蹊径,以后再找其他解决方案了

Link Start!

1.NHibernate组件简介

(1)之前学数据库的时候我就在想,到时候开发服务器的时候到底是自己手动写链接呢,还是借用前人造好的轮子呢,其实对于这一点,对于我们学习者而言,只要掌握了基础知识和原理,前人造好的轮子大部分实际上是对这些基础内容的整合和优化,可以节省我们的时间去进一步学习其他内容,所以无脑造轮子的行为我认为是不可取的,毕竟还是以学习为重点的嘛,因为数据库那一块内容我已经大概学习到了,所以这里我是使用到NHibernate这个组件来连接数据库,加快开发进度
(2)NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去————度娘

2.引用

(1)在NHibernate官网下载后将压缩包中的NHibernate.dll添加引用(如果使用VS的话NHibernate也支持直接从NuGet直接安装)

NHibernate官网

(2)这里用到的数据库为MySQL,所以同理,引入MySql.Data.dll(用NuGet安装可能更方便一些,也方便后期版本更新)

3.NHibernate配置

(1)创建xml文件,文件名固定,为 hibernate.cfg.xml
(2)配置信息
<?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=shinemirai_1;User ID=root;Password=xxxxxx;</property><!--数据库选择以及ID密码填写-->
    <property name="show_sql">true</property><!--是否输出数据库操作语句(建议输出)-->
</session-factory>
</hibernate-configuration>

4.数据库表映射

(1)创建Model文件夹用于存放映射模型类
(2)users.cs
namespace NM_connect.Model
{
    public class users
    {
        public virtual int id { get; set; }
        public virtual string user_name { get; set; }
        public virtual string user_password { get; set; }
    }
}
//对应数据库的列表,我的库里有id user_name user_password三个字段
(3)创建Mappings文件夹用于存放映射文件
(4)创建xml文件,文件名格式为 类名.hbm.xml (我上边创建的类名为users,因此我的文件命名为 users.hbm.xml)
(5)配置信息
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                assembly="MyGameServer" 
                namespace="MyGameServer.Model">
<!--assembly程序集名称,namespace本配置文件对应的文件在那个路径下-->

<class name="users" table="users"><!--name类名 table表名-->
    <id name="id" column="id" type="Int32">
    <generator class="native"></generator>
    </id>
    <property name="user_name" column="user_name" type="String"></property>
    <property name="user_password" column="user_password" type="String"></property>
</class>
<!--注意要将数据库表的主键与其他字段的name(对应类) column(对应数据库) type对应填写正确-->
</hibernate-mapping>

5.解析数据库链接配置文件

(1)引入命名空间
using NHibernate;
using NHibernate.Cfg;
(2)上代码
var configuration = new Configuration();
configuration.Configure();//解析Hibernate.cfg.xml
configuration.AddAssembly("NM_connect");//解析 users.hbm.xml

6.创建会话session进行添加操作

(1)上代码
ISessionFactory sessionFactory = null;
ISession session = null;
try
{
    sessionFactory = configuration.BuildSessionFactory();//构建sessionFactory,创建session对象,充当数据存储的代理
    session = sessionFactory.OpenSession();//打开一个与数据库的会话

    users user = new users() { user_name = "siri", user_password = "hi,siri" };//创建一条信息
    session.Save(user);//通过session 保存到数据库
}
catch (Exception e)
{
    Console.WriteLine(e);
}
finally
{
    if (session != null)
    {
         session.Close();
    }
    if(sessionFactory != null)//不为空时进行关闭操作,否则可能会有问题出现
    {
        sessionFactory.Close();//关闭session  
    }
}

7.利用NH进行事务操作

(1)事务的作用在于保证数据的完整性和统一性
(2)上代码
ISessionFactory sessionFactory = null;
ISession session = null;
ITransaction transaction = null;
try
{
    sessionFactory = configuration.BuildSessionFactory();//构建sessionFactory,创建session对象,充当数据存储的代理
    session = sessionFactory.OpenSession();//打开一个与数据库的会话

    transaction =  session.BeginTransaction();//创建事务
    users user1 = new users() { user_name = "test1", user_password = "test111" };
    users user2 = new users() { user_name = "test2", user_password = "test222" };
    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();//关闭session  
    }
    //注意关闭顺序
}

8.创建NHHelper管理会话工厂

(1)NHibernateHelper.cs(简化session创建)
(2)上代码
namespace MyGameServer
{
    class NHibernateHelper
    {
        private static ISessionFactory _sessionFactory;
        private static ISessionFactory SessionFactory
        {
            get
            {
                if(_sessionFactory == null)
                {
                    var configuration = new Configuration();
                    configuration.Configure();
                    configuration.AddAssembly("MyGameServer");

                    _sessionFactory = configuration.BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }
        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }
}

9.创建管理类,处理CRUD操作

(1)新建文件夹Manager
(2)创建接口文件 IUserManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyGameServer.Model;

namespace MyGameServer.Manager
{
    interface IUserManager
    {
        void Add(users user);//添加
        void Update(users user);//更新
        void Remove(users user);//移除
        users GetById(int id);//通过ID查找
        users GetByUsername(string user_name);//通过用户名查找
        ICollection<users> GetAllUsers();//获取所有用户
        bool VerifyUser(string user_name, string user_password);//密码用户名匹配
    }
}
(3)创建 UserManager.cs 实现接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyGameServer.Model;
using NHibernate;
using NHibernate.Criterion;


namespace MyGameServer.Manager
{
    class UserManager : IUserManager
    {
        public void Add(Model.users user)
        {
            /*
            ISession session = NHibernateHelper.OpenSession();
            session.Save(user);
            session.Close();
            */

            using(ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(user);
                    transaction.Commit();
                }
            }//该方法使用using不需要手动释放或关闭 上边的方法需要手动释放
        }

        public ICollection<Model.users> GetAllUsers()
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                IList<users> user = session.CreateCriteria(typeof(users)).List<users>();
                return user;
            }
        }

        public users GetById(int id)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    users user = session.Get<users>(id);
                    transaction.Commit();
                    return user;
                }
            }
        }

        public users GetByUsername(string user_name)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                /*
                ICriteria criteria = session.CreateCriteria(typeof(users));
                criteria.Add(Restrictions.Eq("Name", user_name));
                users user =criteria.UniqueResult<users>();
                return user;
                */
                users user = session.CreateCriteria(typeof(users)).Add(Restrictions.Eq("user_name", user_name)).UniqueResult<users>();
                return user;//简写方法
            }
        }

        public void Remove(Model.users user)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(user);
                    transaction.Commit();
                }
            }
        }

        public void Update(Model.users user)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(user);
                    transaction.Commit();
                }
            }
        }

        public bool VerifyUser(string user_name, string user_password)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                users user = session
                    .CreateCriteria(typeof(users))
                    .Add(Restrictions.Eq("user_name", user_name))
                    .Add(Restrictions.Eq("user_password",user_password))
                    .UniqueResult<users>();
                if (user == null) return false;
                return true;
            }
        }
    }
}

10.利用NH实现上述功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NM_connect.Model;
using NM_connect.Manager;

namespace NM_connect
{
    class Program
    {
        static void Main(string[] args)
        {
            users user = new users() { user_name = "test3",user_password="test333" };
            IUserManager userManager = new UserManager();
            userManager.Add(user); 
            //数据增添

            users user = new users() { id = 8,user_name = "siri", user_password = "hi,siri" };
            IUserManager userManager = new UserManager();
            userManager.Update(user);
            //数据更新
            
            IUserManager userManager = new UserManager();
            users user = userManager.GetById(2);
            Console.WriteLine(user.user_name);
            Console.WriteLine(user.user_password);
            //获取ID并查询相关信息
            
            IUserManager userManager = new UserManager();
            users user = userManager.GetByUsername("test1");
            Console.WriteLine(user.user_name);
            Console.WriteLine(user.user_password);
            //通过用户名查询信息
            
            IUserManager userManager = new UserManager();
            ICollection<users> user = userManager.GetAllUsers();
            foreach(users u in user)    
            {
                Console.WriteLine(u.user_name + " " + u.user_password);
            }
            //输出所有用户信息

            IUserManager userManager = new UserManager();
            Console.WriteLine(userManager.VerifyUser("siri", "hi,siri"));
            Console.WriteLine(userManager.VerifyUser("test1", "test111"));
            //用户名密码匹配
            Console.ReadKey();
        }
    }
}

11.通过NH实现表的多重映射

这一部分结合后续的实例再来更新

完结撒花~

C91新刊 Pid:60572860


基于PHOTON(光子)的服务器端开发I
https://baifabaiquan.cn/2020/07/30/基于Photon的服务器端开发1/
作者
白发败犬
发布于
2020年7月30日
许可协议