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

news2024/11/26 0:27:33

目录

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】SpringBoot 工程 war包服务部署与调用测试

1.开发环境&#xff1a;IDEA&#xff0c;JDK1.8 2.服务打包类型&#xff1a; war包 3.war包部署环境&#xff1a;Linux系统&#xff0c;tomcat服务器&#xff0c;端口号&#xff1a;8081 4.war包部署位置&#xff1a;tomcat-8081/webapps/temp.war 5.服务名为&#xff1a;t…

Java版本企业电子招投标采购系统源码——功能模块功能描述+数字化采购管理 采购招投标

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…

Postman轻松签名,让SHA256withRSA保驾护航!

postman接口签名教程&#xff1a;https://www.bilibili.com/video/BV1r14y1A7MQ/? 目录&#xff1a;导读 前言 获取pmlib 引入依赖bundle.js&#xff0c;有以下两种方式&#xff1a; 使用Pre-request Script对请求进行加签(具体加签字段请看自己项目) 结语 前言 在接口测…

荔枝派Zero(全志V3S)开启alsa,测试codec

文章目录 前言一、ALSA 简介二、ALSA 框架三、buildroot 配置四、烧录到 SD 卡五、测试1、查看 CODEC 设备2、alsa-utils 使用①、查看设备②、调节音量③、查看控制器④、录音测试⑤、播放测试 前言 默认 dts 中使能了 codec 需要使用的话&#xff0c;在 buildroot 中勾选 a…

2023年五月份图形化四级打卡试题

活动时间 从2023年5月1日至5月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…

开放式耳机有什么好处,盘点几款性能不错的开放式耳机

随着人们对生活质量要求的提高&#xff0c;大家在运动的时候都喜欢戴上耳机&#xff0c;享受运动的乐趣。但是传统耳机戴久了之后就会出现耳朵酸痛的情况&#xff0c;这是因为传统耳机佩戴方式是通过空气振动来传递声音&#xff0c;而人在运动时就会伴随着大量的汗水&#xff0…

基于ResNet-attention的负荷预测

一、attention机制 注意力模型最近几年在深度学习各个领域被广泛使用&#xff0c;无论是图像处理、语音识别还是自然语言处理的各种不同类型的任务中&#xff0c;都很容易遇到注意力模型的身影。从注意力模型的命名方式看&#xff0c;很明显其借鉴了人类的注意力机制。我们来看…

GB/T28181-2022相对2016版“基于TCP协议的视音频媒体传输要求“规范解读和技术实现

规范解读 GB/T28181-2022和GB/T28181-2016规范&#xff0c;有这么一条“更改了附录 D 基于 TCP 协议的视音频媒体传输要求&#xff08;见附录 D&#xff0c;2016 年版的附录 L&#xff09;。”。 本文主要是针对GB/T28181-2022里面提到的“基于 TCP 协议的视音频媒体传输要求…

chmod 命令 (chmod 0660)

chmod的作用: 用于设置文件所有者和文件关联组的命令,就是控制用户的权限命令 注意事项: chown 需要超级用户 root 的权限才能执行此命令。 自己常用chmod 命令是 chmod 777 * 给所有文件权限 chmod 777 文件名 给单独文件权限 这个777 是怎么来的, 或者chmod 0660 这…

Servlet路径问题(“/“到底代表什么)-“web应用程序的根目录“与“web站点的根目录“

JavaWeb——Servlet路径问题("/"到底代表什么) JavaWeb——Servlet路径问题("/"到底代表什么) 在JavaWeb中&#xff0c;使用路径时出现了大量的"/“&#xff0c;而每次使用”“时都感觉其代表的含义是不同的&#xff0c;因此&#xff0c;本篇文章将汇…

分布式ID解决方案对比

在复杂的分布式系统中&#xff0c;往往需要对大量的数据进行唯一标识&#xff0c;比如在对一个订单表进行了分库分表操作&#xff0c;这时候数据库的自增ID显然不能作为某个订单的唯一标识。除此之外还有其他分布式场景对分布式ID的一些要求&#xff1a; 趋势递增&#xff1a; …

(栈和队列) 232. 用栈实现队列 ——【Leetcode每日一题】

❓232. 用栈实现队列 难度&#xff1a;中等 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列…

Jenkins之allure测试报告邮件通知

Jenkins入门教程&#xff1a;Jenkins入门 一般情况下&#xff0c;我们想让Jenkins将构建结果或构建中的代码执行结果&#xff08;比如跑批数据&#xff09;通知我们&#xff0c;这个是构建后的操作。 经常用的是邮件通知 邮件通知基础 Jenkins自带了邮件通知配置&#xff0c…

灌区信息化和灌区自动化监测方案

一、方案背景 以提升粮食综合生产能力和水资源高效利用作为现代化改造的目标&#xff0c;把国家粮食安全和节水放在首位&#xff1b;以完善灌区工程设施体系和管理体系作为现代化改造的基础&#xff0c;以现代信息技术应用、智慧灌区建设作为提高管理能力和服务水平的手段&…

windows 文件夹目录过长超过长度259字符 文件打不开

当路径超过260个字符时&#xff0c;Windows操作系统就无法处理文件或文件夹&#xff0c;并且无法打开或重命名。这是因为Windows系统使用的文件系统&#xff0c;即FAT和NTFS文件系统&#xff0c;都有最大路径限制。NTFS文件系统最大长度限制为32767个字符&#xff0c;但操作系统…

算法训练day4:栈与队列

那么我这里再列出四个关于栈的问题&#xff0c;大家可以思考一下。以下是以C为例&#xff0c;使用其他编程语言的同学也对应思考一下&#xff0c;自己使用的编程语言里栈和队列是什么样的。 C中stack 是容器么&#xff1f;我们使用的stack是属于哪个版本的STL&#xff1f;我们…

FPGA基于XDMA实现PCIE X8采集AD9226数据 提供工程源码和QT上位机程序和技术支持

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PC…

就这些了, 常见 6 款API 文档工具推荐

8年开发经验&#xff0c;想分享一下我接触到这些 API 文档工具&#xff1a; Swagger: Swagger 是一个开源的 API 文档管理工具&#xff0c;可以通过注解自动生成 API 文档&#xff0c;并提供交互式 UI 和 API 调试功能。 Swagger 支持多种语言和格式&#xff0c;包括 Java、Pyt…

Linux没网络的情况下快速安装依赖或软件(挂载本地yum仓库源(Repository))

一、上传iso系统镜像&#xff1a; 上传和系统同一版本、同一位数&#xff08;32bit&#xff1a;i686或i386/64bit:x86_64&#xff09;的系统&#xff0c;不能是Minimal版本&#xff0c;可以是DVD&#xff08;较全&#xff09;或everything&#xff08;最全&#xff09;。 注&am…

Android移除sdk中的权限

有些第三方sdk中的敏感权限会给我们上架带来困扰&#xff0c;比如&#xff1a;QUERY_ALL_PACKAGES权限会导致上架Google play被拒。 案例&#xff1a;<uses-permission android:name"android.permission.QUERY_ALL_PACKAGES" /> 在app下的Manifest中并没有添加…