mysql从安装到建库,utf8mb4最佳实践,jdbc连接串全解析

我现在用的是mysql5.7,操作系统centos

配置YUM源

下载mysql源安装包

[root@VM_0_9_centos software]# wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm

安装mysql源

[root@VM_0_9_centos software]# yum localinstall mysql57-community-release-el7-8.noarch.rpm

安装MySQL

[root@VM_0_9_centos software]# yum localinstall mysql57-community-release-el7-8.noarch.rpm

启动mysql

systemctl start mysqld

启动完了之后,查看mysql状态

systemctl status mysqld

开机启动mysql

[root@VM_0_9_centos software]# systemctl enable mysqld
[root@VM_0_9_centos software]# systemctl daemon-reload

修改root本地登录密码
ysql安装完成之后,在/var/log/mysqld.log文件中给root生成了一个默认密码。通过下面的方式找到root默认密码,然后登录mysql进行修改:

[root@VM_0_9_centos software]# grep 'temporary password' /var/log/mysqld.log
2018-06-16T08:05:45.944135Z 1 [Note] A temporary password is generated for root@localhost: oOo;3qdZL0sq
shell> mysql -uroot -poOo;3qdZL0sq
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';
  • 注意:mysql5.7默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位。否则会提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements错误*

####添加远程登录用户
默认只允许root帐户在本地登录,如果要在其它机器上连接mysql,必须修改root允许远程连接,或者添加一个允许远程连接的帐户,为了安全起见,我们添加一个新的帐户glowd,并且允许所有的ip地址远程访问:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'glowd'@'%' IDENTIFIED BY 'glowd7^&!'

配置默认编码为utf8mb4

最新的mysql数据库默认编码已经是utf8mb4,这能避免很多不必要的问题。
修改/etc/my.cnf配置文件,最终的配置如下

[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'

然后重启一下mysql

systemctl restart mysqld

然后登录mysql,查看是否此时编码是正确的

[root@VM_0_9_centos software]# mysql -uglowd -p

mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

显示结果如下,即为正确

| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8mb4_unicode_ci         |
| collation_database       | utf8mb4_unicode_ci         |
| collation_server         | utf8mb4_unicode_ci         |
+--------------------------+----------------------------+

说明

collation_connection ,collation_database ,collation_server是什么没关系。

但必须保证

系统变量                         描述
character_set_client    (客户端来源数据使用的字符集)
character_set_connection    (连接层字符集)
character_set_database    (当前选中数据库的默认字符集)
character_set_results    (查询结果字符集)
character_set_server    (默认的内部操作字符集)
这几个变量必须是utf8mb4。

常见问题解决,以及最佳实践

建库-建表

建库
CREATE SCHEMA `test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ;
why utf8mb4

http://www.jianshu.com/p/df1523bc67cd

utf8mb4占4个字节,可以保存包括emoji表情在内的很多特殊字符
utf8占3个字节,可以保存绝大部分字符
但是为了更好的兼容所有此类字符,建议全部使用utf8mb4,避免为未来程序的扩展升级埋坑

why utf8mb4_unicode_ci not utf8_general_ci

https://*.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci

在字符校验上面,utf8_unicode_ci比较准确,utf8_general_ci速度比较快,但是对于现代CPU来说,性能可以忽略。但是对于越来越国际化的我们来说,utf8_unicode_ci更占优势

why ci not utf8mb4_bin

ci: case insensitive, 即 “大小写不敏感”, 如果查询的时候,数据库中用户名Glowd,但是用户输入glowd,一样能查出这个用户。
bin: 将字符串中的每一个字符用二进制数据存储,区分大小写

建库的时候,一定要声明CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ;这个会是建表以及字段的默认字符集以及校验规则。如果建库的时候加了,那么建表和字段的时候都可以不加,默认就是
建表
CREATE TABLE `health_package` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '序号',
  `package_id` int unsigned NOT NULL COMMENT '套系 id',
  `module_id`  int unsigned NOT NULL COMMENT '模块 id',
  `is_delete` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否删除,0-未删除,1-删除,默认为0',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Create time, common column by DB rules',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Modified time,common column by DB rules ',
  PRIMARY KEY (`id`)
)  COMMENT='This table stores module and package of health for ...';
如果建库的时候加了CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,在建表或者字段的时候一定不要加了。因为如果你加了DEFAULT CHARSET=utf8mb4,那么mysql会自动将COLLATE变为utf8_general_ci。这个不是我们所希望的。

为了使用utf8mb4还需要这些条件

  • 对于 JDBC 连接,需要使用 MySQL Connector/J 5.1.13(含)以上的版本。
  • JDBC 的连接串中,建议不配置 characterEncoding 选项。后面有解释
  • 确保 mysql进程character_set_server 参数为 utf8mb4
  • 通过“set names utf8mb4”命令设置会话字符集为 utf8mb4
那么需要在开启一个会话的时候,首先执行一个“set names utf8mb4“命令
首先可以在/etc/my.cnf中添加一行配置init_connect='SET NAMES utf8mb4'
或者如果使用的是com.alibaba.druid.pool.DruidDataSource连接池,那么可以加一个属性<property name="connectionInitSqls" value="set names utf8mb4;"/>

mysql JDBC Driver

mysql JDBC URL格式如下:

jdbc:mysql://[host:port],[host:port]…/database=参数值1[=参数值2]…

现只列举几个重要的参数:

参数名称 参数说明 缺省值 最低版本要求
user 数据库用户名(用于连接数据库) 所有版本
password 用户密码(用于连接数据库) 所有版本
useUnicode 是否使用Unicode字符集,如果参数characterEncoding设置为utf-8,本参数值必须设置为true false 1.1g
characterEncoding 当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk false 1.1g
autoReconnect 当数据库连接异常中断时,是否自动重新连接?mysql默认连接如果超过8小时就会断开,此参数可以自动重连 false 1.1
autoReconnectForPools 是否使用针对数据库连接池的重连策略 false 3.1.3
failOverReadOnly 自动重连成功后,连接是否设置为只读? true 3.0.12
maxReconnects autoReconnect设置为true时,重试连接的次数 3 1.1
initialTimeout autoReconnect设置为true时,两次重连之间的时间间隔,单位:秒 2 1.1
connectTimeout 和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时,适用于JDK 1.4及更高版本 0 3.0.1
socketTimeout socket操作(读写)超时,单位:毫秒。 0表示永不超时 0 3.0.1

我们通常的jdbc url

jdbc:mysql://localhost:3306/glowd?useUnicode=true&characterEncoding=utf-8&autoReconnect=true

在xml配置文件中,url中的&符号需要转义成&。比如在tomcat的server.xml中配置数据库连接池时,mysql jdbc url样例如下:

jdbc:mysql://localhost:3306/glowd?useUnicode=true&characterEncoding=utf-8&autoReconnect=true

数据库连接参数:

https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html

For example, to use 4-byte UTF-8 character sets with Connector/J, configure the MySQL server with character_set_server=utf8mb4, and leave characterEncoding out of the Connector/J connection string. Connector/J will then autodetect the UTF-8 setting.

就是说在jdbc字符串上面,建议不要写characterEncoding,这样的话,Connector会自动侦测数据库的’character_set_server’编码,现在我们规定character_set_server必须为utf8mb4,那么就可以略去characterEncoding和useUnicode。现在的jdbc url

jdbc:mysql://localhost:3306/glowd?autoReconnect=true

zeroDateTimeBehavior=convertToNull
JAVA连接MySQL数据库,在操作各项值均为为0(或者有0不正确的数据??)的timestamp等(日期为0000-00-00。。。。)类型时不能正确处理,而是默认抛出一个异常,比如所见的:java.sql.SQLException: Cannot convert value ‘0000-00-00 00:00:00’ from column XX to TIMESTAMP。

举个实际的栗子,你的方法中要传入来自页面的日期参数值,
按照正常的做法,比如日期值为2016-10-11,但是由于误操作,传入了0000-00-00,并没有设置正确的数据,那么这时默认抛出java.sql.SQLException异常
(如果设定这一项 zero datetime behavior(英文字面意思为“0datetime反应”)=
convert to null(英文字面意思为“转化为null”)
,把日期转换为null代替异常处理):

即这类操作情况的处理策略,有3种
1.exception(不指定,则默认)---->默认抛出异常,
2.convertToNull------->转化为null
3.round------->替换成最近的日期即XXXX-01-01

这个在指定管理的数据库连接属性文件(jdbc.properties)jdbc的URL常用到,比如这么写:

jdbc.url=jdbc:mysql://localhost:3306/databaseName?zeroDateTimeBehavior=convertToNull
上一篇:[ExtJS5学习笔记]第十节 Extjs5新增特性之ViewModel和DataBinding


下一篇:[ExtJS5学习笔记]第九节 Extjs5的mvc与mvvm框架结构简介