目录
- 1 MySQL封装
- 2 用户注册、登录方法封装
- 3 Unity交互
接着 上篇文章的注册登录系统,这篇文章将MySQL相关操作封装,在Unity交互脚本中直接调用封装的方法。
1 MySQL封装
编写一个DBConnector脚本,封装MySQL中常用的操作,如连接数据库、关闭数据库、查询数据库、除查询外的插入、更新、删除等操作。
using System;
using System.Data;
using MySql.Data.MySqlClient;
namespace Utils
{
public class DBConnector
{
private string connectionString; // 存储 MySQL 连接字符串
private MySqlConnection connection; // 存储 MySQL 连接实例
// 构造函数,接收 MySQL 连接参数
public DBConnector(string server, string database, string uid, string password)
{
// 创建 MySQL 连接字符串
connectionString = $"Server={server};Database={database};Uid={uid};Pwd={password};";
}
// 打开 MySQL 连接
public bool OpenConnection()
{
try
{
// 创建 MySQL 连接实例
connection = new MySqlConnection(connectionString);
// 打开 MySQL 连接
connection.Open();
return true;
}
catch (MySqlException ex)
{
// 输出连接错误信息
Console.WriteLine(ex.Message);
return false;
}
}
// 关闭 MySQL 连接
public bool CloseConnection()
{
// 判断连接是否为空
if (connection == null)
{
return false;
}
try
{
// 关闭 MySQL 连接
connection.Close();
return true;
}
catch (MySqlException ex)
{
// 输出错误信息
Console.WriteLine(ex.Message);
return false;
}
}
/// <summary>
/// 向指定的 MySQL 数据库发送 SQL 语句并返回结果
/// </summary>
/// <param name="query">接受一个字符串作为参数表示查询</param>
/// <returns></returns>
public DataTable SelectQuery(string query)
{
// 创建 empty DataTable,存储返回的结果
var dataTable = new DataTable();
// 创建一个命令对象,以便在数据库上执行查询
var command = new MySqlCommand(query, connection);
// 执行查询并返回结果
var reader = command.ExecuteReader();
// 将查询结果加载到 DataTable 中
dataTable.Load(reader);
// 关闭数据读取器对象
reader.Close();
// 返回查询结果
return dataTable;
}
/// <summary>
/// 执行非查询语句(如 Insert, Update, Delete)
/// </summary>
/// <param name="query">非查询语句</param>
public void ExecuteNonQuery(string query)
{
// 创建命令对象
var command = new MySqlCommand(query, connection);
// 执行非查询语句
command.ExecuteNonQuery();
}
}
}
2 用户注册、登录方法封装
编写一个User脚本用于封装用户注册、登录方法,供Unity交互脚本直接调用。
using System;
using Utils;
public class User
{
private DBConnector dbConnector; // 数据库连接器
// 构造函数,传入用于连接数据库的连接器
public User(DBConnector dbConn)
{
dbConnector = dbConn; // 保存连接器对象
}
// 用户注册
public int Register(string username, string password)
{
// 查询用户名的数量
var query1 = $"SELECT COUNT(*) FROM usersinfo WHERE username = '{username}'";
// 插入一条新用户记录
var query2 = $"INSERT INTO usersinfo (username, password) VALUES ('{username}', '{password}')";
// 尝试与数据库建立连接
if (dbConnector.OpenConnection() == true)
{
try
{
// 执行查询用户名数量的语句
var dataTable = dbConnector.SelectQuery(query1);
// 从查询结果中获取数量
int count = int.Parse(dataTable.Rows[0][0].ToString());
if (count > 0) // 如果已存在同名用户
{
dbConnector.CloseConnection(); // 关闭连接
return 2; // 用户名已存在
}
dbConnector.ExecuteNonQuery(query2); // 执行插入语句插入新用户记录
dbConnector.CloseConnection(); // 关闭连接
return 1; // 注册成功
}
catch (Exception e)
{
Console.WriteLine(e.Message);
dbConnector.CloseConnection();
return 4; //插入数据失败
}
}
else
{
return 3; //连接错误
}
}
// 用户登录
public int Login(string username, string password)
{
// 查询指定用户名的记录
var query = $"SELECT * FROM usersinfo WHERE username = '{username}' LIMIT 1";
// 尝试与数据库建立连接
if (dbConnector.OpenConnection() == true)
{
// 执行查询指定用户名记录的语句
var dataTable = dbConnector.SelectQuery(query);
// 查询用户输入的用户名是否存在于数据库中
if (dataTable.Rows.Count == 1)
{
// 获取查询结果中的用户密码
string storedPassword = dataTable.Rows[0]["password"].ToString();
// 如果密码与输入密码匹配
if (storedPassword == password)
{
dbConnector.CloseConnection(); // 关闭连接
return 1; // 登录成功
}
else
{
dbConnector.CloseConnection(); // 关闭连接
return 2; // 密码错误
}
}
else
{
dbConnector.CloseConnection(); // 关闭连接
return 3; // 用户名不存在
}
}
else
{
return 4; // 连接错误
}
}
}
其中,由于注册和登录时有各种不一样的情况,这里使用枚举将这些情况列出:
namespace Static
{
public class StaticData
{
public enum RegisterCode
{
RegisterSuccess = 1, // 注册成功
UsernameDoesExist = 2, // 用户名已存在
ConnectionError = 3, // 连接错误
InsertDataError = 4, // 插入数据失败
};
public enum LoginCode
{
LoginSuccess = 1, // 登录成功
IncorrectPassword = 2, // 密码不正确
UsernameDoesNotExist = 3, // 用户名不存在
ConnectionError = 4, //连接错误
};
}
}
3 Unity交互
在与Unity交互时,UI界面沿用之前的不用做更改。
这里编写一个UsersManager脚本继承于MonoBehaviour,用于管理用户的注册登录。
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using Utils;
public class UsersManager : MonoBehaviour
{
// 注册UI和登录UI
public GameObject RegisterUI;
public GameObject LoginUI;
// 用户名输入框和密码输入框
public InputField usernameInputField;
public InputField passwordInputfield;
// 注册消息和登录消息
public Text registerMessage;
public Text loginMessage;
// DBConnector类实例化
public DBConnector connector = new DBConnector("localhost","unitygame","root","123456");
// User类实例化
public User user;
void Start()
{
// 初始化UI状态
LoginUI.SetActive(true);
RegisterUI.SetActive(false);
//连接数据库
user = new User(connector);
}
// 加密密码
private static string HashPassword(string password)
{
SHA256Managed crypt = new SHA256Managed();
StringBuilder hash = new StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(password));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
// 注册逻辑
public void OnRegister()
{
// 从输入框获取用户名和密码
string username = usernameInputField.text;
//使用哈希进行加密
string password = HashPassword(passwordInputfield.text);
if (username == "" || password == "")
{
registerMessage.text = "账号或密码不能为空";
}
else
{
int code = user.Register(username, password);
if (code == 1)
{
Debug.Log("注册成功");
registerMessage.text = "注册成功";
}
else if(code == 2)
{
Debug.Log("用户名已存在,请选择不同的用户名!");
registerMessage.text = "用户名已存在,请选择不同的用户名!";
}
else
{
Debug.Log("注册失败");
registerMessage.text = "注册失败";
}
}
//清空输入框
usernameInputField.text = "";
passwordInputfield.text = "";
}
// 登录逻辑
public void OnLogin()
{
// 从输入框获取用户名和密码
string username = usernameInputField.text;
//使用哈希进行加密
string password = HashPassword(passwordInputfield.text);
if (username == "" || password == "")
{
loginMessage.text = "账号或密码不能为空";
}
else
{
int code = user.Login(username, password);
if (code == 1)
{
Debug.Log("登录成功");
loginMessage.text = "登录成功";
}
else if(code == 2)
{
Debug.Log("登录失败:密码错误");
loginMessage.text = "登录失败:密码错误";
}
else if(code == 3)
{
Debug.Log("登录失败:用户名不存在");
loginMessage.text = "登录失败:用户名不存在";
}
else
{
Debug.Log("登录失败");
loginMessage.text = "登录失败";
}
}
//清空输入框
usernameInputField.text = "";
passwordInputfield.text = "";
}
}
在Unity中新建一个空物体UsersManager,并将UsersManager脚本挂载在该物体上,将对应的变量拖拽即可:
删除或隐藏之前的DataManager物体,并将注册和登录按钮上的事件绑定修改为UserManager中对应的注册和登录方法即可。
接下来,就可以测试运行了,结果与之前是一样的。
封装的写法让整个程序的逻辑结构更加清晰。