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

我正在使用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-Database,我会得到一个NonUniqueResultException ,因为默认情况下mySQL数据库正在进行不区分大小写的比较。 强制mySQL的常用方法是编写一个类似的查询

 SELECT 'abc' LIKE BINARY 'ABC'; 

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

我的第一次尝试是在课堂上注释字段name

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

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

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

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

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

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

似乎没有办法配置JPA来解决这个问题。 但我发现,不仅可以在表级别设置排序规则,还可以按照参考手册12.1.10 CREATE DATABASE SYNTAX和9.1.3.2中的规定为整个数据库设置排序规则。 数据库字符集和校对

 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”,当我查询其中一个时,我只会收到一个。

但是,谢谢你的帮助

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

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

请注意,代码大致完成。