2011-09-30 81 views
4

我正在使用JPA(Hibernate作为提供程序)和基础MySQL数据库。独立于字符串的数据库与JPA的比较

我有一个包含德国街道名称的表格。每个街道名都有唯一的编号。对于一项任务,我必须找出名称的编号。要做到这一点,我写了一个JPQL查询像下面

"SELECT s FROM Strassencode s WHERE s.name = :name" 

不幸的是在德国的街道名称,只有在像“AM kleinen菲尔德”和“AM Kleinen菲尔德”小型大写字母不同。显然,其中一个是格式错误的,但作为一个街道的名称,两个拼写都是允许的,而且他们都有不同的编号。

当我将JPQL查询发送到数据库中,我使用

query.getSingleResult(); 

因为事实上,该表中的每一streetname是独一无二的。但是对于底层的MySQL数据库,我会得到一个NonUniqueResultException,因为默认情况下,mySQL数据库正在进行不区分大小写的比较。以强制MySQL的常用方法是编写一个查询类似

SELECT 'abc' LIKE BINARY 'ABC'; 

为discribed在MySQL参考手册中的章节11.5.1,但在JPQL没有相应的关键字。

我第一次尝试是annotade领域name在类

@Column(nullable = false, columnDefinition = "varbinary(128)") 

注释这样,数据库会自动做一个区分大小写的比较,因为字符串之一是二进制的。但是当我使用这个解决方案时,当我从数据库中读取名字时,遇到了麻烦,将它们写入文件,因为ä,ö,ü等字母被解释为错误。

我知道,字段name应该得到一个uniqueConstraint,这是我的目标之一,但这只有在数据库将执行区分大小写的字符串比较时才有可能。

是否有解决方案,我可以配置JPA进行区分大小写的字符串比较而不必手动微调数据库?

回答

1

似乎没有办法配置JPA来解决此问题。但我发现的是,它是可以设置的排序规则不仅在表级,您还可以将其设置为整个数据库作为Reference Manual 12.1.10 CREATE DATABASE SYNTAX9.1.3.2. Database Character Set and Collation

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name 
[create_specification] ... 

create_specification: 
    [DEFAULT] CHARACTER SET [=] charset_name 
    | [DEFAULT] COLLATE [=] collation_name 

我只需要创建discribed与数据库:

CREATE DATABASE db_name CHARACTER SET latin1 COLLATE latin1_general_cs; 

有了这个,我可以把场上name一个的UniqueConstraint,插入两个“AM kleinen菲尔德”和“AM Kleinen菲尔德”当我查询其中的一个,我只接收一个。

但是,感谢您的帮助

1

要像数据库和JPA提供程序那样保持“独立”,我会避免getSingleResult()并获取列表()并在内存中匹配名称。可能你会得到超过一个,但不是100或更多。

另一种方法可以将名称标准化(修剪,小写)保存在新字段中。

+0

当我归街道的名字,然后我有更多的事实,这两个名字是相同或不? “Am kleinen Feld”和“Am Kleinen Feld”正常化会将它们变成“amkleinenfeld”,但仍然有不同的数字。 – Turbokiwi

+0

你说“表中的每个街道名都是独一无二的”。有一条街道可能会写“银河”或“银河系”,但你的分贝只有其中之一。当“银河系”在你的分贝时,你不能再添加“银河系”了吧? – PeterMmm

+0

你的例子是可能的,因为在版本中包含一个空格,而另一个没有。但是当“银河系”已经在里面的时候,我希望能够插入“银河系”,而不是另一个“银河系”。而当我查询一个版本时,我只想收到一个结果。换句话说,我希望这个列的行为就像Java中的“Strings”的Set,其中''Milky Way“.equals(”Milky Way“)''为'false'。 – Turbokiwi

0

你也写了SQL查询。这就像一个正常的查询:

Query sqlQuery = session.createSqlQuery("select * from CITY where name like binary :name').addString('name', name); 

请注意,代码大致完成。

+1

使用原生querries我不再是数据库独立或您的建议ANSI符合?这对我来说不是一件“好事”。这可能是因为如果在几个月内必须切换到Oracle数据库,并且我不想在必要时更改代码。 – Turbokiwi

+0

然后我会去推荐PeterMmm。 – ssedano