基于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直接安装)
(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实现表的多重映射
这一部分结合后续的实例再来更新
完结撒花~
基于PHOTON(光子)的服务器端开发I
https://baifabaiquan.cn/2020/07/30/基于Photon的服务器端开发1/