尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Unity连接MySQL显示表格:Simple TableUI实现与避坑指南
简介面向 Unity 开发者的 MySQL 数据展示整合包适用于在 Unity 2020.3.45f1 客户端直连数据库、读取表格数据并借助 Simple TableUI 完成界面渲染的技术场景尤其适合做后台管理面板、数据监控看板或本地工具类应用的中级开发者。资源围绕“连接—读取—显示—排错”的主线展开既包含 MySQL 连接配置、查询语句调用、数据模型转换等基础环节也覆盖 Simple TableUI 在使用中常见的初始化异常、字段匹配错误、数据源刷新不及时等问题并给出针对性的排错方向可显著减少自行摸索过程中的编译障碍。配套博文演示了整个操作链路便于边看边对照实践。压缩包以 zip 格式打包整体约 24.36MB内容集中、体积适中下载后即可按说明展开学习。目前已有 742 人浏览学习适合需要快速把 MySQL 数据变成 Unity 内可视化表格的读者参考复用对初学 Unity 数据可视化或想改进现有列表展示效果的人尤为实用。1. Unity 连接 MySql 显示表格Simple TableUI从数据库到界面的最后一公里做工具、做编辑器扩展或者做轻量后台的时候最常卡住的一个需求就是Unity 连接 MySql 显示表格Simple TableUI。游戏客户端不想开浏览器也不想切到 Navicat 里看数据就希望游戏里点一下按钮数据库表立刻以表格形式呈现在屏幕上。这个方案的核心是三层MySql 连接层、数据查询层、uGUI 表格渲染层。它适合要快速交付内部工具的人也适合刚接触数据库集成的 Unity 开发者——不需要上重型网络框架也不用引入大而全的 UI 插件一两个脚本就能跑通。把数据从数据库里拽出来往后端页面放不难难的是用 Unity 的 uGUI 把字段名、行、列、滚动条组织得干净利落。下面按我实际落地时走的路线一步步拆开讲。2. 选型与准备驱动库、表格组件与工程结构动手前先解决两个选型问题用哪个 MySql 驱动库表格 UI 怎么搭。选错后面全是坑这两个点值得花十分钟确认。2.1 驱动库选型MySql.Data 的版本陷阱与备选Unity 里连 MySql 的常见做法是引用 MySql.Data.dll这是 Oracle 官方 .NET 驱动。但它有个明显痛点不同 Unity 版本对 .NET 版本的支持不同Unity 2021 以下默认走 .NET Standard 2.0 / Mono而 MySql.Data 8.0.x 用的依赖项较多扔进 Plugins 文件夹后经常在运行时报找不到文件或安全策略异常。我一般先看 Unity 版本再定驱动。Unity 2020 及之前的项目用 MySql.Data 8.0.32 左右的版本更多Unity 2021 以上可以尝试最新版但一旦报了System.Security.SecurityException或者FileNotFoundException: MySql.Data我不会去逐条引用缺失程序集而是直接换驱动方案。第二个备选方案是 MySqlConnector纯托管库依赖少对 Unity 的 Mono 环境支持更好而且 Async 方法更完整。如果你的项目是从零开始、没有历史包袱我建议第一选择就是它。本篇文章的示例代码用 MySql.Data 写因为搜索这个标题的人多数已经手里有 dll 了但末尾会给出切换成 MySqlConnector 时只有命名空间不同的说明。2.2 表格载体复用 uGUI ScrollView 还是引入第三方插件表格显示层是另一个容易想复杂的地方。Simple TableUI 的思路是尽量轻不绑任何第三方 UI 插件直接用 uGUI 的 ScrollRect 组装表格。具体做法是一个 ScrollRect 组件作为可视区Content 节点挂 VerticalLayoutGroup每一行是一个带背景图的 HorizontalLayoutGroup行里的每个格子是一个 Text 或 TMP_Text。这套结构的好处是零插件依赖、任意分辨率下 Content 可以自动撑开、ScrollRect 的滚动条天然可用。如果你项目里已经引入了带表格功能的 UI 插件当然可以直接用。但做工具类界面时我倾向于少引依赖因为工具界面往往要放进正式游戏工程第三方插件的版本冲突、字体、Shader 兼容问题都会变成后续维护成本。2.3 最小工程结构与文件清单建议按下面的目录结构组织代码后面维护时不会到处找脚本Assets/ Plugins/ MySql.Data.dll MySql.Data.xml Scripts/ DB/ DBConfig.cs DBManager.cs DBQueryExecutor.cs UI/ SimpleTableUI.cs SimpleTableRow.cs SimpleTableCell.cs Prefabs/ UIRoot.prefab TableRow.prefabDBConfig 管连接字符串DBManager 管打开/关闭连接和查询DBQueryExecutor 管查询逻辑与异步回调SimpleTableUI 负责把 DataTable 渲染成 UI 行。按这个分层之后想换成数据表展示、字段过滤、分页逻辑都只动 UI 层就够了。Plugins 文件夹里放 dll 时有一点要注意Unity 默认对 Plugins 下的程序集有任何兼容性也会全量打进去发布 Player 时要确认在 Player Settings 的 Active Input Handling 和 Api Compatibility Level 里选的 .NET 版本不是过旧的 2.0。.NET 版本我一般结合 MySql 驱动的目标框架设成 .NET Standard 2.0能兼容更多环境。3. 从查询到渲染Simple TableUI 的完整实现与参数说明这章是核心先实现数据库连接再写查询最后把结果渲染成表格。3.1 连接字符串配置与最小连接类连接字符串直接写死在脚本里不是最好的做法但工具类项目最怕过度设计。我一般放到一个 DBConfig 静态类里这样只改一处。// DBConfig.cs using System; public static class DBConfig { public static string Server 127.0.0.1; public static int Port 3306; public static string User root; public static string Password your_password; public static string Database game_db; public static string Charset utf8mb4; public static bool Pooling true; public static uint ConnectionTimeout 10; public static string GetConnectionString() { return string.Format( Server{0};Port{1};User{2};Password{3};Database{4}; Charset{5};Pooling{6};ConnectionTimeout{7};SslModeNone;, Server, Port, User, Password, Database, Charset, Pooling, ConnectionTimeout); } }关键参数说明Charsetutf8mb4是中文正常显示的前提用utf8会在部分字符集环境下出现显示问题SslModeNone是测试内网环境的常见配置MySQL 8 默认要求 SSL 校验本地工具开着自签证书反而容易连不上Poolingtrue避免反复握手工具界面频繁点按钮刷新时收益明显。3.2 查询数据并转成可渲染的 DataTable连接写完后写一个查询执行器返回DataTable。这一步要顺手做两件事用参数化 SQL 避免拼字符串注入查询结束及时释放连接。// DBQueryExecutor.cs using UnityEngine; using MySql.Data.MySqlClient; using System.Data; public class DBQueryExecutor { public DataTable ExecuteQuery(string sql) { DataTable dt new DataTable(); using (MySqlConnection conn new MySqlConnection(DBConfig.GetConnectionString())) { conn.Open(); using (MySqlCommand cmd new MySqlCommand(sql, conn)) { cmd.CommandType CommandType.Text; using (MySqlDataAdapter adapter new MySqlDataAdapter(cmd)) { adapter.Fill(dt); } } } return dt; } public DataTable ExecuteQueryWithParams(string sql, params MySqlParameter[] parameters) { DataTable dt new DataTable(); using (MySqlConnection conn new MySqlConnection(DBConfig.GetConnectionString())) { conn.Open(); using (MySqlCommand cmd new MySqlCommand(sql, conn)) { cmd.Parameters.AddRange(parameters); using (MySqlDataAdapter adapter new MySqlDataAdapter(cmd)) { adapter.Fill(dt); } } } return dt; } }这段代码的逻辑不复杂注意using块的使用MySqlConnection、MySqlCommand、MySqlDataAdapter 都实现了 IDisposable逐层 using 能保证连接即使异常也会释放。很多人的工具跑两天就报连接池耗尽就是漏了 finally 块或没写 using。参数化查询的方法里MySqlParameter可以用cmd.Parameters.AddWithValue(key, value)简写但 AddWithValue 在 MySQL 8 的某些版本下推断类型不准确显式new MySqlParameter(key, MySqlDbType.Int32)更稳。3.3 UI 动态生成行列布局与自适应列宽拿到 DataTable 之后进入 SimpleTableUI 的渲染逻辑。每次刷新都要重建行行数 DataTable.Rows.Count列数 DataTable.Columns.Count。这一层用代码动态生成而不是在编辑器里手拖几十个 Text是因为列是动态的字段一变就全废了。// SimpleTableUI.cs using UnityEngine; using UnityEngine.UI; using System.Data; public class SimpleTableUI : MonoBehaviour { public GameObject headerPrefab; // 表头行模板 public GameObject rowPrefab; // 数据行模板 public Transform contentRoot; // ScrollRect 的 Content private DBQueryExecutor executor new DBQueryExecutor(); public void LoadData(string tableName) { DataTable dt executor.ExecuteQuery(SELECT * FROM tableName LIMIT 500;); RenderTable(dt); } private void RenderTable(DataTable dt) { foreach (Transform child in contentRoot) { Destroy(child.gameObject); } // 表头行 GameObject header Instantiate(headerPrefab, contentRoot); SetRowTexts(header, dt.Columns); // 数据行 for (int i 0; i dt.Rows.Count; i) { GameObject row Instantiate(rowPrefab, contentRoot); SetRowTexts(row, dt.Rows[i], dt.Columns); } } private void SetRowTexts(GameObject row, DataColumnCollection cols) { // 行内格子的 Text 数组按顺序排列 Text[] texts row.GetComponentsInChildrenText(); for (int i 0; i texts.Length; i) { if (i cols.Count) texts[i].text cols[i].ColumnName; } } private void SetRowTexts(GameObject row, DataRow dataRow, DataColumnCollection cols) { Text[] texts row.GetComponentsInChildrenText(); for (int i 0; i texts.Length; i) { if (i cols.Count) texts[i].text dataRow[i].ToString(); } } }逻辑说明写到这几个关键点Destroy是延迟删除连续刷新两次表格会出现闪一下要瞬间清掉旧数据用DestroyImmediate配合contentRoot.DetachChildren()或者直接游戏对象池。表头和数据行共用同一个模板会造成表头格式和数据行没区别建议单独做一个表头模板多一个背景色半透明遮罩。参数层面LIMIT 500是防手滑。工具界面的刚需是能看到数据不是一次拉几十万行。等表格能跑通再看要不要加分页别上来就全量查询。3.4 行模板的必需品LayoutElement 与 Text 对齐行模板在 Hierarchy 里长这样Row(Prefab) 下挂 HorizontalLayoutGroup里面每个 Cell 是一个带 LayoutElement 的 Image Text。HorizontalLayoutGroup 的四个值影响所有格子我常用的是Spacing 8Padding 4,4,4,4ChildForceExpandWidth false。Cell 上的 LayoutElement 是列宽控制的入口。PreferredWidth指定理想宽度FlexibleWidth设为 1 表示自动占满剩余空间。列多的时候我会把第一列设置MinWidth 80其余列按类型给 60~200 不等。这样数据库字段再多UI 也不会挤成一团。4. 连接参数与数据权限编码、连接池、执行权限的细节表格显示出来之后接下来最重要的问题不是界面好看而是这个工具在真实使用环境下不会翻车。最常翻车的是中文乱码、连接池占满、查询超时。4.1 表结构字段与 DataTable 映射的边界ExecuteQuery拿到的 DataTable 列名直接来自数据库字段名如果你的字段名里带下划线表格表头就会原样显示 product_id 而不是产品 ID。工具给策划或运营用他们会抱怨看不懂列名。常见的解决办法是在 SQL 层做别名映射SELECT product_id AS 产品ID, product_name AS 商品名 FROM product或者传给 UI 一个列名映射字典。另一个坑是字段类型。DataTable 取出的是强类型值比如 DATETIME 取出来是 DateTime但你 ToString() 后的格式是2025-06-01 12:00:00想显示简短版本就得在 SQL 层用DATE_FORMAT(create_time, %Y-%m-%d %H:%i)格式化。4.2 MySQL 的等待超时与连接池耗尽连接池耗尽是这个方案最常见的黑匣子问题表现是工具开了半小时点一下刷新卡了 10 秒后报Timeout expired。原因通常有两个。第一是连接没释放打开连接后没关连接池满了新连接只能等第二是 MySQL 服务端的wait_timeout把空闲连接回收了客户端连接池还不知道拿着死连接去用。排查方法分三步先用SHOW STATUS LIKE Threads_connected;看当前连接数再在代码里确认每个连接都在 using 块里最后在连接字符串里设置Connection Lifetime参数让连接池定期清掉闲置连接。连接池的 Connection 不是越多越好默认池大小 100 足够工具场景关键是不能泄漏。4.3 账号权限最小化与敏感数据脱敏工具连数据库要用专门的只读账号不要直接用 root。SQL 注入在这个场景里基本是自伤但权限给小了能避免手滑删表。做法是在 MySQL 里创建一个只读用户CREATE USER tool_reader% IDENTIFIED BY Tool_Read123; GRANT SELECT ON game_db.* TO tool_reader%; FLUSH PRIVILEGES;工具账号只给 SELECTDELETE/UPDATE/DROP 一律不给。这个习惯救过我两次——有次在测试环境把 UPDATE 写成了 DELETE因为账号只读报错后数据没丢。另一个容易被忽略的是密码管理。Unity 客户端是剥离工具但如果你拿到的是别人打包好的工具连接串其实可以通过反编译拿到。敏感数据处理原则工具内展示的身份证号、手机号要在 SQL 层直接脱敏比如SELECT CONCAT(LEFT(phone,3), ****, RIGHT(phone,4))别把全量敏感数据拉到本地再隐藏还没显示到 UI 上就已经在内存里过了一遍。5. 避坑Unity 连 MySQL 最常见的 5 个翻车现场5.1 连不上Host xxx is not allowed to connect to this MySQL server现象运行时报错Host 192.168.1.10 is not allowed to connect to this MySQL server。原因MySQL 默认只允许 localhost 连接远程连接权限没开。解决在 MySQL 服务器上执行GRANT ALL PRIVILEGES ON game_db.* TO tool_reader%;或者创建账号时指定 IP 网段。注意%不是允许所有 IP在 MySQL 8 里%代表所有主机但 localhost 是单独记录的如果工具是连 127.0.0.1 而代码里写 localhost也会出现这个问题。5.2 中文全部变成问号现象表格里所有中文显示为????????。原因连接字符串里少了分号或者漏了Charsetutf8mb4参数也可能数据库表本身是 latin1 字符集。解决连接字符串按 3.1 节的写法补齐 Charset再执行ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。表改完重启工具再拉数据就正常了。5.3 每次查询都卡住主线程点击按钮后界面假死现象按下查询按钮界面卡 1~2 秒然后才出表格。数据量大时卡 5 秒以上。原因查询逻辑直接跑在主线程MySqlConnection.Open() 和 adapter.Fill() 都是 IO 阻塞操作。解决UI 操作放主线程数据库查询放后台线程。开一个线程执行查询完成后用 Unity 的UnityMainThreadDispatcher回调主线程生成 UI具体代码在第 6 章。5.4 发布到 Windows 后报错 FileNotFoundException: MySql.Data现象编辑器里跑得好好的打包后再打开点查询直接报找不到 MySql.Data。原因MySql.Data.dll 没有被打进包或者没随构建一起拷贝。Plugins 下的 dll 有时在子目录中未被识别为需要拷贝的资源。解决打开 Plugins 文件夹在 MySql.Data.dll 的 Inspector 面板里确认Any Platform勾上了而且在Include in Build选项选中。另一个隐蔽原因是 dll 放在 Editor 文件夹或 StreamingAssets 文件夹里了移动它到 Plugins 根目录。5.5 SSL 连接错误Authentication to host failed现象连接时报MySql.Data.MySqlClient.MySqlException: Authentication to host ... for user ... using method ... failed且错误前缀有 SSL 字样。原因MySQL 8 默认开启了 SSL 校验但客户端侧驱动拿不到可信证书或自签证书不被信任。Unity 里的 Mono 环境对自签证书的信任处理很麻烦属于血泪经验区。解决测试环境连接字符串加SslModeNone;如 3.1 节生产环境如果 MySQL 有正式证书把SslModePreferred留空避免强制 None 泄露密码。这行字写错排查起SSL来是玄学级别的体验先从 SslMode 入手改。6. 异步加载与增量刷新把 Simple TableUI 做成常用工具界面表格能同步显示之后最后的收尾工作是让它别卡界面、能刷新、能看大数据表。这里说两个我常用的进阶处理。6.1 用线程做异步查询主线程只做 UI 刷新Unity 2021 上异步可以走 async/await但这套代码在 2020 上就得改。我给一个通用写法兼容所有版本// SimpleTableUI_Async.cs using System; using System.Threading; using System.Data; using UnityEngine; public class SimpleTableUI_Async : MonoBehaviour { public GameObject rowPrefab; public Transform contentRoot; public GameObject loadingPanel; public void LoadAsync(string tableName) { loadingPanel.SetActive(true); ThreadPool.QueueUserWorkItem(state { DBQueryExecutor executor new DBQueryExecutor(); DataTable dt executor.ExecuteQuery(SELECT * FROM tableName LIMIT 1000;); RunOnMainThread(() { RenderTable(dt); loadingPanel.SetActive(false); }); }); } private void RunOnMainThread(Action action) { MainThreadQueue.Enqueue(action); } }MainThreadQueue是一个轻量分发器Update 里把队列里的 Action 逐个执行。注意查询线程里不要碰任何 Unity APIInstantiate、Destroy、Text.text都必须在主线程。这里的RunOnMainThread只是一个示意实际落地时可以用 UniTask 的UniTask.SwitchToMainThread或者自己维护一个 ConcurrentQueue。线程池的默认线程数足够别在工具里起裸 Thread也不好管。6.2 增量刷新与分页——别让表格一屏装十万行同步刷新掉一整个表再重建所有行会让你点击查询按钮后等半天出不来看见凉 UI。实用做法是加两个参数页码和页大小。SELECT * FROM product ORDER BY id DESC LIMIT 200 OFFSET 0;每次翻页只查 200 条渲染 200 个 Text 在 uGUI 里是合理的超过 1000 行时请优先想着分页而不是优化渲染。刷新功能我一般做成按钮 快捷键按 R 重新抓当前页这样本地改了数据也能快速同步。若你还想要一个“点某个表格行看对应字段详情”的弹窗复用同一个 DataRow 数据即可这属于表格之后的交互扩展第 3 章的DataRow里保留原始字段类型就是为这个准备的。最后收一句个人习惯做这类数据库工具我会把连接字符串放在不被 Git 跟踪的DBConfig.local.cs中提交时只留模板。团队里接手的人永远会拿着连接串问为什么连不上把配置抽出来之后每次排错都快很多。Simple TableUI 做到能查、能分页、能异步、能脱敏这四件事工具就能安心交到策划手里用了。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

C语言链表:从基础操作到高级应用全解析

C语言链表:从基础操作到高级应用全解析

1. 链表基础与核心概念 链表是C语言中最基础也最重要的数据结构之一,它与数组最大的区别在于内存的非连续性和动态扩展能力。想象一下火车车厢的连接方式——每节车厢独立存在,通过挂钩连接,这就是链表的生动写照。 1.1 链表的结构定义 链表…

📅 2026/11/2 10:29:02
C# WinForm MQTT客户端实例:协议选型、订阅发布与避坑指南

C# WinForm MQTT客户端实例:协议选型、订阅发布与避坑指南

简介:面向 C# WinForm 开发者的 MQTT 客户端实例(StdioMQTT-master),适合需要接入 MQTT 服务器、学习消息遥测传输协议,或搭建桌面端物联网验证工具的开发人员。压缩包共 121 个文件、7.82MB,含 13 个 cs 源…

📅 2026/11/2 10:29:02
基于蒙特卡洛法的电动汽车充电负荷计算MATLAB仿真程序

基于蒙特卡洛法的电动汽车充电负荷计算MATLAB仿真程序

简介:针对电动汽车充电负荷预测这一电力系统规划的关键问题,这份MATLAB程序提供了基于蒙特卡洛法的完整计算方案,面向电力系统研究人员、电动汽车方向学生及工程师,适用于充电基础设施规划与电网调度分析。程序通过大量随机抽样模…

📅 2026/11/2 10:29:02
MORE NEWS

更多资讯

📰

OSM路网入Neo4j:Java路由服务的Dijkstra/A*算路与接口封装

简介:Neo4jOSM 是一个以 Java 实现的轻量级路线规划示例项目,面向希望将图数据库与开放地理数据结合的开发者与学习者,重点解决从 OpenStreetMap 路网数据到 Neo4j 图模型、再到路径查询的基础实践问题。压缩包共 35 个文件,约 31…

📰

Winform中英文实时切换:XML语言包与控件树递归实践

简介:面向 Winform 桌面开发学习者的中英文切换示例项目,基于 C# 与 Visual Studio 2012 构建,通过 XML 文件集中存放中英文文本资源,演示界面语言动态加载、事件驱动切换及软件国际化与本地化的基础实现,适合需要为桌…

📰

C++实现大数相乘的算法

前言 C 内置的整数类型有明确的上限:long long 至少 64 位,能表示的最大无符号值约为 1.810⁹,也就是 20 位十进制数。计算阶乘、处理加密参数、做大数幂运算时,结果动辄几百上千位,内置类型完全不够用。大数相乘&…

📰

CS229机器学习复习主线:从监督学习到SVM与EM的推导链

简介:CS229 全课程资料包面向希望系统学习机器学习的学习者与复习备考者,汇集 Andrew Ng 课程讲义、作业及配套讲解,可帮助读者从线性回归、逻辑回归、生成学习、支持向量机、学习理论、EM 与聚类、PCA、因子分析到强化学习等主题建立完整知识…

📰

声源定位精度瓶颈:GCC-PHAT时延估计与MUSIC空间谱实践

简介:面向信号处理与声学定位方向的学习者与研究者,这份 MATLAB 程序包围绕声源定位的三条典型技术路线展开:基于到达时间差的广义互相关定位、基于阵列信号处理的空间谱估计定位,以及用于模拟室内反射与衰减的简单房间回响模型。…

📰

YOLO26最新创新改进系列:样条KAN令牌主干,1×1 卷积给每个通道一个固定权重:让 YOLO26 的主干用样条函数去表达非线性!

YOLO26最新创新改进系列:样条KAN令牌主干,11 卷积给每个通道一个固定权重:让 YOLO26 的主干用样条函数去表达非线性! 截止目前,YOLO26最新创新改进系列已更新100种,排列组合后可达到上万种创新模型&#x…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬