Spring Data JPA 的 Specification 通过 CriteriaBuilder 的 like() 配合 concat() 或字符串拼接实现模糊查询,支持前缀、后缀、全模糊匹配;推荐用 lower() 统一转小写以保证跨库一致性,并注意防止 SQL 注入。
` 中怎么配合通配符构造复杂查询">
Spring Data JPA 的 Specification 本身不直接支持 SQL 通配符(如 %、_),但你可以通过 CriteriaBuilder 的 like()、ilike()(PostgreSQL)或 lower()/upper() 配合字符串拼接,安全地构造带通配符的模糊查询。
like() + concat() 实现前后/左右模糊匹配like() 是标准 JPA 方法,需手动拼接通配符。关键点是:通配符必须作为字符串值的一部分传入,不能写在字段名里;且推荐使用 CriteriaBuilder#concat() 或 Java 字符串拼接(注意防止 SQL 注入)。
cb.like(root.get("name"), cb.concat(cb.literal("xxx"), "%"))
cb.like(root.get("name"), cb.concat("%", cb.literal("xxx")))
cb.like(root.get("name"), cb.concat("%", cb.concat(cb.literal("xxx"), "%")))
cb.like(root.get("name"), "%" + keyword + "%") —— 仅限 keyword 已校验/转义,否则有注入风险lower() 统一转换数据库默认 like 区分大小写(如 MySQL 默认不区分,但 H2/PostgreSQL 区分)。为确保跨库一致性,建议统一转小写:
cb.like(cb.lower(root.get("name")), "%" + keyword.toLowerCase() + "%")cb.equal(cb.lower(root.get("name")), keyword.toLowerCase()) 做精确小写匹配and() / or() 连接Specification 天然支持逻辑组合。例如“姓名或邮箱包含关键词”:
立即学习“Java免费学习笔记(深入)”;
cb.or( cb.like(cb.lower(root.get("name")), "%" + kw + "%"), cb.like(cb.lower(root.get("email")), "%" + kw + "%"))注意:多个 like 同时存在时,数据库可能无法有效使用索引,大数据量下建议配合全文检索或添加函数索引(如 PostgreSQL 的 LOWER(name) 索引)。
keyword 若来自前端,需清理特殊通配符(%、_、)或设置 escape 字符:
keyword = keyword.replaceAll("[%_]", "")
):cb.like(root.get("desc"), "%"+kw+"%", ''),然后要求用户写 abc% 表示查字面量 %
escape() 方法:cb.like(root.get("desc"), "%" + kw, '')