由mysql的 datetime 類型字段默認設置爲了'0000-00-00' 引起的血案

1、錯誤信息

Java鏈接數據庫轉化爲對象時報如下錯誤信息: html

Error querying database. Cause: 
java.sql.SQLException: Value '0000-00-00 00:00:00' 
can not be represented as java.sql.Timestamp

數據庫遷移導入sql文件時報如下錯誤: java

[SQL] INSERT INTO `auto_policy_info` VALUES 
('14', null, null, '0', '0000-00-00 00:00:00', '2015-09-21 10:10:36', ...);
[Err] 1292 - Incorrect datetime value:
 '0000-00-00 00:00:00' for column 'update_time' at row 1

2、解決辦法

     鏈接數據庫轉化爲對象出錯的解決辦法爲在數據庫鏈接後面加上參數zeroDateTimeBehavior=convertToNull 這樣若是碰到 ‘0000-00-00:00:00:00’的日期類型時,將會轉化爲null值 mysql

db.jdbcurl=jdbc:mysql://192.168.1.52:3306/db?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
   針對數據插入數據‘0000-00-00:00:00:00’ 數據自己不接受的解決辦法爲,用root用戶登陸,從新設置數據庫的模式(儘可能使用root用戶 要否則 GLOBAL設置不成功,可是能夠設置SESSION的)

    一、首先查詢出數據庫現有的模式 sql

select @@sql_mode;

    

    二、把NO_ZERO_IN_DATE,NO_ZERO_DATE去掉,而後從新設置 數據庫

SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

這樣關閉數據庫客戶端的鏈接,從新登陸,而後再執行那種比較操蛋的插入語句便可正確的插入。 服務器

3、刨根問底

若是以上兩步已經解決了問題,不想再細究其餘的東西,那到此問題就結束了。 app

從剛開始接觸Java程序開始,咱們對這種數據庫的鏈接語句已經爛熟於胸,也許在咱們也會常常設置字符編碼,可是對其餘的參數知之甚少,或者不多使用,還有就是數據庫服務器是有模式這個東西的,這個若是僅僅是對開發人員來講應該不多接觸,這個模式的設置對咱們程序的有什麼樣的影響,如何設置數據庫的模式(此處暫時只看mysql的)。因此引起了我對以上兩個問題的探究。 less

一、數據庫鏈接參數

數據庫鏈接URL格式 curl


jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] »
[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]
簡單鏈接


jdbc:mysql://localhost:3306/sakila?profileSQL=true
多數據鏈接


jdbc:mysql:loadbalance://localhost:3306,localhost:3310/sakila

數據鏈接後的參數影響着服務器到數據庫數據的行爲,在咱們一般使用的狀況下,mysql數據庫鏈接參數咱們設置最多的就是characterEncoding=GBK/UTF-8 了,這個是爲了防止應用程序亂碼(數據庫查詢出來的數據轉化到應用程序中亂碼)而設置的,還有user和password參數,可是對其餘參數就不知道了,跑到官方文檔幾經折騰,終於找到了針對MySQL 5.7版本的關於參數的詳細說明socket

如下簡要說明,其餘的能夠自行在裏面去查找

Connection/Authentication. 

屬性和描述

user

鏈接數據庫的用戶

Since version: all versions

password

鏈接數據庫的密碼

Since version: all versions

socketFactory

The name of the class that the driver should use for creating socket connections to the server. This class must implement the interface 'com.mysql.jdbc.SocketFactory' and have public no-args constructor.

Default: com.mysql.jdbc.StandardSocketFactory

Since version: 3.0.3

connectTimeout

鏈接超時時間(毫秒數),設置爲在jdk1.4版本之後默認爲0,意思是永不超時

Default: 0

Since version: 3.0.1

socketTimeout

操做超時時間,默認爲0,永不超時

Default: 0

Since version: 3.0.1

connectionLifecycleInterceptors

A comma-delimited list of classes that implement "com.mysql.jdbc.ConnectionLifecycleInterceptor" that should notified of connection lifecycle events (creation, destruction, commit, rollback, setCatalog and setAutoCommit) and potentially alter the execution of these commands. ConnectionLifecycleInterceptors are "stackable", more than one interceptor may be specified via the configuration property as a comma-delimited list, with the interceptors executed in order from left to right.

Since version: 5.1.4

useConfigs

Load the comma-delimited list of configuration properties before parsing the URL or applying user-specified properties. These configurations are explained in the 'Configurations' of the documentation.

Since version: 3.1.5

authenticationPlugins

Comma-delimited list of classes that implement com.mysql.jdbc.AuthenticationPlugin and which will be used for authentication unless disabled by "disabledAuthenticationPlugins" property.

Since version: 5.1.19

defaultAuthenticationPlugin

Name of a class implementing com.mysql.jdbc.AuthenticationPlugin which will be used as the default authentication plugin (see below). It is an error to use a class which is not listed in "authenticationPlugins" nor it is one of the built-in plugins. It is an error to set as default a plugin which was disabled with "disabledAuthenticationPlugins" property. It is an error to set this value to null or the empty string (i.e. there must be at least a valid default authentication plugin specified for the connection, meeting all constraints listed above).

Default: com.mysql.jdbc.authentication.MysqlNativePasswordPlugin

Since version: 5.1.19

disabledAuthenticationPlugins

Comma-delimited list of classes implementing com.mysql.jdbc.AuthenticationPlugin or mechanisms, i.e. "mysql_native_password". The authentication plugins or mechanisms listed will not be used for authentication which will fail if it requires one of them. It is an error to disable the default authentication plugin (either the one named by "defaultAuthenticationPlugin" property or the hard-coded one if "defaultAuthenticationPlugin" property is not set).

Since version: 5.1.19

disconnectOnExpiredPasswords

If "disconnectOnExpiredPasswords" is set to "false" and password is expired then server enters "sandbox" mode and sends ERR(08001, ER_MUST_CHANGE_PASSWORD) for all commands that are not needed to set a new password until a new password is set.

Default: true

Since version: 5.1.23

interactiveClient

Set the CLIENT_INTERACTIVE flag, which tells MySQL to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT

Default: false

Since version: 3.1.0

localSocketAddress

Hostname or IP address given to explicitly configure the interface that the driver will bind the client side of the TCP/IP connection to when connecting.

Since version: 5.0.5

propertiesTransform

An implementation of com.mysql.jdbc.ConnectionPropertiesTransform that the driver will use to modify URL properties passed to the driver before attempting a connection

Since version: 3.1.4

useCompression

Use zlib compression when communicating with the server (true/false)? Defaults to 'false'.

Default: false

Since version: 3.0.17



二、數據庫服務器模式

在mysql官網的mode index中有對各個模式的描述


MySQL服務器能夠以不一樣的SQL模式來操做,而且能夠爲不一樣客戶端應用不一樣模式。這樣每一個應用程序能夠根據本身的需求來定製服務器的操做模式。

模式定義MySQL應支持哪些SQL語法,以及應執行哪一種數據驗證檢查。這樣能夠更容易地在不一樣的環境中使用MySQL,並結合其它數據庫服務器使用MySQL

你能夠用--sql-mode="modes"選項啓動mysqld設置默認SQL模式。若是你想要重設,該值還能夠爲空(--sql-mode ="")

你還能夠在啓動後用 SET [SESSION|GLOBAL] sql_mode='modes'語句設置 sql_mode變量來更改 SQL模式。設置 GLOBAL變量時須要擁有 SUPER權限,而且會影響從那時起鏈接的全部客戶端的操做。設置 SESSION變量隻影響當前的客戶端。任何客戶端能夠隨時更改本身的會話 sql_mode


查閱5.17版本,提供了以下模式

ALLOW_INVALID_DATES

在嚴格模式下不要檢查所有日期。只檢查112之間的月份和131之間的日。這在Web應用程序中,當你從三個不一樣的字段獲取年、月、日,而且想要確切保存用戶插入的內容(不進行日期驗證)時很重要。該模式適用於DATEDATETIME列。不適合TIMESTAMP列,TIMESTAMP列須要驗證日期

ANSI

等同 REAL_AS_FLOATPIPES_AS_CONCATANSI_QUOTESIGNORE_SPACE

ANSI_QUOTES

將‘ "’視爲識別符引號 (`’引號字符 ),不要視爲字符串的引號字符。在 ANSI模式,你能夠仍然使用‘ `’來引用識別符。啓用 ANSI_QUOTES後,你不能用雙引號來引用字符串,由於它被解釋爲識別符。

ERROR_FOR_DIVISION_BY_ZERO

在嚴格模式下,在INSERT或者UPDATE過程當中,若是零除(或者MOD(X,0)),則產生錯誤(不然爲警告)。若是未給出該模式,背零除時Mysql返回NULL。

HIGH_NOT_PRECEDENCE

NOT操做符的優先順序是表達式例如 NOT a BETWEEN b AND c被解釋爲 NOT (a BETWEEN b AND c)。在一些舊版本 MySQL中, 表達式被解釋爲 (NOT a) BETWEEN b AND c。啓用 HIGH_NOT_PRECEDENCE SQL模式,能夠得到之前的更高優先級的結果。

IGNORE_SPACE

容許函數名和  '(' 之間有空格。

MAXDB

等同 PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_AUTO_CREATE_USER

MSSQL

等同 PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONS

MYSQL323

等同 NO_FIELD_OPTIONSHIGH_NOT_PRECEDENCE

MYSQL40

等同 NO_FIELD_OPTIONSHIGH_NOT_PRECEDENCE

NO_AUTO_CREATE_USER

防止GRANT自動建立新用戶,除非還制定了密碼

NO_AUTO_VALUE_ON_ZERO

NO_AUTO_VALUE_ON_ZERO影響AUTO_INCREMENT列的處理。通常狀況,你能夠向該列插入NULL0生成下一個序列號。NO_AUTO_VALUE_ON_ZERO禁用0,所以只有NULL能夠生成下一個序列號。

若是將0保存到表的AUTO_INCREMENT列,該模式會頗有用。(不推薦採用該慣例)。例如,若是你用mysqldump轉儲表並重載,MySQL遇到0值通常會生成新的序列號,生成的表的內容與轉儲的表不一樣。重載轉儲文件前啓用NO_AUTO_VALUE_ON_ZERO能夠解決該問題。mysqldump在輸出中自動包括啓用NO_AUTO_VALUE_ON_ZERO的語句。

NO_BACKSLASH_ESCAPES

禁用反斜線字符('\')做爲字符串內的退出字符。啓用改模式,反斜線則成爲普通字符

NO_DIR_IN_CREATE

建立表時,忽視全部 INDEX DIRECTORYDATA DIRECTORY指令。該選項對從複製服務器有用。

NO_ENGINE_SUBSTITUTION

若是須要的存儲引擎被禁用或未編譯,能夠防止自動替換存儲引擎

NO_FIELD_OPTIONS

不要在 SHOW CREATE TABLE的輸出中打印 MySQL專用列選項。該模式在可移植模式( portability mode)下用於 mysqldump

NO_KEY_OPTIONS

不要在 SHOW CREATE TABLE的輸出中打印 MySQL專用索引選項。該模式在可移植模式( portability mode)下用於 mysqldump

NO_TABLE_OPTIONS

不要在 SHOW CREATE TABLE的輸出中打印 MySQL專用表選項(例如 ENGINE)。該模式在可移植模式( portability mode)下用於 mysqldump

NO_UNSIGNED_SUBTRACTION

在減運算中,若是某個操做數沒有符號,不要將結果標記爲 UNSIGNED。請注意這樣使 UNSIGNED BIGINT不能 100%用於上下文中。

NO_ZERO_DATE

在嚴格模式,不要將 '0000-00-00'作爲合法日期。你仍然能夠用 IGNORE選項插入零日期。在非嚴格模式,能夠接受該日期,但會生成警告。

NO_ZERO_IN_DATE

在嚴格模式,不接受月或日部分爲0的日期。若是使用IGNORE選項,咱們爲相似的日期插入'0000-00-00'。在非嚴格模式,能夠接受該日期,但會生成警告。

ONLY_FULL_GROUP_BY

不要讓 GROUP BY部分中的查詢指向未選擇的列。

ORACLE

等同 PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_AUTO_CREATE_USER

PAD_CHAR_TO_FULL_LENGTH


PIPES_AS_CONCAT


POSTGRESQL

等同 PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONS

REAL_AS_FLOAT

REAL視爲 FLOAT的同義詞,而不是 DOUBLE的同義詞。


STRICT_TRANS_TABLES

若是不能將給定的值插入到事務表中,則放棄該語句。對於非事務表,若是值出如今單行語句或多行語句的第 1行,則放棄該語句

TRADITIONAL

Make MySQL的行爲象「傳統SQL數據庫系統。該模式的簡單描述是當在列中插入不正確的值時「給出錯誤而不是警告」。釋:一旦發現錯誤當即放棄INSERT/UPDATE。若是你使用非事務存儲引擎,這種方式不是你想要的,由於出現錯誤前進行的數據更改不會「滾動」,結果是更新「只進行了一部分」。

相關文章
相關標籤/搜索