首页
/ Dapper中处理JSON_CONTAINS查询参数替换的技巧

Dapper中处理JSON_CONTAINS查询参数替换的技巧

2025-05-12 10:33:41作者:范靓好Udolf

在使用Dapper进行MySQL数据库操作时,经常会遇到需要处理JSON类型数据的场景。本文将通过一个实际案例,介绍如何在Dapper中正确替换JSON_CONTAINS函数中的参数变量。

问题背景

在MySQL中,JSON_CONTAINS函数用于检查JSON文档中是否包含特定值。开发者经常需要动态地将参数传递给这个函数。例如:

JSON_CONTAINS(mcmod_game_version->'$.Fabric', '[\"@version\"]')

当尝试通过Dapper传递参数时:

var list = codeSQL.Query<DataObj>(sql, new {version});

发现这种方式无法正常工作,而直接拼接字符串却能成功查询。

问题分析

这个问题源于SQL字符串字面量的处理机制。在SQL中,字符串字面量中的内容(包括@符号)会被视为普通字符,而不是参数占位符。因此,'["@version"]'中的@version不会被Dapper识别为需要替换的参数。

解决方案

方法一:使用字符串连接

MySQL支持使用CONCAT函数动态构建JSON字符串:

JSON_CONTAINS(mcmod_game_version->'$.Forge', CONCAT('[\"', @version, '\"]'))

这种方式通过CONCAT函数将参数值动态插入到JSON字符串中,确保Dapper能够正确识别并替换@version参数。

方法二:使用字符串拼接操作符

另一种方法是使用字符串拼接操作符:

'[\"' + @version + '\"]'

但需要注意,这种方法在某些MySQL版本或配置下可能会有不同的行为,且需要特别注意SQL注入风险。

安全注意事项

在使用动态构建JSON字符串时,必须考虑SQL注入风险:

  1. 始终使用参数化查询(如Dapper提供的参数替换)
  2. 对输入参数进行严格验证
  3. 避免直接将用户输入拼接到SQL语句中

完整示例

以下是一个完整的C#代码示例,展示了如何在Dapper中正确使用JSON_CONTAINS函数:

string sql = @"
    SELECT * FROM `mcmod` 
    WHERE `mcmod_mod_type` LIKE @modtype 
    AND JSON_CONTAINS(mcmod_game_version->'$.Forge', CONCAT('[\"', @version, '\"]')) 
    ORDER BY mcmod_update_time 
    LIMIT @page, 20";

using var connection = new MySqlConnection(connectionString);
var results = connection.Query<ModInfo>(sql, new {
    modtype = "魔法",
    version = "1.12.2",
    page = 0
});

总结

在Dapper中处理MySQL的JSON_CONTAINS函数时,直接使用@参数占位符在JSON字符串字面量中是无效的。开发者需要通过CONCAT函数或字符串拼接的方式动态构建JSON字符串,同时确保使用参数化查询来防止SQL注入。理解这些细节可以帮助开发者更高效地使用Dapper处理JSON类型数据的查询。

登录后查看全文
热门项目推荐
相关项目推荐