【问题标题】:Insert emoji does not work with spring-boot and MariaDB插入表情符号不适用于 spring-boot 和 MariaDB
【发布时间】:2018-06-22 02:03:47
【问题描述】:

我想插入表情符号,例如 ????在 mariaDB 数据库中,但我总是得到一个 sql 错误。

这是堆栈跟踪:

12-01-2018 16:01:44.466 [Executor - Migration - 1] WARN  o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions:129 - SQL Error: 1366, SQLState: 22007
12-01-2018 16:01:44.466 [Executor - Migration - 1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions:131 - (conn:498) Incorrect string value: '\xF0\x9F\x92\xB3\xF0\x9F...' for column 'notes' at row 1
Query is: insert into customer (backend_archiving_date, backend_creation_date, backend_update_date, genius_client_id, address, birthday, city, company_name, country, email, fidelity_account_id, first_name, last_name, notes, phone, siret, zip_code, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?), parameters [<null>,'2018-01-12 15:01:44.454','2018-01-12 15:01:44.454',2159,'20 rue raspail
',<null>,'LEVALLOIS PERRET','','FRANCE','','00c55854-99df-4db1-88b9-34f7e5608477','claude','amsellem','????????????????','','','92300','2152ed7d-80a1-4305-9fcb-4e21f5947e32']

我的 Maria db,表有

ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

并且“notes”字段也有“utf8mb4 - Unicode”字符集。

当我通过 sql 查询插入时

update customer set notes='????????????????' where id = 'f5920301-5ee0-4d58-a786-d4701d9e9d73';

它可以工作,但是当我想用我的程序(spring-boot、spring-data-jpa、hibernate)插入表情符号时,我总是会收到错误消息(请参阅堆栈跟踪)。

编辑

仅供参考,这是创建脚本

CREATE TABLE `customer` (
`id` char(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`first_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`phone` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`email` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`birthday` date DEFAULT NULL,
`notes` varchar(2048) DEFAULT NULL,
`address` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`city` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`country` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`zip_code` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`company_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`siret` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`fidelity_account_id` char(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`backend_creation_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`backend_update_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`backend_archiving_date` timestamp NULL DEFAULT NULL,
`genius_client_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `fk_customer_fidelity_account` (`fidelity_account_id`),
CONSTRAINT `fk_customer_fidelity_account` FOREIGN KEY (`fidelity_account_id`) REFERENCES `fidelity_account` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

编辑 2

这里是连接参数(spring-boot application.yml)

# Datasource configuration
spring:
  datasource:
    type: "com.zaxxer.hikari.HikariDataSource"
    url: "jdbc:mariadb://localhost:3306/genius_back useUnicode=yes&characterEncoding=UTF8"
    hikari:
      driver-class-name: "org.mariadb.jdbc.Driver"
      username: "mariadb"
      password: "mariadb"
      minimum-idle: 5
      maximum-pool-size: 20
      validation-query: "SET NAMES utf8mb4"
  jackson:
     serialization:
      write_dates_as_timestamps: false
  http:
     client-user-agent: "Genius"
     multipart:
      max-file-size: 100Mb
      max-request-size: 150Mb

【问题讨论】:

    标签: spring-boot utf-8 mariadb utf8mb4


    【解决方案1】:

    好的, 我发现了问题。

    解决方案是添加

    spring:
      datasource:
         connectionInitSql: "SET NAMES 'utf8mb4'" 
    

    在 application.yml 中。

    connectionInitSql 被 HikariCP 在打开连接时使用。

    【讨论】:

    • 那么,“验证查询”是否应该去掉?
    • 是的,可以删除。我删除了它并且它有效。谢谢瑞克。
    【解决方案2】:

    spring-boot2.0.0.RC2

    mysql5.7.14

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    
    
    Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\xAD' for column 'title' at row 1
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2079)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2013)
    at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5104)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1998)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)
    ... 68 more
    

    spring.datasource.connectionInitSql 不适合我

    我看到了 hikari.pool

    那就试试

    spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
    

    效果不错

    spring.datasource.hikari.connection-init-sql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
    

    参考https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby

    【讨论】:

      【解决方案3】:

      对于嵌入 tomcat 的 Spring boot:

      spring.datasource.tomcat.initSQL = SET NAMES 'utf8mb4'

      【讨论】:

        【解决方案4】:

        连接时,将字符集设置为 utf8mb4。请提供连接详情。

        在表中的列上使用 utf8mb4。请提供SHOW CREATE TABLE,以便我们验证,而不仅仅是表默认是utf8mb4。

        【讨论】:

        • 我添加了创建脚本。请注意,我可以使用update customer set notes='????' where id = 'f5920301-5ee0-4d58-a786-d4701d9e9d73'; 之类的 sql 查询添加表情符号,因此这不是数据库问题。问题可能出在 spring/hibernate 级别...?
        猜你喜欢
        • 2017-04-12
        • 2018-10-07
        • 2016-04-29
        • 2017-06-30
        • 2020-05-25
        • 1970-01-01
        • 2017-06-24
        • 2019-09-15
        • 1970-01-01
        相关资源
        最近更新 更多