在MyBatis-Plus中,可通过apply方法结合动态参数占位符实现JSON字段的高效查询,避免SQL注入并提升代码可读性。 具体实现步骤如下:
1. 核心方法:apply动态拼接SQL- apply方法允许将动态参数安全嵌入SQL片段,通过占位符(如{0})替换实际值,防止SQL注入。
- 语法:apply("SQL片段", 参数1, 参数2...),其中SQL片段中的{n}会被第n+1个参数替换。
2. JSON字段查询示例- 场景:查询data表中json_data字段包含键test_variable的记录,且键值动态传入。
- 原始SQL风险:直接拼接json_extract(json_data,'$.test_variable')会导致SQL注入,且硬编码参数降低可维护性。
- MyBatis-Plus优化方案:ChainWrappers.lambdaQueryChain(mapper) .apply("JSON_EXTRACT(json_data,'$.{0}')", "test_variable") .list();
说明:
{0}为占位符,被"test_variable"替换。
生成的SQL为:SELECT * FROM data WHERE JSON_EXTRACT(json_data,'$.test_variable'),参数动态且安全。
3. 多参数与复杂条件扩展多参数占位:若需同时查询多个JSON键,可扩展apply参数:
ChainWrappers.lambdaQueryChain(mapper) .apply("JSON_EXTRACT(json_data,'$.{0}') = {1}", "test_variable", "expected_value") .list();生成的SQL:WHERE JSON_EXTRACT(json_data,'$.test_variable') = 'expected_value'。
组合条件:结合and或or方法构建复杂查询:
ChainWrappers.lambdaQueryChain(mapper) .apply("JSON_EXTRACT(json_data,'$.{0}') IS NOT NULL", "key1") .eq("other_field", "value") .list();
4. 与Lambda查询的对比优势- Lambda查询:适用于表字段直接映射,但无法直接处理JSON内部路径。// 仅适用于普通字段,无法查询JSON内部lambdaQuery().eq(Data::getNormalField, "value");
- apply方法:专为非标准字段(如JSON)设计,通过动态SQL片段实现灵活查询。
5. 注意事项- 数据库兼容性:JSON_EXTRACT是MySQL语法,其他数据库需替换为等效函数(如PostgreSQL的jsonb_path_query)。
- 占位符索引:从{0}开始,按参数顺序递增。
- 性能优化:对频繁查询的JSON字段,可考虑添加函数索引(如MySQL的生成列索引)。
6. 完整代码示例// 查询json_data中包含test_variable且值为"123"的记录List<Data> result = ChainWrappers.lambdaQueryChain(dataMapper) .apply("JSON_EXTRACT(json_data,'$.{0}') = {1}", "test_variable", "123") .list();总结:MyBatis-Plus的apply方法通过动态SQL拼接与占位符机制,为JSON字段查询提供了安全、高效的解决方案,兼顾了灵活性与代码规范性。