【发布时间】:2023-04-02 00:46:01
【问题描述】:
嘿,我正在寻找搜索文本模式(在 jpa 中)并对结果进行排序的方法,首先是所有以该字符串开头的结果,然后是所有其他结果。 我找到Mysql order by using search string 得到mysql 的答案
大多数答案使用union(jpa 中不存在)并强制查询数据库或为此打开视图。 (从代码中排序不是很好的解决方案,因为我们使用分页来获取部分结果,因为结果大小可能非常大)
我喜欢上面链接的一个解决方案是:
select * from employee where name like '%ani%' order by locate('ani', name) asc, name asc
source
这在我看来很清楚,但我不确定如何将其转换为 jpa。似乎 Order 对象无法获取定位输出
欢迎任何想法
谢谢!
阿隆
编辑: 谢谢你的答复。我想用 jpa critiera 实现同样的目标
Iterator<Order> sortingIter = page.getSort().iterator();
ArrayList<javax.persistence.criteria.Order> order = new ArrayList<javax.persistence.criteria.Order>();
String fieldName;
while (sortingIter.hasNext()) {
Order sort = sortingIter.next();
fieldName = sort.getProperty();
order.add(sort.getDirection() == Sort.Direction.ASC ? cb
.asc(keyword.get(fieldName)) : cb.desc(keyword
.get(fieldName)));
}
虽然上面的效果很好。我无法将以下行添加到代码中。好像Order对象不喜欢他们
Expression<String> fieldValue = keyword.get(fieldName);
order.add(cb.locate(fieldValue,key));
编辑 2: 试过了 order.add(new javax.persistence.criteria.Order() {
@Override
public javax.persistence.criteria.Order reverse() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isAscending() {
// TODO Auto-generated method stub
return true;
}
@Override
public Expression<?> getExpression() {
// TODO Auto-generated method stub
return cb.locate(fieldValue,key);
}
});
jpa 没有抱怨,但查询没有得到正确的顺序
编辑 3: 发现我的错误!
我在上面传递的键值已经包含“%”并且双方...所以定位没有正常工作。
现在我在一些特殊字符上出现了一些奇怪的行为:如果 - 例如 - 我有单词 Ghurabā 查询 like %ba% 会找到它。但是,locate(Ghurabā,ba) 似乎将返回 0 - 意思是 pattern was not found in string 知道如何克服这个问题吗?
似乎这不仅是 jpa 也是 mysql 行为。
SELECT *
FROM `keywords`
WHERE name LIKE '%ba%'
ORDER BY LOCATE( 'ba', name ) , name
LIMIT 0 , 30
将返回下一个结果
Ghurabā'
Khuṭabā'
qabā\
Ribāṭ
ba'urchi (cook)
Baghdad
...
请注意,它确实适用于“常规英文字符”,但 like 和 locate 函数之间存在不匹配
使用Collcation:utf8_general_ci(与utf_unicode_ci得到相同的结果)
【问题讨论】:
标签: jpa jpa-2.0 spring-data-jpa