拒绝死记硬背:从底层拆解C#数据库操作与SQL注入防护全攻略
大家好,我是零点博客博主。最近在整理EMLOG插件源码和在线工具的底层逻辑时,发现很多初学者对数据库操作的理解还停留在“拼接字符串”的层面。今天不整虚的,我们直接用 C# 结合 MySQL 来实战,讲讲为什么预处理语句是后端开发的底线,以及如何写出高性能的 SQL 语句。
一、 字符串拼接的致命伤:SQL注入原理
在做后端开发时,最忌讳的就是手动拼接 SQL 语句。比如用户输入一个 `' or 1=1 --`,如果你直接拼接进字符串,数据库一查全挂了。
很多人觉得这是理论,在爬虫开发或简单接口中不防护没事。但在开发像“在线工具开发”这类对稳定性要求高的产品时,这是致命的。底层逻辑很简单:SQL 执行时,参数变成了执行逻辑的一部分,而不是数据本身。
二、 核心方案:预处理语句与SqlParameter
怎么解决?答案就是预处理语句。在 C# 中,不要相信任何来自前端的 HTML/CSS/JS 数据,统统丢给数据库参数化。
1. 建立连接与对象
首先需要引用 `MySql.Data` 包。建立连接时,务必注意连接字符串的配置。
using System.Data;
using MySql.Data.MySqlClient;
// 这里是经典的连接池管理方式
string connectionString = "Server=localhost;Database=emlog;Uid=root;Pwd=123456;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
2. 执行安全的数据库操作
千万不要用 `string.Format("select * from user where name = '{0}'", inputName)` 这种做法。直接用参数。
// 使用参数化查询,底层会自动转义特殊字符
using (SqlCommand cmd = new SqlCommand("SELECT id, username FROM user WHERE status = @status", conn))
{
cmd.Parameters.AddWithValue("@status", 1); // 强类型,杜绝注入
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
// 读取数据,配合 JSON 序列化返回给前端
responseList.Add(new { id = dr.GetInt32(0), name = dr.GetString(1) });
}
}
}
}
三、 实战复盘:JSON/XML 数据解析与接口开发
数据库查出来的只是数据,真正给用户看的是接口。在开发接口时,我们要考虑兼容性。
- JSON 解析: 现在的趋势是 JSON,速度快且轻量。我们可以用 `Newtonsoft.Json` 库,把 C# 对象直接序列化。
- XML 解析: 老旧系统或特定系统可能需要 XML。可以用 `XmlDocument` 或 LINQ to XML。但在新项目中,推荐 JSON。
比如一个简单的用户查询接口:
// 假设 responseList 是 List<User>
string jsonResult = JsonConvert.SerializeObject(responseList);
// 返回给前端,浏览器会自动解析 JSON
context.Response.ContentType = "application/json";
context.Response.Write(jsonResult);
四、 底层拆解与避坑指南
作为一个在技术上反复踩坑的博主,这里有几个避坑指南:
- 资源释放: `using` 语句块是神器,确保 `SqlConnection` 和 `SqlCommand` 及时释放,防止连接池耗尽。
- 事务处理: 如果是涉及金额或库存的更新,必须开启事务。一旦异常,回滚,这比 try-catch 重要得多。
- 正则表达式优化: 在插入数据前,用正则表达式过滤掉非法字符,作为最后一道防线。
掌握好数据库操作的精髓,你就掌握了后端的七寸。希望这篇结合 C# 实战与 EMLOG 开发的复盘,能帮大家在开发在线工具时少走弯路。
关注零点博客,获取更多关于爬虫、接口开发与底层原理的硬核干货。



评论一下吧
取消回复