【问题标题】:order-by-using-search-string - JPA按使用搜索字符串排序 - JPA
【发布时间】:2023-04-02 00:46:01
【问题描述】:

嘿,我正在寻找搜索文本模式(在 jpa 中)并对结果进行排序的方法,首先是所有以该字符串开头的结果,然后是所有其他结果。 我找到Mysql order by using search string 得到mysql 的答案

大多数答案使用unionjpa 中不存在)并强制查询数据库或为此打开视图。 (从代码中排序不是很好的解决方案,因为我们使用分页来获取部分结果,因为结果大小可能非常大)

我喜欢上面链接的一个解决方案是: 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 函数之间存在不匹配

使用Collcationutf8_general_ci(与utf_unicode_ci得到相同的结果)

【问题讨论】:

    标签: jpa jpa-2.0 spring-data-jpa


    【解决方案1】:

    这不会引起任何抱怨。

    String jpql = "select e from Employee e where e.name like '%ani%' order by locate('ani', e.name) asc, e.name asc";
    TypedQuery<Employee> query2 = em.createQuery(jpql ,Employee.class);
    

    这就是hibernate所做的翻译。

    休眠:选择employee0_.id 作为id1_2_,employee0_.address_id 作为 地址 5_2_,employee0_.DEPT_ID 作为 DEPT6_2_,employee0_.manager_id 作为 manager7_2_,employee0_.name 作为 name2_2_,employee0_.salary 作为 工资 3_2_,员工 0_.startDate 作为来自员工的 startDat4_2_ employee0_ where employee0_.name like '%ani%' order by locate('ani', employee0_.name) asc, employee0_.name asc

    使用一些数据作为您提到的链接。

    Employee 10: name: anil, salary: 59000, 
    Employee 1: name: anirudha, salary: 55000, 
    Employee 5: name: rani, 
    Employee 7: name: Stephanie, salary: 54000, 
    

    {anil,anirudha,rani, ...}

    使用 CriteriQuery 解决方案时遇到同样的问题

    好吧,你给我一些积分 =)

    休眠:选择employee0_.id 作为id1_2_,employee0_.address_id 作为address5_2_,employee0_.DEPT_ID 作为DEPT6_2_,employee0_.manager_id 作为manager7_2_,employee0_.name 作为name2_2_,employee0_.salary 作为salary3_2_,employee0_.startDate 作为startDat4_2_ from Employeeemployee0_ employee0_.name 喜欢在哪里?按 locate(?, employee0_.name) asc, employee0_.name asc 排序

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
    
    Root<Employee> root = cq.from(Employee.class);
    cq.where(cb.like(root.<String>get("name"), "%ani%"));
    cq.orderBy(cb.asc(cb.locate(root.<String>get("name"), "ani")), cb.asc(root.get("name")));
    
    TypedQuery<Employee> query2 = em.createQuery(cq);
    printList(query2.getResultList());
    

    试试上面的应该可以的。

    Employee 10: name: anil, salary: 59000, 
    Employee 1: name: anirudha, salary: 55000, 
    Employee 5: name: rani, 
    Employee 7: name: Stephanie, salary: 54000, 
    

    如果您认为 ?(问号)在查询中不正确,请查看此内容。 http://webdev.apl.jhu.edu/~jcs/ejava-javaee/coursedocs/605-784-site/docs/content/html/jpa-query-criteria-function.html#jpa-query-criteria-function-string-locate

    【讨论】:

    • 嘿@Koitoer 感谢您的快速回复。我已编辑我的问题以使用 JPA 标准
    猜你喜欢
    • 2011-11-22
    • 2016-03-15
    • 1970-01-01
    • 2011-02-14
    • 2014-07-02
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多