【Unity+MySQL】实现注册登录系统(封装版)


接着 上篇文章的注册登录系统,这篇文章将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中对应的注册和登录方法即可。
在这里插入图片描述
在这里插入图片描述
接下来,就可以测试运行了,结果与之前是一样的。

封装的写法让整个程序的逻辑结构更加清晰。

猜你喜欢

转载自blog.csdn.net/qq_41084756/article/details/130363620