GVKun编程网logo

Oracle jdbc中的PreparedStatement和setTimestamp(oracle.jdbc.readtimeout)

15

本篇文章给大家谈谈Oraclejdbc中的PreparedStatement和setTimestamp,以及oracle.jdbc.readtimeout的知识点,同时本文还将给你拓展java.sql

本篇文章给大家谈谈Oracle jdbc中的PreparedStatement和setTimestamp,以及oracle.jdbc.readtimeout的知识点,同时本文还将给你拓展java.sql.PreparedStatement不能转换为com.mysql.jdbc.PreparedStatement、Java中PreparedStatement和Statement的用法区别、java中PreparedStatement和Statement详细讲解、jdbc PreparedStatement 方式向Oracle批量插入数据怎么取Sequence的值?等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Oracle jdbc中的PreparedStatement和setTimestamp(oracle.jdbc.readtimeout)

Oracle jdbc中的PreparedStatement和setTimestamp(oracle.jdbc.readtimeout)

我在where子句中使用带有时间戳的PreparedStatement:

PreparedStatement s=c.prepareStatement("select value,utctimestamp from t where utctimestamp>=? and utctimestamp<?"); s.setTimestamp(1, new Timestamp(1273017600000L));   //2010-05-05 00:00 GMTs.setTimestamp(2, new Timestamp(1273104000000L));   //2010-05-06 00:00 GMTResultSet rs = s.executeQuery();if(rs.next()) System.out.println(rs.getInt("value"));

当我在客户端计算机上具有不同的时区时,得到的结果是不同的。这是Oracle jdbc中的错误吗?或正确的行为?

Oracle数据库版本为10.2,并且我尝试使用Oracle jdbc瘦驱动程序版本10.2和11.1。

参数为时间戳,我希望途中不会进行任何时间转换。数据库列类型为DATE,但我还使用TIMESTAMP列类型对其进行了检查,结果相同。

有没有办法达到正确的结果?我无法将整个应用程序中的默认时区更改为UTC。

谢谢你的帮助

答案1

小编典典

要在UTC时区的PreparedStatement中设置时间戳记值,应使用

stmt.setTimestamp(1, t, Calendar.getInstance(TimeZone.getTimeZone("UTC")))

Timestamp值始终为UTC,但并非总是jdbc驱动程序可以自动将其正确发送到服务器。第三个参数Calendar可以帮助驱动程序为服务器正确准备值。

java.sql.PreparedStatement不能转换为com.mysql.jdbc.PreparedStatement

java.sql.PreparedStatement不能转换为com.mysql.jdbc.PreparedStatement

您的导入存在问题,您必须从java.sql而非Connection导入PreparedStatementResultSetcom.mysql.jdbc,因此请使用:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

代替此:

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
,

在Connections.getConnection()处,应使用DriverManager初始化连接。

类似

ret.reg_dt = pd.to_datetime(ret.reg_dt,format='%Y-%m-%d %H:%M:%S')

https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html#db_connection_url

Java中PreparedStatement和Statement的用法区别

Java中PreparedStatement和Statement的用法区别

1、 PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。

 

2、作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法

      execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数

 

3、在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替

      Statement.也就是说,在任何时候都不要使用Statement.
基于以下的原因:
一.代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values (''"+var1+"'',''"+var2+"'',"+var3+",''"+var4+"'')");//stmt是Statement对象实例

perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate(); //prestmt是 PreparedStatement 对象实例 

不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.

二.PreparedStatement尽最大可能提高性能.
    语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当 于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹 配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹 配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values (''11'',''22'');
insert into tb_name (col1,col2) values (''11'',''23'');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.

当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.

三.最重要的一点是极大地提高了安全性.

即使到目前为止,仍有一些人连基本的恶义SQL语法都不知道.
String sql = "select * from tb_name where name= ''"+varname+"'' and passwd=''"+varpasswd+"''";
如果我们把['' or ''1'' = ''1]作为varpasswd传入进来.用户名随意,看看会成为什么?

select * from tb_name = ''随意'' and passwd = '''' or ''1'' = ''1'';
因为''1''=''1''肯定成立,所以可以任何通过验证.更有甚者:
把['';drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = ''随意'' and passwd = '''';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.

而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.

 

转载于:http://www.cnblogs.com/zhizhuwang/p/3513372.html

java中PreparedStatement和Statement详细讲解

java中PreparedStatement和Statement详细讲解

这篇文章主要介绍了java中PreparedStatement和Statement详细讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

大家都知道PreparedStatement对象可以防止sql注入,而Statement不能防止sql注入,那么大家知道为什么PreparedStatement对象可以防止sql注入,接下来看我的案例大家就会明白了!

我用的是MysqL数据库,以admin表为例子,如下图:

最后面有具体的java代码和sql代码案例

最终执行的sql语句打印出来是SELECT * FROM admin WHERE username = '韦小宝' AND password = '222' OR '8'='8'

从以上截图就能看出来,由此可见,prepareStatement对象防止sql注入的方式是把用户非法输入的单引号用反斜杠做了转义,从而达到了防止sql注入的目的

Statement对象就没那么好心了,它才不会把用户非法输入的单引号用反斜杠做转义呢!

PreparedStatement可以有效防止sql注入,所以生产环境上一定要使用PreparedStatement,而不能使用Statement

当然啦,你可以仔细研究下PreparedStatement对象是如何防止sql注入的,我自己把最终执行的sql语句打印出来了,看到打印出来的sql语句就明白了,原来是MysqL数据库产商,在实现PreparedStatement接口的实现类中的setString(int parameterIndex, String x)函数中做了一些处理,把单引号做了转义(只要用户输入的字符串中有单引号,那MysqL数据库产商的setString()这个函数,就会把单引号做转义)

大家有兴趣可以去网上,下载一份MysqL数据库的驱动程序的源代码,看看MysqL数据库产商的驱动程序的源代码,去源代码中找到setString(int parameterIndex, String x)函数,看看该函数中是怎么写的,我没有下载MysqL数据库产商的驱动程序的源代码,而是把MysqL数据库的驱动程序jar包解压了,找到了PreparedStatement.class文件,利用反编译工具,反编译了一下,如下:

这下大家应该知道PreparedStatement是如何防止sql注入的了吧

像222' OR '8'='8这样的sql注入还算温柔了,有些更可恶的用户,他们输入的非法的值是delete from tableName或truncate table tableName 这是十分危险的,更有甚者传入drop table tableName;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句执行,所以生产环境上一定要使用PreparedStatement,而不能使用Statement

下面再举几个例子,看截图

最终打印SELECT * FROM admin WHERE username = '韦小宝' AND password = ''; DROP TABLE tableName;#'

最终打印SELECT * FROM admin WHERE username = '韦小宝' AND password = ''; delete from tableName;#'

最终打印SELECT * FROM admin WHERE username = '韦小宝' AND password = ''; truncate table tableName;#'

下面是java代码和sql语句,供大家参考,主要是为了测试PreparedStatement对象,所以java代码写的比较粗略,大家凑合着看吧!

package com.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.sqlException; import java.sql.Statement; /* * 研究PreparedStatement是如何防止sql注入的,我分析了一下,原来是MysqL数据库产商,在实 * 现PreparedStatement接口的实现类中的setString(int parameterIndex, String x)函 * 数中做了一些处理,把单引号做了转义(只要用户输入的字符串中有单引号,那MysqL数据库产商的setString()这个函 * 数,就会把单引号做转义) */ public class TestConnMysqL2 { public static void main(String[] args) { String connStr = "jdbc:MysqL://localhost:3306/girls"; // String sql = "select * from admin"; String sql = "SELECT * FROM admin WHERE username = ? AND password = ?"; try { Class.forName("com.MysqL.jdbc.Driver"); Connection connection = DriverManager.getConnection(connStr, "root", "root"); System.out.println("数据库连接=" + connection); //Statement无法防止sql注入 // Statement stmt = connection.createStatement(); //PreparedStatement可以有效防止sql注入,所以生产环境上一定要使用PreparedStatement,而不能使用Statement PreparedStatement prepareStatement = connection.prepareStatement(sql); prepareStatement.setString(1, "韦小宝"); //模拟用户输入正常的值 // prepareStatement.setString(2, "222"); //测试sql注入(模拟用户输入非法的值) prepareStatement.setString(2, "222' OR '8'='8"); /* *上面那种的sql注入还算温柔了,有些更可恶的用户,他们输入的非 *法的值是delete from tableName或truncate table tableName 这是十分危险的, * 更有甚者传入drop table tableName;有些数据库是不会让你成功的,但也有很多数 * 据库就可以使这些语句执行,所以生产环境上一定要使用PreparedStatement,而不能使用Statement */ //测试sql注入(模拟用户输入非法的值)在MysqL中#井号表示单行注释(这是MysqL中的基础知识,我就不赘述了) // prepareStatement.setString(2, "'; DROP TABLE tableName;#"); //测试sql注入(模拟用户输入非法的值) // prepareStatement.setString(2, "'; delete from tableName;#"); //测试sql注入(模拟用户输入非法的值) // prepareStatement.setString(2, "'; truncate table tableName;#"); ResultSet rs = prepareStatement.executeQuery(); System.out.println("sql=" + prepareStatement.toString()); int col = rs.getMetaData().getColumnCount(); System.out.println("============================"); while (rs.next()) { for (int i = 1; i

#用户输入正常合法的值 SELECT * FROM admin WHERE username = '韦小宝' AND `password` = '222'; #用户输入正常合法的值 SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = '222'; #sql注入(用户输入非法的值)使用Statement对象,无法防止sql注入(会查询出表的所有数据) SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = '222' OR '8'='8' #sql注入(用户输入非法的值)使用PreparedStatement对象,可以有效防止sql注入 SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = '222' OR '8'='8' #sql注入(用户输入非法的值)使用Statement对象,无法防止sql注入(DROP操作很危险) SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; DROP TABLE tableName;#' #sql注入(用户输入非法的值)使用PreparedStatement对象,可以有效防止sql注入 SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; DROP TABLE tableName;#' #sql注入(用户输入非法的值)使用Statement对象,无法防止sql注入(TruncATE操作很危险) SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; TruncATE TABLE tableName;#' #sql注入(用户输入非法的值)使用PreparedStatement对象,可以有效防止sql注入 SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; truncate table tableName;#' #sql注入(用户输入非法的值)使用Statement对象,无法防止sql注入(DELETE操作很危险) SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; DELETE FROM tableName;#' #sql注入(用户输入非法的值)使用PreparedStatement对象,可以有效防止sql注入 SELECT * FROM admin WHERE username = '韦小宝' AND PASSWORD = ''; delete from tableName;#' #所以生产环境上一定要使用PreparedStatement,而不能使用Statement /* 顺便复习一下MysqL中的3种注释,我是多行注释 */ #我是单行注释 -- 我也是单行注释(注意:-- 这种注释,后面必须要加一个空格,否则语法报错)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。

jdbc PreparedStatement 方式向Oracle批量插入数据怎么取Sequence的值?

jdbc PreparedStatement 方式向Oracle批量插入数据怎么取Sequence的值?

jdbc PreparedStatement 方式向Oracle批量插入数据怎么取Sequence的值?代码如下:

String sql = "insert into employee (id, name, city, phone) values (seq_emp.NextVal,?, ?, ?)";
Connection connection = new getConnection();
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement(sql);
 for (Employee employee: employees) {
    ps.setString(1, employee.getName());
    ps.setString(2, employee.getCity());
    ps.setString(3, employee.getPhone());
    ps.addBatch();
}
ps.executeBatch();
connection.commit();
这样提交了5条记录,数据库只有一条,可能是Sequence的值相同,数据覆盖了, 问题就是这种情况怎么取Sequence?

今天的关于Oracle jdbc中的PreparedStatement和setTimestamporacle.jdbc.readtimeout的分享已经结束,谢谢您的关注,如果想了解更多关于java.sql.PreparedStatement不能转换为com.mysql.jdbc.PreparedStatement、Java中PreparedStatement和Statement的用法区别、java中PreparedStatement和Statement详细讲解、jdbc PreparedStatement 方式向Oracle批量插入数据怎么取Sequence的值?的相关知识,请在本站进行查询。

本文标签: