2012-03-08 51 views
5

出于某种奇怪的原因,我似乎无法UTF-8的数据添加到我的MySQL数据库。当我输入一个非拉丁字符时,它被存储为?????。其他一切都存储正常。例如,“这是一个example®™”存储的很好,但“和英辞典”存储为“????”。不能存储在MySQL UTF-8的内容使用Java的PreparedStatement

连接URL是好的:

private DataSource getDB() throws PropertyVetoException { 
    ComboPooledDataSource db = new ComboPooledDataSource(); 
    db.setDriverClass("com.mysql.jdbc.Driver"); 
    db.setJdbcUrl("jdbc:mysql://domain.com:3306/db?useUnicode=true&characterEncoding=UTF-8"); 
    db.setUser("..."); 
    db.setPassword("..."); 
    return db; 
} 

我使用PreparedStatement的你所期望的,我甚至尝试进入“设置名称UTF8”有人建议。

Connection conn = null; 
    PreparedStatement stmt = null; 
    ResultSet rs = null; 
    try { 
     conn = db.getConnection(); 

     stmt = conn.prepareStatement("set names utf8"); 
     stmt.execute(); 
     stmt = conn.prepareStatement("set character set utf8"); 
     stmt.execute(); 

        ... set title... 
     stmt = conn.prepareStatement("INSERT INTO Table (title) VALUES (?)"); 
     stmt.setString(1,title); 

     stmt.execute(); 
    } catch (final SQLException e) { 
    ... 

表本身似乎要被罚款。

Default Character Set: utf8 
Default Collation: utf8_general_ci 
... 
Field title: 
Type text 
Character Set: utf8 
Collation: utf8_unicode_ci 

我通过输入以Unicode测试了它(“和英辞典”特异性)通过GUI编辑器,并从表中选择 - 和它返回就好了。所以这似乎是JDBC的一个问题。

我错过了什么?

+0

你确定'title'有正确的内容吗?也许你从一个使用ISO的文件读取它 - 无论什么? – 2012-03-08 22:11:26

+0

是的,当我在标题上放置一个断点时,我可以看到它确实是unicode(例如:和英辞典),而不是? – nostromo 2012-03-08 22:33:44

+0

'utf8'是一个字符串,所以用引号括起来:''set names'utf8'“'。不要混淆字符集。 – 2012-03-08 22:55:14

回答

3

有在MySQL服务器2分,以正确地设置UTF-8字符集进行检查。

数据库级

这是通过创建它获得:

CREATE DATABASE 'db' CHARACTER SET 'utf8'; 

表级

所有的表需要在UTF-8还(这似乎是你的情况下)

CREATE TABLE `Table1` (
    [...] 
) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 

的重要组成部分,是默认字符集= UTF8 COLLATE = utf8_general_ci

最后,如果你的代码不正确处理UTF-8,你可以迫使你的JVM通过在启动时更改设置使用utf8编码:

java -Dfile.encoding=UTF-8 [...] 

,或者使用改变环境变量

"**JAVA_TOOLS_OPTIONS**" to -Dfile.encoding="UTF-8" 

或编程:

System.setProperty("file.encoding" , "UTF-8"); 

(最后一个可能没有欲望的效果,因为在JVM上的高速缓存启动时默认的字符编码的值)

希望这有助于。

+0

设置jvm的默认编码对某些事情很有用,但肯定不需要将unicode数据导入和导出数据库。 – jtahlborn 2012-03-10 14:25:52

+0

根据nostromo昨天关于断点的评论。我们可以假设他的jvm已经正确地处理了unicode,所以我同意在他的情况下它不是必需的。 – Kharaone 2012-03-10 15:17:52

+0

实际上有三个层次。还有连接级别:http://stackoverflow.com/questions/9283575/getting-incorrectly-encoded-characters-when-retrieving-values-from-mysql-db – 2012-03-14 12:39:29

1

如果您登录到您的mysql数据库并运行show variables like 'character%'; 这可能会提供一些见解。

由于您将多字节字符与问号进行一对一的比例,因此很可能连接正在进行字符集转换,并用单字节的替换字符替换中文字符组。

5

在您的JDBC连接字符串,你只需要设置的字符集编码是这样的:

的jdbc:mysql的://本地主机:3306/DBNAME的characterEncoding = UTF8

3

使用stmt.setNString(...)而不是stmt.setString(...)
另外不要忘记检查数据库端的列整理。

+0

你节省了我的一天。 – 2017-10-27 02:09:48

0

还要检查Ubuntu的Ubuntu默认的工作与en_US环境和没有安装其他的语言环境locale -a命令。 必须在通过JDBC连接时指定characterEncoding = utf8。