java日期类型对象通过mybatis向数据库中的存取
java日期类型对象通过mybatis向数据库中的存取
一、数据库中的日期数据类型
数据库中的日期数据类型有四种: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相当于少了一层数据拦截。