Spring Data JPA Specification实现SQL Server高棉语LIKE查询(带N前缀)
问题描述
基于Spring Boot + Spring Data JPA + SQL Server 2017开发应用时,需要用LIKE表达式查询高棉语Unicode数据。在SQL Server Management Studio中执行以下语句可正常返回结果:
SELECT * FROM merchant_holiday_setting WHERE description_kh LIKE N'%ទិវា%'
但通过JPA Specification Criteria实现时无法正常匹配,当前的Kotlin代码如下:
override fun findAllList(q: String?, page: Int, size: Int): Page<MerchantHolidaySetting>? { return mchHolidayRepo.findAll({ root, cq, cb -> val predicate = ArrayList<Predicate>() q?.let { println("Query $q") val descEn = cb.like(cb.upper(root.get("description")), "%${q.toUpperCase()}%") val descKh = cb.like(root.get("descriptionKh"), "%$q%") predicate.add(cb.or(descEn, descKh)) } predicate.add(cb.isTrue(root.get("status"))) cq.orderBy(cb.asc(root.get<Date>("holidayDate"))) cb.and(*predicate.toTypedArray()) }, PageRequest.of(page, size)) }
解决方案
问题核心在于SQL Server中N'%xxx%'的N前缀表示该字符串为Unicode(NVARCHAR类型),而JPA默认生成的SQL不会自动添加这个前缀,导致高棉语字符无法被正确识别匹配。以下两种方法可以解决:
方法一:修改Hibernate配置(推荐)
通过配置让Hibernate默认将所有String参数按NVARCHAR类型处理,自动生成带N前缀的SQL。在application.properties或application.yml中添加以下配置:
# 指定SQL Server方言 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect # 让所有String参数默认使用NVARCHAR类型 spring.jpa.properties.hibernate.connection.defaultNChar=true
添加配置后,原有的JPA Specification代码无需修改即可正常匹配高棉语Unicode数据。
方法二:手动构造带N前缀的LIKE条件
如果不想修改全局配置,可以在Specification中手动构造带N前缀的匹配条件,同时保持参数绑定避免SQL注入:
override fun findAllList(q: String?, page: Int, size: Int): Page<MerchantHolidaySetting>? { return mchHolidayRepo.findAll({ root, cq, cb -> val predicate = ArrayList<Predicate>() q?.let { println("Query $q") val descEn = cb.like(cb.upper(root.get("description")), "%${q.toUpperCase()}%") // 手动构造带N前缀的Unicode匹配条件 val khPattern = cb.concat(cb.literal("N'%"), cb.concat(q, cb.literal("%"))) val descKh = cb.like(root.get("descriptionKh"), khPattern) predicate.add(cb.or(descEn, descKh)) } predicate.add(cb.isTrue(root.get("status"))) cq.orderBy(cb.asc(root.get<Date>("holidayDate"))) cb.and(*predicate.toTypedArray()) }, PageRequest.of(page, size)) }
这种方式会让JPA生成类似description_kh LIKE N'%?%'的SQL,确保高棉语字符被正确解析。
内容的提问来源于stack exchange,提问作者Tona
相关产品推荐
相关产品推荐

