数据库独立字符串与JPA的比较

时间:2011-09-30 10:28:06

标签: java mysql jpa jpql

我正在使用JPA(Hibernate作为提供者)和基础MySQL数据库。

我有一张桌子,里面有德国街道的每个名字。每个街道名称都有一个唯一的编号。对于一项任务,我必须找出名称的编号。为此,我编写了一个JPQL-Query,如下所示

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

不幸的是,德国的街道名称只有“Am kleinen Feld”和“Am Kleinen Feld”等小写和大写字母不同。显然其中一个是错误的,但作为街道的名称,两种拼写都是允许的,并且两者都有不同的数字。

当我将JPQL-Query发送到数据库时,我正在使用

query.getSingleResult();

因为表中的每个街道名称都是唯一的。但是对于底层的MySQL数据库,我会得到NonUniqueResultException,因为默认情况下mySQL数据库正在进行不区分大小写的比较。强制mySQL的常用方法是编写类似

的查询
SELECT 'abc' LIKE BINARY 'ABC';

如mySQL参考手册中的第11.5.1节所述,但JPQL中没有相应的关键字。

我的第一次尝试是使用

对类中的字段name进行注释
@Column(nullable = false, columnDefinition = "varbinary(128)")

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

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

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

3 个答案:

答案 0 :(得分:1)

要像对数据库和JPA提供程序所说的那样保持“独立”,我会避免使用getSingleResult()并获取list()并在内存中匹配名称。可能你会获得不止一个而不是100个或更多。

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

答案 1 :(得分: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

我只需要用:

创建数据库
CREATE DATABASE db_name CHARACTER SET latin1 COLLATE latin1_general_cs;

有了这个,我可以在字段name上放置一个uniqueConstraint并插入“Am kleinen Feld”和“Am Kleinen Feld”,当我查询其中一个时,我只会收到一个。< / p>

但是,感谢您的帮助

答案 2 :(得分:0)

您还要编写SQL个查询。这就像一个普通的查询:

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

请注意,代码大致完成。