【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 ...
随机推荐
- vue+node+mongondb实战之mongodb登陆操作
页面搭建基本完成,只是样式还没有美化,由于采取的前后端分离开发,所有页面逻辑全部由vue来负责,后台采用express框架只用来提供 接口,注册就是讲数据存入数据库,比较简单,而登陆碰了一些小问题,发 ...
- Rabbitmq的死信
一.概述 死信有死信队列.死信交换器和死信消息组成.死信消息则有如下三种情况生成: 1.消费者使用basic.reject或 basic.nack并将requeue参数设置为false来拒绝该消息 2 ...
- 带allow-create的el-select限制长度
需求:给el-select添加新增字段长度限制且新增内容不能为空 1.首先给el-select绑定一个id(例如:selectSku),这个id会传到组件里面,绑定在那个input上面, <el ...
- lilypond和弦及其转位的表示
在lilypond,如果要打和弦的话,有所谓的chordmode,命令就是\chordmode {} 要使用chordmode需要一些基本的和弦命名的知识,最好先补一下乐理 实际上lilypond的官 ...
- 没有人比我更会使用集合!对, 是dart中的集合
目录 简介 List的使用 Set的使用 Map的使用 常见的集合方法 总结 简介 dart中的集合有三个,分别是list,set和map.dart在dart:core包中提供了对于这三种集合非常有用 ...
- [Net 6 AspNetCore Bug] 解决返回IAsyncEnumerable<T>类型时抛出的OperationCanceledException会被AspNetCore 框架吞掉的Bug
记录一个我认为是Net6 Aspnetcore 框架的一个Bug Bug描述 在 Net6 的apsnecore项目中, 如果我们(满足以下所有条件) api的返回类型是IAsyncEnumerabl ...
- CF187D BRT Contract
考虑如果哪次经过了红灯则显然已经和出发的时间没关系了. 然后我们需要做的是怎么样找到最近的一个是红灯的点. 然后实际下是我们做一个前缀和:\(L_i = \sum d_i\) 然后求\(\min (L ...
- 洛谷 P3246 - [HNOI2016]序列(单调栈+前缀和)
题面传送门 这道题为什么我就没想出来呢/kk 对于每组询问 \([l,r]\),我们首先求出区间 \([l,r]\) 中最小值的位置 \(x\),这个可以用 ST 表实现 \(\mathcal O(n ...
- SQLite3 约束和简单命令
安装sqlite3,配置环境变量. 1.打开数据库 sqlite3.exe db_name.db 2.常用命令 .tables 查看所有表 .headers on 设置显示表头 .schema tab ...
- DTOJ 3999: 游戏
题目描述这个游戏是这样的,你有一个初始序列S ,你每次可以选择一段任意长度的连续区间,把他们+1 再膜k,给定目标序列,你需要尝试用尽量少的操作次数将初始序列变为目标序列.作为一名优秀的OIer,您认 ...