[转]JDBC中日期时间的处理技巧

2023-11-18

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 日期/时间(包括年月日,时分秒,还有毫秒和纳秒)

有了上面的一些基础知识,下面介绍一些处理技巧。


 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()的好。
另外,采用字符串来保存时间存在一些问题,我在另外一篇帖子中解释过(见:Java中日期/时间的使用技巧【原创】);
还有是效率问题,用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;
java.util.Date utilDate;
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;
java.util.Date utilDate;
ts.setTime(utilDate.getTime());

java.sql.Date和java.sql.Time也是一样的道理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转]JDBC中日期时间的处理技巧 的相关文章

  • 用于解析和构建逻辑表达式的 Java 库

    我正在寻找一个 Java 开源库来解析和构建类似 SQL 的表达式 例如评估表达式的有效性 例如 a x or y and b z 另外我想要一个用于构建或扩展表达式的 API 就像是 Expression exp new Expressi
  • 将 MouseListener 添加到面板

    我正在尝试将鼠标操作添加到我的面板中 这就是程序应该做的事情 编写一个程序 允许用户通过按三下鼠标来指定一个三角形 第一次按下鼠标后 画一个小点 第二次按下鼠标后 绘制一条连接前两个点的线 第三次按下鼠标后 绘制整个三角形 第四次按下鼠标会
  • 从 Spring MVC XML 文件转移到 javaconfig。我真的对我的数据库 XML 文件感到困惑

    我从 Spring MVC XML 文件转移到 javaconfig 我真的对我的数据库 XML 文件感到困惑 我不知道如何让 Hibernate4 工作以及我的 JBoss JNDI 数据源工作 有人可以告诉我如何使 javaconfig
  • 重写 getPreferredSize() 会破坏 LSP

    我总是在这个压倒一切的网站上看到建议getPreferredSize 而不是使用setPreferredSize 例如 如前面的线程所示 对于固定大小的组件 使用重写 getPreferredSize 而不是使用 setPreferredS
  • Spring中的ProxyFactoryBean

    有人可以解释一下吗代理工厂Bean http static springsource org spring docs current javadoc api org springframework aop framework ProxyFa
  • 使用 Spring 控制器处理错误 404

    I use ExceptionHandler处理我的网络应用程序抛出的异常 在我的例子中我的应用程序返回JSON回应HTTP status用于对客户端的错误响应 但是 我正在尝试弄清楚如何处理error 404返回与处理的类似的 JSON
  • 无法访问“不安全”java方法的java表达式语言

    我正在开发一个项目 让用户向服务器提交小 脚本 然后我将执行这些脚本 有很多脚本语言可以嵌入到Java程序中 例如mvel ognl uel clojure rhino javascript等 但是 据我所知 它们都允许脚本编写者调用Jav
  • JavaFX使节点覆盖父节点边框颜色

    我有一个如下所示的节点 仅使用 css 我希望标签覆盖其父边框颜色 因此标签下方的边框颜色部分变得不可见 我用来制作这个边框的CSS代码 fx border color black fx border width 3 fx border r
  • 如何在 HandlerInterceptorAdapter 中添加 HttpServletRequest 标头?

    我正在尝试将授权标头添加到我的请求中 作为我们切换环境时的临时解决方法 我试图在扩展 HandlerInterceptorAdapter 的拦截器中处理它 我使用 MutableHttpServletRequest 类制作here http
  • 无法从资源加载图片

    So I am trying to load a image file from a resource so that when I export my application into a jar file it could be use
  • 可访问数据的 Java 约定。 (公共访问器和 Getter/命名)

    通过 Java API 您会看到大量冲突的命名和实践 这让我感到非常困惑 例如 The String http grepcode com file repository grepcode com java root jdk openjdk
  • 纱线上的火花,连接到资源管理器 /0.0.0.0:8032

    我正在我的开发机器 Mac 上编写 Spark 程序 hadoop的版本是2 6 spark的版本是1 6 2 hadoop集群有3个节点 当然都在linux机器上 我在idea IDE中以spark独立模式运行spark程序 它运行成功
  • JUNIT 测试 void 方法

    我有一个充满 void 方法的 java 类 我想进行一些单元测试以获得最大的代码覆盖率 例如我有这个方法 protected static void checkifValidElements int arg1 int arg2 metho
  • 在 Java 中创建 XML 文件的最佳方法是什么?

    我们目前使用 dom4j 来创建 XML 文件 不过 我猜现在有更好的东西了 如果我们使用的是 Java 1 6 或更高版本 那么在编写 XML 文件时最好使用什么类 运行速度最快 使用简单 我不需要构建一个 DOM 然后编写整个 DOM
  • 如何从intellij项目视图中隐藏不必要的文件?

    给定一个示例 gradle 项目 其项目结构如下所示 正如你所看到的 有很多东西你实际上不需要在想法中看到 但你需要它们存在 我知道下面被忽略的文件 文件夹类型Editor File Types但这些正在影响库和项目 idea 会在各处忽略
  • 如何使用Gson仅从Json反序列化某些特定字段?

    我有以下 JSON 字符串 channel bvmt initValues data value instrumentIds TN0007250012 TN0007500010 instruments mnemonic ADWYA marc
  • javax.media.jai 类的公共下载?

    这是一个非常简单的问题 我一直在寻找可以下载 javax media jai 库的地方 我找到了 jai imageio 库 但是我发现的所有其他 jai 内容要么已经过时 2008 年及之前 然后我遇到了登录屏幕 是否有 javax me
  • 让 Hibernate 和 SQL Server 与 VARCHAR 和 NVARCHAR 良好配合

    我目前正在大型数据库的某些表中启用 UTF 8 字符 这些表已经是 MS SQL 类型 NVARCHAR 此外 我还有几个使用 VARCHAR 的字段 Hibernate 与 JDBC 驱动程序的交互存在一个众所周知的问题 例如 参见在 h
  • 在实现使用原始类型的接口时如何避免警告?

    我正在实施流程工厂 http help eclipse org ganymede index jsp topic org eclipse platform doc isv reference api org eclipse debug co
  • 受信任的 1.5 小程序可以执行系统命令吗?

    如果是的话 这个能力有什么限制吗 具体来说 我需要以 Mac OSX 为目标 我以前用过这个在 Windows 系统上启动东西 但从未在 Mac 上尝试过 public void launchScript String args Strin

随机推荐

  • DataFrame入门丨Pandas数据分析基础(4)

    个人主页 互联网阿星 格言 选择有时候会大于努力 但你不努力就没得选 作者简介 大家好我是互联网阿星 和我一起合理使用Python 努力做时间的主人 如果觉得博主的文章还不错的话 请点赞 收藏 留言 支持一下博主哦 行业资料 PPT模板 简
  • Qt 6.x中Qt Quick简介及示例

    Qt Quick首次在Qt 4 7和Qt Creator 2 1中引入 是一种高级UI技术 Qt Quick模块是用于编写QML Qt Meta Object Language Qt元对象语言 应用程序的标准库 Qt QML模块提供了QML
  • Linux获取本机的IP的几种方式

    共计五条命令 使用的方式都不同 但原理相同充分利用LInux管道技术 root vagrant centos65 ifconfig eth0 grep Bcast cut d f2 cut d f1 192 168 191 2 root v
  • 西门子PLC的编程工具是什么?

    西门子PLC编程工具主要有下面这几个 1 STEP 7 Simatic Manager STEP 7或者Simatic Manager是西门子PLC编程最常用的软件开发环境 它是一款强大的集成开发环境 可以用来编写 调试PLC编程代码 还可
  • 《基础篇第4章:vue2基础》:使用vue脚手架创建项目

    文章目录 4 1初始化脚手架 4 1 1说明 4 1 2具体步骤 4 1 3模板项目的结构 4 1 4 创建第一个vue项目分析index html组成部分 4 1 5render函数 4 1 6修改默认配置 本人其他相关文章链接 4 1初
  • ubuntu wget ERROR 403: Forbidden 错误

    解决办法 临时变更wget的UA wget U 浏览器的useragent 下载地址 永久变更Wget 未测试 修改配置文件 etc wgetrc 添加下面这一行 header User Agent 浏览器的useragent 上面这个配置
  • 【vue】vue history和hash用法和区别

    vue中模式选择 router gt index js const router new VueRouter mode history base process env BASE URL routes hash和history区别 1 ha
  • 彷徨

    1 什么是hbase HBASE是一个高可靠性 高性能 面向列 可伸缩的分布式存储系统 利用HBASE技术可在廉价PC Server上搭建起大规模结构化存储集群 HBASE的目标是存储并处理大型的数据 更具体来说是仅需使用普通的硬件配置 就
  • 相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。

    题目描述 相传韩信才智过人 从不直接清点自己军队的人数 只要让士兵先后以三人一排 五人一排 七人一排地变换队形 而他每次只掠一眼队伍的排尾就知道总人数了 输入3个非负整数a b c 表示每种队形排尾的人数 a lt 3 b lt 5 c l
  • 贝叶斯优化优化参数,以Kmeans为例

    文章目录 步骤一 构造黑盒目标函数 步骤二 确定取值空间 步骤三 构造贝叶斯优化器 全部代码 贝叶斯优化有几个步骤 构造黑盒目标函数 确定取值空间 构造贝叶斯优化器 下面以kmeans为例 步骤一 构造黑盒目标函数 这个函数主要是运行需要的
  • Git笔记

    一 安装Git Win10 直接到Git官网下载安装程序 按照默认选项安装即可 安装完成后 在开始菜单里找到Git gt Git Bash 打开弹出类似命令行的窗口 则说明Git安装成功 安装完成后还需要对Git进一步设置 在命令行输入 g
  • ubuntu18.04 git clone:Failed to connect to github.com port 443: Connection refused

    git clone问题记录 一 Failed to connect to github com port 443 Connection refused 1 问题 2 解决方法 3 参考博文 二 gnutls handshake failed
  • Golang并发安全和锁

    目录 场景 互斥锁 读写互斥锁 互斥锁 读写锁 Sync Once sync Map 定时器 场景 有时候在Go代码中可能会存在多个goroutine同时操作一个资源 临界区 这种情况会发生竞态问题 数据竞态 类比现实生活中的例子有十字路口
  • Go学习笔记 : cobra 包简介

    cobra 是 go 语言的一个库 可以用于编写命令行工具 通常我们可以看到git pull docker container start apt install 等等这样命令 都可以很容易用corba来实现 另外 go 语言是很容易编译成
  • c++ 写一个头文件声明类方法,然后用一个cpp来定义类方法,最后再写一个main.cpp来调用类方法,出现找不到函数问题

    问题场景 在做 剑指offer 的面试题7 用两个栈实现一个队列 作者给出的代码只有两个文件 一个头文件和一个cpp源文件 然而从程序设计的角度来看 应当将头文件中的声明留在头文件中 函数的实现应当写在cpp源文件中 写完代码后 运行然而出
  • 淘特app x-sign参数签名分析

    之前看见大佬说淘特app的风控比tb的要小很多 于是学习了下t特的签名分析 一 抓包分析 通过Charles抓包分析 分析请求参数 headers x sgext JAWowlF3DRjHdjoiU 2Flc38K43prxmuGa9Jv3
  • OpenGL纹理UV动画

    http www codesampler com oglsrc htm OpenGL纹理UV动画 分类 C OpenGL 随想 感想 2013 07 08 15 34 162人阅读 评论 0 收藏 举报 opengl 动画 UV动画 Ope
  • 解决前端websocket数据帧接收数据大小限制(数据分帧)问题

    websocket前后台出现问题解决方法 一开始通过限制后台返回数据帧以125字节分隔分段数据返回给前台 但调试时发现只要加上其他的一些信息返回json string很容易就会超过了125字节 于是在后台修改了这个限制大小为2048 但是这
  • react的条件渲染(或者组件渲染)五种方式 --开发基础总结

    1 使用if的方式判断是否渲染某个组件 function UserGreeting props return h1 Welcome back h1 function GuestGreeting props return h1 Please
  • [转]JDBC中日期时间的处理技巧

    Java中用类java util Date对日期 时间做了封装 此类提供了对年 月 日 时 分 秒 毫秒以及时区的控制方法 同时也提供一些工具方法 比如日期 时间的比较 前后判断等 java util Date中采用一个long型的数来保存