項目上線后,一直很穩定,后來加入了微信登錄后,有反饋說異常。排查得出結果是mysql插入的數據包含表情。特此記錄下。
首先分析為什么會出現這樣的情況,原因在于我們的評論數據中存在emoj表情,而這些表情是按照四個字節一個單位進行編碼的,而我們通常使用的utf-8編碼在mysql數據庫中默認是按照3個字節一個單位進行編碼的,正是這個原因導致將數據存入mysql數據庫的時候出現錯誤,那么這個問題我們應該怎么解決呢?
-
mysql數據修改
- 檢查數據庫編碼是不是uft8mb4
- 檢查表內的要存儲的字段是不是uft8mb4
- 手動sql插入條帶表情的數據是不是成功。
-
修改springboot配置文件
- 如果是用的默認配置的話,那么需要在applciation.yml中增加如下:
spring:
datasource:
url: jdbc:mysql://XXX:3306/XXX?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
username: root
password: root #
tomcat:
init-s-q-l: SET NAMES utf8mb4 //這是最重要的一步
- 如果是使用的數據庫連接池,那么需要手動配置。如Druid:
@Bean //聲明其為Bean實例
@Primary //在同樣的DataSource中,首先使用被標注的DataSource
public DruidDataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
String connectionInitSqls = "SET NAMES utf8mb4";
StringTokenizer tokenizer = new StringTokenizer(connectionInitSqls, ";");
//重點設置該參數
datasource.setConnectionInitSqls(Collections.list(tokenizer));
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
System.err.println("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}