一、數據庫中的日期數據類型
數據庫中的日期數據類型有四種:date、datetime、timestimp、time。date類型只保存年月日,不保存時分秒,datetime和timestimp保 存年月日時分秒,time只保存時分秒。數據庫字段值進行比較時,date只比較年月日,datetime和timestimp比較年月日時分秒,time只比較 時分秒。
datetime、timestimp在數據庫中的存儲結構不一樣,timestimp更節省空間,但對於java對象的存取都是一樣的。
二、java中的四種日期類型:java.util.Date、java.sql.date、timestimp、time。
(1)java.sql.date、timestimp、time都在java.sql包下,都是java.util.date類的子類。java.sql包下的date顯示年月日, timestimp顯示年月日時分秒,time顯示時分秒,java.sql.date顯示年月日時分秒。
(2)這四種日期類型內部保存的都是時間戳。雖然java.sql.date、time值顯示年月日或時分秒,但其內部保存的都是完整的時間 戳,因此當把java.sql.date、time轉型為java.uitl.Date類型時,還是能顯示完整的年月日時分秒。
(3)直接System.out.println(java.sql.date)顯示年月日,System.out.println(java.sql.time)顯示時分秒。但是通過
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = simpleDateFormat.format(objDate)
無論objDate是四種類型中的任何類型,返回的str字符串都是准確的完整的年月日時分秒。因simpleDateFormat.format()方法的 參數是類型時java.util.Date類型,java.sql.date、timestimp、time會自動轉為java.util.Date類型。
三、數據庫中的四種日期數據類型通過mybatis逆向工程生成的實體類對應屬性的類型都是java.util.Date(不是java.sql.Date)類型。
-----java.util.Date類型的java數據保存-----
(1)java.util.Date類型的java數據(如2019-05-08 14:56:23)向數據庫date類型字段存值時,會忽略掉Date java對象中的時分秒 ,只保存年月日(2019-05-08),當再從數據庫中讀取date類型字段值賦值為java的Date對象時,Date對象的值為2019-05-08 00:00:00,時 分秒變成00:00:00,保存到數據庫之前的原有的時分秒(14:56:23)丟失。
(2)java.util.Date類型的java數據(如2019-05-08 14:56:23)向數據庫datetime、timestimp類型字段存值時,其年月日時分秒 都會保存,再從數據庫中取值賦給Date對象,還是2019-05-08 14:56:23
(3)java.util.Date類型的java數據(如2019-05-08 14:56:23)向數據庫time類型字段存值時,會忽略掉年月日,只保存時分秒 ,當再從數據庫中讀取time類型字段值賦值為java的Date對象時,Date對象的值為1970-01-01 14:56:23,保存到數據庫之前的原有的年月日 信息(2019-05-08)丟失。
-----java.sql.Date類型的java數據保存-----
(1)java.sql.Date類型的java數據向數據庫date類型字段存值時,因java.sql.Date只會顯示年月日不顯示時分秒,因此只保存年月 日(如2019-05-08),當再從數據庫中讀取date類型字段值賦值為java的Date對象時,Date對象的值為2019-05-08。
(2)java.sql.Date類型的java數據向數據庫datetime、timestimp類型字段存值時,因java.sql.Date只會顯示年月日不顯示時分 秒(即使對象內部保存的是時間戳,有時分秒信息),保存到數據庫datetime、timestimp類型字段的值為2019-05-08 00:00:00,再從數 據庫中取值賦給Date(無論是java.util.Date還是java.sql.Date)對象,值為2019-05-08 00:00:00
(3)java.sql.Date類型的java數據向數據庫time類型字段存值時,因java.sql.Date只會顯示年月日不顯示時分秒(即使對象內部 保存的是時間戳,有時分秒信息),因此會報錯,存儲失敗。
-----java.sql.Time類型的java數據保存-----
(1)因time類型只顯示時分秒如:12:12:12,因此向數據庫time字段保存時,只保存時分秒,當在從數據庫取值賦值給Time對象, Time對象如果轉為java.util.Date對象,其年月日信息丟失,顯示為1970-01-01 12:12:12;
(2)因time類型只顯示時分秒,當向數據庫date、datetime、timestimp字段存值時會報錯。
注:java.sql.Timestimp類型的java數據保存和java.util.Date的保存情況一樣
當從數據庫中讀取數據存入java對象時。java.util.Date存儲讀取的年月日時分秒,java.sql.Date只存儲讀取的年月日,即使讀取的數據庫 字段是datetime字段,有時分秒,如果用java.sql.Date接收讀取的數據,還是值存年月日,即使java.sql.Date轉成java.util.Date對象, 時分秒的值還是00:00:00。Time對象只存儲數據庫從讀取的時分秒值,年月日為1970-01-01
四、mybatis的mapper配置文件中的jdbctype
jdbctype相當於是一個數據攔截器,當向數據庫存取時,jdbctype在入庫之前起作用,當從獲取庫取數據時,jdbctype在從數據庫 取出數值時候和向java對象賦值之前起攔截作用。
1 <resultMap id="BaseResultMap" type="test.entity.Datetest" > 2 <id column="id" property="id" jdbcType="INTEGER" /> 3 <result column="datestimp" property="datestimp" jdbcType="TIMESTAMP" /> 4 <result column="datetest" property="datetest" jdbcType="DATE" /> 5 <result column="time" property="time" jdbcType="TIME" /> 6 </resultMap> 7 8 <insert id="insert" parameterType="test.entity.Datetest" > 9 insert into datetest (id, datestimp, datetest, time) 10 values (#{id,jdbcType=INTEGER}, #{datestimp,jdbcType=TIMESTAMP}, #{datetest,jdbcType=DATE}, #{time,jdbcType=TIME}) 11 </insert>
mybatis逆向工程生產的mapper文件的jdbctype的設置為:
(1)date類型字段對應的jdbctype類型為jdbcType="DATE"。
(2)datetime和timestimp類型字段對應的為jdbcType="TIMESTAMP"
(3)time字段對應個為jdbcType="TIME"
注意:只有當java對象為java.util.Date類型時,jdbcType對數據的存取才起作用,對其他的java時間對象,jdbcType沒有作用。
jdbcType類型對java.util.Date日期數據向數據庫存取的影響:
(1)當jdbcType="DATE",當向數據庫存取數據時會過濾掉時分秒。無論數據庫中的字段是date、datetime、timestimp中的哪一種,最終保存的都只有年月日,如果字段類型為datetime、 timestimp,時分秒信息為00:00:00。如果java對象類型為time或者數據庫字段類型為time類型,會報錯。當從數據庫中取數據是,無論數據字段類型為date、datetime、timestimp、time哪一種,最終取到的只有年月日,時分秒 為00:00:00。從time字段取值存到java的date對象顯示為1970-01-01 00:00:00。
(2)當jdbcType="TIMESTAMP"時,jdbcType不過濾任何內容,對存取沒影響。
(3)當jdbcType="TIME"時,當向數據庫存取數據時會過濾掉年月日。向數據庫中存數據,如果數據庫字段為date、datetime、timestimp會報錯。從數據庫取數據存入java的date對象時,年月日都會變成1970-01-01
可以不設置jdbcType時,不設置jdbctype相當於少了一層數據攔截。