我正在尝试使用Hibernate在MySQL数据库中保存一些值,但大多数立陶宛字符都不会被保存,包括ąĄ čČ ęĘ ėĖ įĮ ųŲ ūŪ
(它们保存为?
),但是,{{ 1}}得到保存。
如果我手动插入,那么这些值会被正确保存,因此问题很可能出现在Hibernate配置中。
到目前为止我尝试过:
šŠ žŽ
如上所述here
我尝试将hibernate.charset=UTF-8
hibernate.character_encoding=UTF-8
hibernate.use_unicode=true
---------
properties.put(PROPERTY_NAME_HIBERNATE_USE_UNICODE,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_USE_UNICODE));
properties.put(PROPERTY_NAME_HIBERNATE_CHARSET,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARSET));
properties
.put(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING));
---------
private void registerCharachterEncodingFilter(ServletContext aContext) {
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setForceEncoding(true);
cef.setEncoding("UTF-8");
aContext.addFilter("charachterEncodingFilter", cef)
.addMappingForUrlPatterns(null, true, "/*");
}
添加到数据库连接网址。
如上所述here
我确保我的数据库设置为UTF-8字符集。 ?useUnicode=true&characterEncoding=utf-8
phpmyadmin > information_schema > schemata
这是我保存到db:
的方式def db_name utf8 utf8_lithuanian_ci NULL
第一组println包含所有立陶宛字符,而第二组用//Controller
buildingService.addBuildings(schema.getBuildings());
List<Building> buildings = buildingService.getBuildings();
System.out.println("-----------");
for (Building b : schema.getBuildings()) {
System.out.println(b.toString());
}
System.out.println("-----------");
for (Building b : buildings) {
System.out.println(b.toString());
}
System.out.println("-----------");
//Service:
@Override
public void addBuildings(List<Building> buildings) {
for (Building b : buildings) {
getCurrentSession().saveOrUpdate(b);
}
}
取代最多
编辑:添加了详细信息
?
编辑:
我找不到合适的解决方案,所以我想出了一个解决方法。我最终逃脱/取消了角色,将它们存储起来:insert into buildings values (11,'ąĄčČęĘ', 'asda');
select short, hex(short) from buildings;
//Šalt. was inserted via hibernate
//letters are properly displayed:
ąĄčČęĘ | C485C484C48DC48CC499C498
MIF Šalt. | 4D494620C5A0616C742E
select address, hex(address) from buildings;
Šaltini? <...> | C5A0616C74696E693F20672E2031412C2056696C6E697573
//should contain "ų"
--------
show create table buildings;
buildings | CREATE TABLE `buildings` (
`id` int(11) NOT NULL,
`short` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL,
`address` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_lithuanian_ci
。
答案 0 :(得分:3)
让我们验证它们是否存储正确...请执行SELECT col, HEX(col) ...
以获取具有立陶宛字符的单元格。正确存储的ą
将显示C485
。其他应显示C4xx或C5xx的各种十六进制值。 3F
为?
。
但是,更重要的是,确实显示了4个字符。如果正确存储为utf8,则Š
应为C5A0
。但是,我怀疑,您会看到8A
,这意味着表中的列实际上已声明为CHARACTER SET latin1
。 (4个字符显示在my charset blog的第一列中。)
执行SHOW CREATE TABLE
以查看列的定义方式。如果它显示latin1
,那么问题在于表定义,你可能应该重新开始。
答案 1 :(得分:0)
您必须确保参与数据录入的每个组件都明确使用 UTF-8 编码。
如果您通过浏览器输入值,请确保
使用以下标题显示结果的页面
Content-Type: text/html; charset=utf-8
。
输入表格定义如下
<form action="submit" accept-charset="UTF-8">...</form>
。
如果要从字节数组创建String
个对象,请确保
明确说明构造函数中的Charset
。
如果您的条目来自文本文件,则该文件必须为 UTF-8 编码。
如果它直接在您的代码中进行硬编码,那么源必须是 UTF-8 编码。
答案 2 :(得分:0)
您的数据库保存正确的UTF-8(特殊字母的两个或更多字节)这一事实令人放心。
如果您为特殊字母获得一个?
,则会尝试将UTF-8转换为某些不包含这些字母的编码。 似乎就是这种情况。 正确转换的字母位于 ISO-8859-1 或 Windows-1252 范围内。其他人不是。
现在ISO-88591-1 aka Latin-1是默认的HTTP编码,在java EE服务器中是默认的。你可能喜欢在写作之前做:
response.setCharacterEncoding("UTF-8");
现在System.out.println
的一个问题是它使用系统默认编码。使用记录器记录到文件更有趣。或者调试并检查String及其char数组。
架构看起来似乎有效,可能是架构字符串直接来自Java源,编辑器编码和javac编译器编码不同。这可以通过u-evcaping java中的字符串文字来检查:"\u0105"
而不是"ą"
。
进行从数据库写入和读取的单元测试。