设为首页 收藏本站
查看: 1367|回复: 0

[经验分享] mysql 插入中文报错: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect dat

[复制链接]

尚未签到

发表于 2017-12-12 07:35:00 | 显示全部楼层 |阅读模式
  总结写在前面,

总结:
  当Java通过jdbc链接mysql插入中文时,要保证程序可以正常执行,而且插入的中文不会乱码,


  • mysql服务器端,对数据表(不是数据库)的编码设置,要保证是支持中文的,例如gbk, gb2312, utf-8
  • jdbc的连接配置,要开启useUnicode=true,并且要设置一个支持中文的编码,不需要跟mysql表的编码保持一致,只需要支持中文就行。例如characterEncoding=utf8
  • 本身的Java文件的编码需要支持中文
  =============================================================================
  刚学习JDBC,今天在调试代码的时候发现明明在公司的时候还能正常执行的插入语句,回来就不行了,测试代码是这样的。
  数据库配置文件 mysql.ini
  

driver=com.mysql.jdbc.Driver  

url=jdbc:mysql://127.0.0.1:3306/dedecms  
user=root
  
pass=
  

  测试代码
  

package db;  

  
import java.io.FileInputStream;
  
import java.io.FileNotFoundException;
  
import java.io.IOException;
  
import java.sql.Connection;
  
import java.sql.DriverManager;
  
import java.sql.SQLException;
  
import java.sql.Statement;
  
import java.util.Properties;
  


  
public>  
     private String driver;
  
     private String url;
  
     private String user;
  
     private String pass;

  
     public void initParam(String paramFile) throws FileNotFoundException, IOException,>  
         Properties prop = new Properties();
  
         prop.load(new FileInputStream(paramFile));
  
         driver = prop.getProperty("driver");
  
         url = prop.getProperty("url");
  
         user = prop.getProperty("user");
  
         pass = prop.getProperty("pass");

  
        >  
     }
  
     
  
     public int insertData(String sql) throws SQLException {
  
         try (
  
                 Connection conn = DriverManager.getConnection(url, user, pass);
  
                 Statement stmt = conn.createStatement()) {
  
             return stmt.executeUpdate(sql);
  
         }
  
     }
  
     

  
     public static void main(String[] args) throws FileNotFoundException,>  
         Test t = new Test();
  
         t.initParam("mysql.ini");
  
         t.insertData("insert into jdbc_test (jdbc_name, jdbc_desc) values ('测试标题','测试内容');");
  
         System.out.println("ok");
  
     }
  

  
}
  

  本来在公司还能执行的,拿回家新建了数据库,就不行了,报错如下,
  

Exception in thread "main" com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect string value: '\xCE\xE4\xBA\xBA\xB5\xD8...' for column 'jdbc_name' at row 1  
     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3513)
  
     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)
  
     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)
  
     at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)
  
     at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2548)
  
     at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1605)
  
     at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1524)
  
     at db.ExecuteSQL.insertData(ExecuteSQL.java:47)
  
     at db.ExecuteSQL.main(ExecuteSQL.java:119)
  

  考虑到插入了中文,在网上搜索了mysql的jdbc的url配置方法
  

url=jdbc:mysql://127.0.0.1:3306/dedecms?useUnicode=true&characterEncoding=utf8  

  即需要开启useUnicode=true并设置一种字符集,但是发现设置之后还是会出现上面的错误,于是又尝试修改了Eclipse文档的字符集,
  即在preferences->general->workspace->text file encoding下选择UTF-8,使java文件与jdbc链接配置的编码一致,
DSC0000.png

  然而发现这么设置之后,已然会出现上面的问题,想想大概是mysql数据库本身的设置不对,于是又更改下面的配置(用的phpMyAdmin做mysql客户端)
  找到我当前的数据库,将排序规则改为了 utf8_unicode_ci
DSC0001.png

  再次执行程序,发现问题依然存在,于是又折腾了半天,发现不仅仅是数据库可以修改排序规则,单个表格也可以修改排序规则,
  将表格的排序规则也改成 utf8_unicode_ci ,并且勾选 Change all column collations ,
DSC0002.png

  再次执行程序,终于可以看到数据正常插入了!
  程序测试结果,
DSC0003.png

  表内容
DSC0004.png

  不过后来又发现一个有趣的事情,就是无论mysql服务器的表设置为什么编码,只要在jdbc链接的时候也选择同样的编码,程序就可以执行成功,
  只不过如果编码不支持中文的话,数据表里就会出现乱码,例如这样,
  mysql数据表是拉丁编码
DSC0005.png

  mysql链接字符串也用拉丁编码
  

url=jdbc:mysql://127.0.0.1:3306/dedecms?useUnicode=true&characterEncoding=latin1  

  java文件编码默认
DSC0006.png

  然后发现可以执行,
DSC0007.png

  但是数据表里全是乱码,
DSC0008.png

  而一旦将数据表里的编码修改成支持中文的编码,比如gb2312
DSC0009.png

  并且将mysql jdbc的链接也修改成支持中文的编码, gb2312, gbk, utf8中的任何一个都行,并不需要跟数据表编码一致,
  

url=jdbc:mysql://127.0.0.1:3306/dedecms?useUnicode=true&characterEncoding=utf8  

  当然,eclipse的文件编码也必须支持中文(否则根本无法保存含有中文的文件),比如utf-8
DSC00010.png

  这样的话,就能正常执行程序,而且插入数据表的中文也不会乱码了
DSC00011.png

  所以,在创建表的时候顺便指定字符集是很重要的,像这样,
  

create table jdbc_test (jdbc_id int auto_increment primary key,  jdbc_name varchar(255), jdbc_desc text) DEFAULT CHARSET=utf8;  


总结:
  当Java通过jdbc链接mysql插入中文时,要保证程序可以正常执行,而且插入的中文不会乱码,


  • mysql服务器端,对数据表的编码设置,要保证是支持中文的,例如gbk, gb2312, utf-8
  • jdbc的连接配置,要开启useUnicode=true,并且要设置一个支持中文的编码,不需要跟mysql表的编码保持一致,只需要支持中文就行。例如characterEncoding=utf8
  • 本身的Java文件的编码需要支持中文
  ps:
  关于这个问题,今天在CSDN上看到一个喜欢钻研的人,研究了一下jdbc数据传输过程(tcp),并做了抓包分析,颇有帮助,
  http://blog.csdn.net/dslztx/article/details/47070475

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423201-1-1.html 上篇帖子: Mysql通信协议 下篇帖子: MySQL interval()函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表