最近在处理微信数据时,出现如下的错误:
ERROR[12-02 11:11:57]cn.hl.basic.datapersist.DbBasicService.execSql(DbBasicService.java:632): java.sql.SQLException: Incorrect string value: '\xF0\x9F\x8D\xAC",...' for column 'user_info' at row 1
错误是在获取微信用户信息后,插入数据库时发生的,基本可以判断是微信用户名中有特殊字符,所以导致数据插入不了
在网上也找资源半天,说是编码问题,需要调整编码为utf8mb4,但看了数据库这个字段的编码,却就是utf8mb4的,又看了些文章,网上有说要改MySQL服务端的编码,也就是修改配置,然而服务器的配置不是那么好动的,现在运行的项目有很多。
是否是我连接的时候编码就指定错了,或是可以通过连接URL来指定呢?这样想着,查看了MySQL的连接URL,目前的如下:
jdbc:mysql://ipandport/dbname?useOldAliasMetadataBehavior=true&autoReconnect=true&failOverReadOnly=false&characterEncoding=utf8
不是说使用utf8mb4吗?这里用的utf8,会影响吗?是这个问题吗?带着问题,又查看了网上的资料,
明白了一个问题,这些乱码是微信中的表情符,这些表情符是占4个字节的,而utf8却三个字节的,如果在连接URL中指定characterEncoding=utf8的话,那么他写入数据时就按照3个字节写入了,那肯定写不进去的,有不指定写入字节,按照本身的字符的字节来写吗?
有!!!就是useUnicode参数,设置为useUnicode=true,那么在写入数据时,会根据数据本身的字节来写,好吧,明白了问题的原因,果断试下,果然不出所料,实践证明了预想的结论。
说明:useUnicode的作用:
当设置useUnicode=true时,数据在存入数据库时会根据数据库字段的编码进行转换后,再存储。所以数据库的编码设置为utf8mb4,那么存储肯定没啥问题了。
正确的配置如下:
jdbc:mysql://ipandport/dbname?useOldAliasMetadataBehavior=true&autoReconnect=true&failOverReadOnly=false&userUnicode=true
以下为再网上查询的一些资料,放在这里,以供参考:
http://ourmysql.com/archives/1402
http://www.jianshu.com/p/20740071d854
网上还说了另一种方案,就是在知道会有这样字符的字段时,统一对其进行转码,比如转成base64的存入到数据库,取出时再统一转码,但是对于之前数据库中已经存在历史大量的数据,操作是很麻烦的,还要去刷数据,所以在连接指定字符是最简单可行的方法。
另外说下,对于有这样的字符,插入到数据库中的时候会变成?,不用担心,取出来后数据还是可以还原的。