MySQL存储邮编JSON数组及查询报错,求Hibernate实现方案
解决MySQL JSON_CONTAINS查询报错 & Hibernate实现方案
先搞定MySQL的报错问题
你碰到的Error Code: 3146原因很明确:JSON_CONTAINS函数的第二个参数必须是合法的JSON格式值,你直接传数字22079肯定不行——MySQL没法把它识别成JSON类型的参数。另外提一句,如果你的testJson列目前是VARCHAR类型,虽然能存JSON字符串,但最好改成JSON类型,这样MySQL会自动校验格式,减少后续麻烦。
修正后的查询语句
有两种靠谱的写法:
- 直接把查询值用单引号包裹成JSON字符串:
SELECT * FROM Test WHERE JSON_CONTAINS(testJson, '22079');
- 用
JSON_QUOTE函数生成标准JSON值(更严谨,适合JSON类型的列):
SELECT * FROM Test WHERE JSON_CONTAINS(testJson, JSON_QUOTE('22079'));
如果还没改列类型,建议先执行这条语句把testJson改成JSON类型:
ALTER TABLE Test MODIFY COLUMN testJson JSON;
再来说Hibernate的实现方式
这里给你三种常用的方案,根据你的项目情况选就行:
方案1:原生SQL查询
最直接的方式,和你在MySQL客户端写的语句几乎一样:
String targetZip = "22079"; String nativeSql = "SELECT * FROM Test WHERE JSON_CONTAINS(testJson, :zipParam)"; Query<Test> query = entityManager.createNativeQuery(nativeSql, Test.class); // 注意参数要包裹单引号,因为需要是JSON字符串 query.setParameter("zipParam", "'" + targetZip + "'"); List<Test> matchedRecords = query.getResultList();
方案2:HQL查询(适用于Hibernate 5.2+)
先确保你的实体类字段映射正确,比如把testJson映射成JSON类型:
@Entity @Table(name = "Test") public class Test { @Id private Integer id; // 用columnDefinition指定JSON类型,或者用Hibernate的@Type注解 @Column(columnDefinition = "JSON") private List<String> testJson; // 也可以用String类型,看你需求 // getter、setter省略 }
然后写HQL查询:
String targetZip = "22079"; String hql = "FROM Test t WHERE JSON_CONTAINS(t.testJson, :zipParam)"; Query<Test> query = entityManager.createQuery(hql, Test.class); query.setParameter("zipParam", "'" + targetZip + "'"); List<Test> results = query.getResultList();
方案3:Criteria API(类型更安全)
如果项目里常用Criteria API,可以这么写,避免硬拼字符串:
String targetZip = "22079"; CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Test> cq = cb.createQuery(Test.class); Root<Test> root = cq.from(Test.class); // 调用MySQL的JSON_CONTAINS函数 Expression<Boolean> jsonContainsExpr = cb.function( "JSON_CONTAINS", Boolean.class, root.get("testJson"), cb.literal("'" + targetZip + "'") // 生成JSON格式的参数 ); cq.where(jsonContainsExpr); List<Test> matchedList = entityManager.createQuery(cq).getResultList();
内容的提问来源于stack exchange,提问作者Noman
相关产品推荐
相关产品推荐

