【Java 与数据库】JDBC中日期时间的处理技巧
基础知识
Java中用类java.util.Date
对日期/时间做了封装,此类提供了对年、月、日、时、分、秒、毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等。
java.util.Date中采用一个long型的数来保存日期/时间,它表示从格林威治时间1970年1月1日00点00分00秒至今的毫秒数。
JDBC中,在这个类的基础之上扩展了3个类:
java.sql.Date,
java.sql.Time,
java.sql.Timestamp
java.sql.Date
表示日期,只包括年月日;
java.sql.Time
表示时间,只包括时分秒;
java.sql.Timestamp
表示时间戳,包括年月日,时分秒,还有毫秒和纳秒;值得注意的是它比java.util.Date
还多了一个纳秒。
这3个类分别对应数据库的3种数据类型:
java.sql.Date
日期(只包括年月日)
java.sql.Time
时间(只包括时分秒)
java.sql.Timestamp
日期/时间(包括年月日,时分秒,还有毫秒和纳秒)
java.sql.Date构造函数
java.util.Date构造函数
获取当前时间
1.通过Util包中的Date获取
Date date = new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
System.out.println(dateFormat.format(date));
2.通过Util包的Calendar 获取
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
System.out.println(dateFormat.format(calendar.getTime()));
3.通过Util包的Calendar 获取时间,分别获取年月日时分秒
Calendar cal=Calendar.getInstance();
int y=cal.get(Calendar.YEAR);
int m=cal.get(Calendar.MONTH);
int d=cal.get(Calendar.DATE);
int h=cal.get(Calendar.HOUR_OF_DAY);
int mi=cal.get(Calendar.MINUTE);
int s=cal.get(Calendar.SECOND);
System.out.println("现在时刻是"+y+"年"+m+"月"+d+"日"+h+"时"+mi+"分"+s+"秒");
通过sql包获取当前时间
java.sql包下给出三个与数据库相关的日期时间类型:
Date:表示日期,只有年月日,没有时分秒。会丢失时间;
Time:表示时间,只有时分秒,没有年月日。会丢失日期;
Timestamp:表示时间戳,有年月日时分秒,以及毫秒。
//获取当前时间java.sql.Date
java.sql.Date sqlDate=new java.sql.Date(new java.util.Date().getTime());
System.out.println(sqlDate); //2020-06-23
java.sql.Time sTime=new java.sql.Time(new java.util.Date().getTime());
System.out.println(sTime); //10:29:19
java.sql.Timestamp stp=new java.sql.Timestamp(new java.util.Date().getTime());
System.out.println(stp); //2020-06-23 10:29:19.329
Util包和sql包之间相互转换
System.out.println("*********util.Date转sql.Date*********");
Date utilDate = new Date();//util.Date
System.out.println("utilDate : " + utilDate);
Timestamp sqlDate = new Timestamp(utilDate.getTime());//util.Date转sql.Date
System.out.println("sqlDate : " + sqlDate);
System.out.println("*********sql.Date转util.Date*********");
System.out.println("sqlDate : " + sqlDate);
Date date = new Date(sqlDate.getTime());//sql.Date转util.Date
/*
java.util.Date date = new java.util.Date(sqlDate.getTime());
*/
System.out.println("utilDate : " + date);
运行结果:
*********util.Date转sql.Date*********
utilDate : Tue Jun 23 10:36:24 CST 2020
sqlDate : 2020-06-23 10:36:24.917
*********sql.Date转util.Date*********
sqlDate : 2020-06-23 10:36:24.917
utilDate : Tue Jun 23 10:36:24 CST 2020
处理技巧。
1.对于数据库种不同的时间类型,要分别采用与之相对应的Java包装类来存取
日期类型用java.sql.Date
,时间类型用java.sql.Time
,日期/时间类型用java.sql.Timestamp
;
这里举个例子:假设要从oracle中获取系统时间,需要执行sql:select sysdate from dual
,然后在通过ResultSet
获取查询结果时,一定要调用方法:getTimestamp()
,这样才可以把年月日时分秒都取出来,调用getDate()
只能取出年月日,调用getTime()
只能取出时分秒。调用getString
也可以取出来,但是存在问题,见技巧2。
2.尽量不要调用getString()来获取日期/时间类型的数据
调用getString()
也可以取出时间类型的数据,JDBC在内部将日期/时间转换为字符串;但是这个字符串的格式却取决于数据库,用Oracle是一种,用Sybase又是一种,mysql又是一种,如果你想兼容多种数据库,还是不要用getString()
的好。
另外,采用字符串来保存时间存在一些问题,还有是效率问题,用getString()
需要在内部将日期时间转换为字符串,涉及字符串处理;但用getTimestamp()
只需要做整数的运算和处理;而整数的运算处理一般都比字符串处理效率高。
3.如何将JDBC的日期/时间类型转换为字符串
曾经看到过有人这样写:
java.sql.Timestamp timeStamp = //通过数据库访问获取到该数据
java.util.Date utilDate = new java.util.Date(timeStamp.getTime());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(utilDate);
这样也可以达到最终目的,但是有点问题,java.sql.Timestamp
是继承java.util.Date
的,因此format的时候直接传入timeStamp
即可,没有必要临时创建一个utilDate
。像下面这样就可以了:
java.sql.Timestamp timeStamp = //通过数据库访问获取到该数据
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(timeStamp);
如果是java.sql.Date
或java.sql.Time
,也是同样的道理。
4.在做select、update或insert时,如果某个字段为日期/时间类型,最好用PreparedStatement,而不要采用Statement
经常会看到这样的程序:
Connection conn;//前面的步骤略
Statement stmt = conn.createStatement();
stmt.execute("insert into tab ( begin_date ) values ( TO_Date( '06/27/2005 12:59:52', 'MM/DD/YYYY HH24:MI:SS'))");
熟悉oracle的人都知道,To_Date
是oracle里的函数,其他数据库没有,即使有也很可能不一样。那么这段代码只能用在oracle上,如果换成其他数据库,程序就无法执行了。
如果采用PreparedStatement,代码是这样:
Connection conn;//前面的步骤略
PreparedStatement pstmt = conn.prepareStatement("insert into tab ( begin_date ) values( ?)");
pstmt.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt.execute();
可以看出来,这段代码与数据库无关,只要是支持标准sql的数据库都没有问题。
客户是上帝,想用什么数据库,我们就得支持什么数据库,为了避免以后的麻烦,还是用PreparedStatement
的好。
5.存储过程的参数,该用日期/时间类型的就要用,不要一味的都采用字符串型
存储过程,只要是日期/时间,都采用字符串类型(varchar2或其它)。这样会造成很多麻烦。
首先,需要约定字符串格式,调用者和被调用者都必须遵循这个格式,这种约定很容易受人为因素影响;
其次,存储过程中需要对字符串做分析,合法性检查等,增加了编码的难度和负责度;
再者,这些额外的代码,降低的程序的效率,增加了数据库的负担。
采用日期/时间类型来作为存储过程的参数,可以降低编码的难度,从逻辑上看起来更清晰,而且运行效率高。
在JDBC中采用CallableStatement
来调用存储过程,对日期/时间的输入和输出,可以采用setTimestamp,getTimestamp,setDate,getDate,setTime,getTime
。
6.java.sql.Timestamp如何转换为java.util.Date?
java.sql.Timestamp
是java.util.Date
的子类,不需要做任何转换直接赋值即可:
java.sql.Timestamp ts = new java.sql.Timestamp();
java.util.Date utilDate = new java.util.Date();
utilDate = ts;
java.sql.Date
和java.sql.Time
也是一样的道理。
7.java.util.Date如何转换为java.sql.Timestamp?
java.util.Date
是java.sql.Timestamp
的父类,不能像技巧6那样做了。要这样:
java.sql.Timestamp ts = new java.sql.Timestamp();
java.util.Date utilDate = new java.util.Date utilDate();
ts.setTime(utilDate.getTime());
java.sql.Date
和java.sql.Time
也是一样的道理。
【Java 与数据库】JDBC中日期时间的处理技巧的更多相关文章
- [转]JDBC中日期时间的处理技巧
Java中用类java.util.Date对日期/时间做了封装,此类提供了对年.月.日.时.分.秒.毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等. java.uti ...
- Java中日期时间API小结
Java中为处理日期和时间提供了大量的API,确实有把一件简单的事情搞复杂的嫌疑,各种类:Date Time Timestamp Calendar...,但是如果能够看到时间处理的本质就可以轻松hol ...
- Oracle 数据库中日期时间的插入操作
Oracle 中如何插入日期时间类型的数据,首先为了演示, 新建数据表如下 create table t( mydate date); 插入日期时间 SQL> insert into t val ...
- java android中日期时间 问题总结
Date 类型: Date date = new Date(); // 代表获取当前系统日期和时间 System.out.println(date); 使用类的方法设置时间和日期:(通过该方法初始 ...
- sql语句中日期时间格式化查询
今天在做会员管理系统搜索时,我发现以前的搜索时间方式不太科学,效率也不是太高.由其是在查询指定的时间相等的时候,我在数据库中都存这样的时间格式"2007-5-22 14:32:1 ...
- PHP中日期时间函数date()用法总结
date()是我们常用的一个日期时间函数,下面我来总结一下关于date()函数的各种形式的用法,有需要学习的朋友可参考. 格式化日期date() 函数的第一个参数规定了如何格式化日期/时间.它使用字母 ...
- Sql Server中日期时间格式化为字符串输出
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- SqlServer数据库表导入SqlLite数据库表保持日期时间类型字段的格式
在写查询功能的过程中遇到一个这样的问题:按日期范围查询,sql语句是:where dt>=用户选择起始日期&&dt<=用户选择结束日期.数据库中的数据如图1,我选择的测试数 ...
- Java 之 JDK1.8之前日期时间类
一.JDK1.8之前日期时间类 二. java.lang.System类 System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1 ...
随机推荐
- EDG夺冠!用Python分析22.3万条数据:粉丝都疯了!
一.EDG夺冠信息 11月6日,在英雄联盟总决赛中,EDG战队以3:2战胜韩国队,获得2021年英雄联盟全球总决赛冠军,这个比赛在全网各大平台也是备受瞩目: 1.微博热搜第一名,截止2021-11-1 ...
- C# | VS2019连接MySQL的三种方法以及使用MySQL数据库教程
本文将介绍3种添加MySQL引用的方法,以及连接MySQL和使用MySQL的教程 前篇:Visual Studio 2019连接MySQL数据库详细教程 \[QAQ \] 第一种方法 下载 Mysql ...
- rocketmq广播消息的(五)
一.简介 广播消费指的是:一条消息被多个consumer消费,即使这些consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次,广播 ...
- wm_concat结果长度限制的有关问题 ORA-06502: PL/SQL: 数字或值错误
该函数作用是把列值合并(用英文逗号分割),但是数量有限制,返回的字符数上线是4000(oracle11g),超过会报错,听说oracle版本到 11.2.0.2.0 或以上返回的是clob类型,长度就 ...
- NOIP模拟99(多校31)
T1 法阵 解题思路 原题3100,张口放 T1(出题人原话) 思维题,合法的情况其实就是上下两个梯形拼起来的样子. 他们的边界都是在 \(i\) 轴上面,但是不能相交. 于是我们可以尝试两者相交的纵 ...
- scrapy获取当当网中数据
yield 1. 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代 2. yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yiel ...
- [atARC071F]Infinite Sequence
注意到当$a_{i}\ne 1$且$a_{i+1}\ne 1$,那么$\forall i<j,a_{j}=a_{i+1}$(证明的话简单归纳就可以了) 令$f_{i}$表示在题中条件下,还满足$ ...
- vscode 整理————开篇之力(一)
前言 作为一个开发为什么对一个vscode 这样的工具进行整理呢,因为vscode 非常的常用,它包含很多编辑器共同有的特征,这些特征帮助我们了解其他编辑器. 这里可能就有人疑问了,我们需要去非常的关 ...
- Codeforces 288E - Polo the Penguin and Lucky Numbers(数位 dp+推式子)
题目传送门 似乎我的解法和官方题解不太一样 纪念自己独立做出来的一道难度 2800 的题. 我们记 \(ans(x)\) 为 \([444...44,x]\) 的答案,显然答案为 \(ans(r)-a ...
- 洛谷 P7360 -「JZOI-1」红包(Min-Max 容斥+推式子)
洛谷题面传送门 hot tea. 首先注意到这个 \(\text{lcm}\) 特别棘手,并且这里的 \(k\) 大得离谱,我们也没办法直接枚举每个质因子的贡献来计算答案.不过考虑到如果我们把这里的 ...