如何在PostgreSQL和JPA2中执行类似的不区分大小写和不区分重音的操作?

如何在PostgreSQL和JPA2中执行类似的不区分大小写和不区分重音的操作?,postgresql,jakarta-ee,jpa-2.0,postgresql-9.1,Postgresql,Jakarta Ee,Jpa 2.0,Postgresql 9.1,我有一个使用PostgreSQL 9.X和JPA2(Hibernate实现)的JavaEE项目。 如何强制like查询不区分大小写和重音 我能够更改DB的字符集,因为它是第一个使用它的项目。一般来说,没有标准的方法来编写“不区分重音”的代码,或者在忽略重音的情况下比较单词是否相等。整个想法毫无意义,因为不同的重音字符在不同的语言/方言中意味着不同的东西,它们的“普通ascii”替换/扩展因语言而异。请不要这样做resume和résumé是两个不同的词,如果考虑英语以外的任何语言,情况会变得更糟

我有一个使用PostgreSQL 9.X和JPA2(Hibernate实现)的JavaEE项目。 如何强制like查询不区分大小写和重音


我能够更改DB的字符集,因为它是第一个使用它的项目。

一般来说,没有标准的方法来编写“不区分重音”的代码,或者在忽略重音的情况下比较单词是否相等。整个想法毫无意义,因为不同的重音字符在不同的语言/方言中意味着不同的东西,它们的“普通ascii”替换/扩展因语言而异。请不要这样做
resume
résumé
是两个不同的词,如果考虑英语以外的任何语言,情况会变得更糟

对于大小写不敏感,您可以在JPQL中使用类似lower(“%match\u expression”)的
lower(列)
。据我所知,
ilike
在JPQL中不受支持,但我还没有检查以验证这一点。这是相当可读的,所以考虑下载JPA2规范和阅读它。JPA2标准提供了
限制。为此,我喜欢
。两者都不会规范化/去除/忽略重音字符

对于剥离重音符号等,可能需要使用特定于数据库引擎的存储函数或本机查询。请参阅,例如,或者如果您打算用非重音替代字符替换重音字符,请再次说明,请不要这样做,除非出于非常有限的目的,例如查找可能被误导的软件或用户“非重音”的单词的位置。

如果安装了:

select unaccent(lower('ãóÊ'));
 unaccent 
----------
 aoe

我有这个问题,我不能使用数据库功能。因此,我在标准代码中使用了正则表达式限制:

searchText = unaccent(searchText);
String expression = "firstName ~* '.*" + searchText + ".*'";
Criterion searchCriteria = Restrictions.sqlRestriction(expression);
然后我编写了一个名为uncent的函数,将每个字符更改为or语句,例如,任何字母e都将变成(e |é|)。对“hello”的查询将变成“h(e|é||||||||)llo”

下面是从这个线程中得到启发的函数

private String uncent(字符串文本){
String charactersProcessed=“;//避免多次执行替换。
字符串newText=text.toLowerCase();
text=newText;//Case语句应为小写。
对于(int i=0;i
您使用的是标准查询还是JPQL?另外,请看这个问题:请看,我正在使用标准查询,但如果需要,我可以使用JPQL。我知道upper的诀窍,但它总是对重音敏感…是的,但使用此解决方案,我必须进行本机查询。请,您可以将此方法用于公共静态字符串uncent(字符串文本){return Normalizer.normalize(text,Normalizer.Form.NFD)。replaceAll(“[^\\p{ASCII}]”,“);}谢谢,除非我错误地理解了这个函数
Normalizer.normalize(text,Normalizer.Form.NFD).replaceAll(“[^\\p{ASCII}]”,“)
)的目的,否则它似乎规范了Java代码中的文本。这里需要在PostgreSQL中对其进行规范化。我写的不完整函数我写的不完整函数我写的不完整函数,我写的不完整函数,我写的不完整函数,我写的不完整函数,我写的不完整函数,我写的不完整函数,把这串串<代码>我写的,把这串<代码>你写的<代码>我写的<代码>我写的<代码>把这串<代码>我写我写我写我写的<代码>我写我写我写的<代码>我写我写我写的<代码>我写我写的<代码>我写我写我写的这串<代码>我写我写的<代码>我写我写的<代码>我写的代码>我写我写我写我写的<代码>我写的代码>我写我写的代码>我写我写的这串<代码>我写我写我写我写我写的<代码>我写我写的代码>我写的代码>我写我写我写我写的代码>除了使用本机SQL,解决方案不是最优的。可以使用类似的SQL本机函数,但在我的例子中,我不能。你可以通过将字符串字母表转换成字母表(一个接一个),并在所有结果之间建立一个联合。
private String unaccent(String text) {
    String String charactersProcessed = ""; // To avoid doing a replace multiple times.
    String newText = text.toLowerCase();
    text = newText; // Case statement is expecting lowercase.
    for (int i = 0; i < text.length(); i++) {
        char c = text.charAt(i);
        if (charactersProcessed.contains(c + "")) {
            continue; // We have already processed this character.
        }
        String replacement = "";
        switch (c) {
        case '1': {
            replacement = "¹";
            break;
        }
        case '2': {
            replacement = "²";
            break;
        }
        case '3': {
            replacement = "³";
            break;
        }
        case 'a': {
            replacement = "á|à|â|ã|ä|å|ā|ă|ą|À|Á|Â|Ã|Ä|Å|Ā|Ă|Ą|Æ";
            break;
        }
        case 'c': {
            replacement = "ć|č|ç|©|Ć|Č|Ç";
            break;
        }
        case 'd': {
            replacement = "Đ|Ð";
            break;
        }
        case 'e': {
            replacement = "è|é|ê|ё|ë|ē|ĕ|ė|ę|ě|È|Ê|Ë|Ё|Ē|Ĕ|Ė|Ę|Ě|€";
            break;
        }
        case 'g': {
            replacement = "ğ|Ğ";
            break;
        }
        case 'i': {
            replacement = "ı|ì|í|î|ï|ì|ĩ|ī|ĭ|Ì|Í|Î|Ï|Ї|Ì|Ĩ|Ī|Ĭ";
            break;
        }
        case 'l': {
            replacement = "ł|Ł";
            break;
        }
        case 'n': {
            replacement = "ń|ň|ñ|Ń|Ň|Ñ";
            break;
        }
        case 'o': {
            replacement = "ò|ó|ô|õ|ö|ō|ŏ|ő|ø|Ò|Ó|Ô|Õ|Ö|Ō|Ŏ|Ő|Ø|Œ";
            break;
        }
        case 'r': {
            replacement = "ř|®|Ř";
            break;
        }
        case 's': {
            replacement = "š|ş|ș|ß|Š|Ş|Ș";
            break;
        }
        case 'u': {
            replacement = "ù|ú|û|ü|ũ|ū|ŭ|ů|Ù|Ú|Û|Ü|Ũ|Ū|Ŭ|Ů";
            break;
        }
        case 'y': {
            replacement = "ý|ÿ|Ý|Ÿ";
            break;
        }
        case 'z': {
            replacement = "ž|ż|ź|Ž|Ż|Ź";
            break;
        }
        }
        if (!replacement.isEmpty()) {
            charactersProcessed = charactersProcessed + c;
            newText = newText.replace(c + "", "(" + c + "|" + replacement + ")");
        }
    }

    return newText;
}