简体   繁体   中英

Can't store UTF-8 Content in MySQL Using Java PreparedStatement

For some strange reason I can't seem to add UTF-8 data to my MySQL database. When I enter a non-latin character, it's stored as ?????. Everything else is stored fine. So for example, "this is an example®™" is stored fine, but "和英辞典" is stored as "????".

The connection url is fine:

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;
}

I'm using PreparedStatement as you would expect, I even tried entering "set names utf8" as someone suggested.

    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) {
    ...

The table itself seems to be fine.

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

I tested it by entering in Unicode ("和英辞典" specifically) through a GUI editor and then selecting from the table -- and it was returned just fine. So this seems to be an issue with JDBC.

What am I missing?

On your JDBC connection string, you just need set the charset encoding like this:

jdbc:mysql://localhost:3306/dbname?characterEncoding=utf8

Use stmt.setNString(...) instead of stmt.setString(...) .
Also don't forget to check column collation in database side.

There is 2 points in the mysql server to check in order to correctly set the UTF-8 charset.

Database Level

This is obtained by creating it :

CREATE DATABASE 'db' CHARACTER SET 'utf8';

Table Level

All of the tables need to be in UTF-8 also (which seems to be the case for you)

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

The important part being DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci

Finally, if your code weren't handling utf8 correctly, you could have forced your JVM to use utf8 encoding by changing the settings by on startup :

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

or changing the environment variable

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

or programmatically by using :

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

(this last one may not have the desire effect since the JVM caches value of default character encoding on startup)

Hope that helped.

If you log in to your mysql database and run show variables like 'character%'; this might provide some insight.

Since you're getting a one-to-one ratio of multi-byte characters to question marks then it's likely that the connection is doing a character set conversion and replacing the Chinese characters with the replacement character for the single-byte set.

Also check locale -a on ubuntu default Ubuntu works with en_us locale and doesn't have other locale installed. must specify characterEncoding=utf8 while connecting through JDBC.

添加到数据库连接的末尾url - (没有其他需要)ex。

spring.datasource.url = jdbc:mysql://localhost:3306/dbname?characterEncoding=utf8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM