数据库独立字符串与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);
请注意,代码大致完成。