HQL查询忽略重音

时间:2011-07-28 17:20:29

标签: java hibernate hql ignore diacritics

我有以下问题:

select u from User u where upper(u.name) like upper(?1)

这是怎么回事,但忽略了u.name?1中的重音?

谢谢你们!

4 个答案:

答案 0 :(得分:0)

您使用的数据库是什么?在大多数情况下,您可以发送特定的SQL命令来设置排序规则。

答案 1 :(得分:0)

我找到了实现这个的方法。基本上有两个步骤:

  1. 规范化参数(在您的情况下为1)和
  2. 规范化数据库中的数据
  3. 实施例

    public User getByName(String paramName) {
       .....
    }
    

    原始HQL查询:

    String queryString = "select u from User u where u.name : =paramName";
    

    新查询:

    paramName = normalizer(paramName );
    
    String queryString = "select u from User u where " + replacer(u.name) +" : =paramName";
    

    以及两种方法:

    public static String normalizer(String s)  {
        return Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
    }
    
    public String replacer(String param) {
        String t1 = "àâäçéèëêùûüôöïî";
        String t2 = "aaaceeeeuuuooii";
        String s = param;
        for (int i = 0; i < t1.length(); i++) {
            s = "replace(" + s + ",'" + t1.charAt(i) + "','" + t2.charAt(i) + "')";
        }
        return s;
    }
    

答案 2 :(得分:0)

在葡萄牙语中,我错过了某些字符的重音,所以我在替换方法中添加了更多字符:

public String replacer(String param) {
    String t1 = "áãàâäçéèëêùûüúóôöïîíÁÀÂÄÃÇÉÈËÊÙÛÜÚÓÔÖÏÎÍ";
    String t2 = "aaaaaceeeeuuuuoooiiiAAAAÃCEEEEUUUUOOOIII";
    String s = param;
    for (int i = 0; i < t1.length(); i++) {
        s = "replace(" + s + ",'" + t1.charAt(i) + "','" + t2.charAt(i) + "')";
    }
    return s;
}

答案 3 :(得分:0)

通过 CriteriaBuilder,您可以使用以下规范

public static Specification<User> byNameIgnoringCaseAndAccents(String paramName) {

    return (root, cq, cb) -> {
        String paramNameNormalized = paramName != null ? normalize(paramName.toLowerCase()) : null;

        String characters = "áãàâäçéèëêùûüúóôöïîíÁÀÂÄÃÇÉÈËÊÙÛÜÚÓÔÖÏÎÍ";
        String replacements = "aaaaaceeeeuuuuoooiiiAAAAÃCEEEEUUUUOOOIII";
        Expression<String> replacedName = root.get("name");
        for (int i = 0; i < characters.length(); i++) {
            replacedName = cb.function("REPLACE", String.class, replacedName, cb.literal(characters.charAt(i)), cb.literal(replacements.charAt(i)));
        }
        replacedName = cb.lower(replacedName);

        return cb.like(cb.literal(paramNameNormalized), cb.concat("%", cb.concat(replacedName, "%")));
    };
}

public static String normalize(String s) {
    return s != null ? Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "") : s;
}