【问题标题】:HQL query ignoring accents忽略重音符号的 HQL 查询
【发布时间】:2011-10-15 08:01:53
【问题描述】:

我有以下查询:

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

会怎样,但忽略 u.name?1 中的重音符号?

【问题讨论】:

  • 请详细说明您的问题...您是否要从比较中删除重音字符??
  • 我希望在咨询期间忽略重音字符,包括数据库中的参数和值。
  • 不知道能不能在数据库端做。它在 Java 端应该是可行的(在提交查询之前删除重音符号),但是我在基础库(java.util.text)中没有找到任何相关内容。您需要为所有重音字符及其相应的“普通”字符构建一个映射。我很惊讶它还没有完成。

标签: java hibernate hql diacritics


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我已经找到了实现这一点的方法。基本上有2个步骤:

    1. 规范化参数(在您的情况下为 1)和
    2. 标准化数据库中的数据

    例子

    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;
    }
    

    【讨论】:

      【解决方案3】:

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

      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;
      }
      

      【讨论】:

        【解决方案4】:

        使用 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2013-08-28
          • 1970-01-01
          • 2018-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-14
          相关资源
          最近更新 更多