我正在使用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配置为进行区分大小写的字符串比较,而无需手动微调数据库?
答案 0 :(得分:1)
要像对数据库和JPA提供程序所说的那样保持“独立”,我会避免使用getSingleResult()并获取list()并在内存中匹配名称。可能你会获得不止一个而不是100个或更多。
另一种方法是将名称标准化(修剪,小写)保存在新字段中。
答案 1 :(得分:1)
似乎没有办法配置JPA来解决这个问题。但我发现,不仅可以在表级设置排序规则,还可以按照Reference Manual 12.1.10 CREATE DATABASE SYNTAX和9.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);
请注意,代码大致完成。