mysql jdbc url指定字符集_JDBC中连接数据库时,若未指定useUnicode=true,那么采用的字符集是什么?...

为了你这个问题 我研究了一天 最后发现useUnicode=true&characterEncoding=utf8这句话仅仅把character_set_client和character_set_connection的值改为了utf8 而这种修改是会话范围内的 也就是说不是全局范围 这种修改仅仅是一次性的 对其他链接无影响

而经过SHOW SESSION VARIABLES LIKE 'character\\_set\\_%' 命令并且打印结果发现(这条命令就是查询会话范围内各个字符集的值) 结果发现 如果useUnicode=true&characterEncoding=GBK 那么character_set_client和character_set_connection的值会变为GBK 而character_set_results为空(通过官方文档可以 发现 为空则表示默认值 默认值为utf8mb4)

而useUnicode=true&characterEncoding=UTF-8或者干脆不写这句话 查询到的结果都是一样的 也就是character_set_client和character_set_connection的值都是utf8 character_set_results为空

我可能是全网第一个把这个问题说的这么透的 为了这个问题 我百度谷歌了一天 完全没有任何可靠回答 然后我在mysql官方文档中看到了SHOW SESSION VARIABLES LIKE 'character\\_set\\_%' 命令 官方文档说这个命令能查询到当前会话的所有字符集 然后我通过亲身实验 得出了结果 我的mysql版本为5.5 其他版本是什么结果暂时未知

----------------------------------2020.7.11补充更正-------------------------------------

今天再次研究jdbc 使用数据库为mysql 研究结果如下 无论useUnicode=true&characterEncoding=UTF-8或者gbk 数据库返回的结果都是utf-8编码的或者ascii编码(后面会说到) 所以这个选项完全没有影响数据库的返回结果的字符集 影响的只是从客户端发送SQL语句时的字符集 也就是说jdbc会通知mysql数据库使用某个字符集发送 然后mysql数据库会用某种字符集来解码 然而客户端的编码过程是jdbc来完成的 所以理论上说永远不会乱码 因为客户端会和mysql服务器使用相同的字符集来编码和解码

通过一步步加断点再debug深入研究 可以发现 数据库返回的结果中会带有编码方式 如果返回的结果在数据库中是varchar类型则使用utf-8编码 如果返回的结果在数据库是int或者float类型 那么编码为ascii

给大家上个图 看一下就清楚了 这张图是ResultSet结果集的getString方法中的debug值

这是返回的某个查询结果 在debug页面的展示 其中共有七行 对应着数据库中某个表的七列

其中1,2,3,6列在数据库中均为varchar类型 4,5,7列在数据库中均为int或float类型

对应到debug结果可以看出 凡是varchar类型 数据库返回的查询结果会指定charsetName=utf-8 而凡是int或者float类型均指定为了US-ASCII 即我们平时说的ascii码

当然我们可以发现在charsetName前面还有一个charsetIndex 在ResultSet结果集的getString方法后面会对这个值进行判断 如果为63 则使用后面的charsetName解码 如果不是则使用character_set_connection编码进行解码 而character_set_connection的值即为我们之前useUnicode=true&characterEncoding设置的值 到此 我们才发现useUnicode=true&characterEncoding这句话到底有什么意义 如果我们在数据库中使用int类型或者float类型存储字符串 那么解码的时候会使用useUnicode=true&characterEncoding=***来解码 我们平时都是使用varchar类型在数据库存储字符串 所以useUnicode=true&characterEncoding=***这句话完全没有意义 反正在jdbc mysql下是无意义的 所以URL中完全不需要加这句话 加这句话完全是以讹传讹 其实大家根本就没懂这句话到底干了什么

简单总结:URL加与不加useUnicode=true&characterEncoding=***完全不会造成乱码 起码用jdbc连接mysql是这样 反过来说 如果项目乱码 绝对不是因为这件事 因为jdbc做了很多事情 它会正确处理与mysql服务器之间的编码 无需我们指定

而且加与不加这句话 不会影响mysql数据库返回结果的编码 mysql返回结果的编码永远为utf-8 不会受这句话影响

最后 加这句话完全没有必要 除非你在数据库中用int或者float存储了字符串 我相信不会有人真的这么做 百分之100的人都是使用varchar 这也是character_set_connection的意义所在 很多人质疑character_set_connection的作用 认为他是多余的 现在发现它的作用仅仅体现在使用int或者float存储字符串 然后解码的时候会使用这个字符集 所以看来它确实有些多余

-------------------补充-----------------

最近发现 有些时候加和不加 还是有区别的 我也懵逼了 既然 这样 就加吧 反正一句话的事 。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值