- 浏览: 122759 次
- 性别:
- 来自: 杭州
最新评论
-
小幕天:
...
解决System.Data.OracleClient需要Oracle 客户端软件8.1.7或更高版本 -
u011922057:
使用final修饰变量会让变量的值不能被改变吗--楼主给的这一 ...
谈使用final关键字 -
一念思量LG:
路过,
谈使用final关键字 -
yuejingjiahong:
在搞并发下是有的
将不使用的对象置为NULL可以加快回收吗 -
a00589:
太感谢了 刚刚公司说发送的邮件看不了图片,我也纠结了半天,想都 ...
IE8打开GMAIL的邮件中的图片
PreparedStatement jdk的解释是
An object that represents a precompiled SQL statement. A SQL statement is precompiled and stored in a PreparedStatement object.
主要特点是:
1、提高了安全性,可以防止SQL注入;
2、调试不方便,看不到sql语句,需要额外使用p6spy等辅助包;
2、预编译语句。
并不是说PreparedStatement在所有的DB上都不会提高效率,PreparedStatement需要服务器端的支持,比如在Oracle上就会有显著效果。而MySQL比较明确地说明了不支持PreparedStatement。至于为什么预编译就会提高效率呢?因为oracle中会将所有的sql语句先编译,叫做“执行计划”,放在oracle内部的一个特定的缓存中,每次遇到相同的sql,就会预先调用缓存中,如果不预编译,每次都用statement,那么每次都要编译,在缓冲中会有很多重复的“执行计划”,影响数据库的效能。
还有一点就是在使用setObject()的时候,记得一定要使用带targetSqlType参数的方法,来提高效率。
以下是mysql驱动包中有关setObject()的源代码
public void setObject(int parameterIndex, Object parameterObj, int targetSqlType, int scale) throws SQLException { if (parameterObj == null) { setNull(parameterIndex, java.sql.Types.OTHER); } else { try { switch (targetSqlType) { case Types.BOOLEAN: if (parameterObj instanceof Boolean) { setBoolean(parameterIndex, ((Boolean) parameterObj) .booleanValue()); break; } else if (parameterObj instanceof String) { setBoolean(parameterIndex, "true" .equalsIgnoreCase((String) parameterObj) || !"0".equalsIgnoreCase((String) parameterObj)); break; } else if (parameterObj instanceof Number) { int intValue = ((Number) parameterObj).intValue(); setBoolean(parameterIndex, intValue != 0); break; } else { throw new SQLException("No conversion from " + parameterObj.getClass().getName() + " to Types.BOOLEAN possible.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } case Types.BIT: case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: case Types.REAL: case Types.FLOAT: case Types.DOUBLE: case Types.DECIMAL: case Types.NUMERIC: setNumericObject(parameterIndex, parameterObj, targetSqlType, scale); break; case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: if (parameterObj instanceof BigDecimal) { setString( parameterIndex, (StringUtils .fixDecimalExponent(StringUtils .consistentToString((BigDecimal) parameterObj)))); } else { setString(parameterIndex, parameterObj.toString()); } break; case Types.CLOB: if (parameterObj instanceof java.sql.Clob) { setClob(parameterIndex, (java.sql.Clob) parameterObj); } else { setString(parameterIndex, parameterObj.toString()); } break; case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: case Types.BLOB: if (parameterObj instanceof byte[]) { setBytes(parameterIndex, (byte[]) parameterObj); } else if (parameterObj instanceof java.sql.Blob) { setBlob(parameterIndex, (java.sql.Blob) parameterObj); } else { setBytes(parameterIndex, StringUtils.getBytes( parameterObj.toString(), this.charConverter, this.charEncoding, this.connection .getServerCharacterEncoding(), this.connection.parserKnowsUnicode())); } break; case Types.DATE: case Types.TIMESTAMP: java.util.Date parameterAsDate; if (parameterObj instanceof String) { ParsePosition pp = new ParsePosition(0); java.text.DateFormat sdf = new java.text.SimpleDateFormat( getDateTimePattern((String) parameterObj, false), Locale.US); parameterAsDate = sdf.parse((String) parameterObj, pp); } else { parameterAsDate = (java.util.Date) parameterObj; } switch (targetSqlType) { case Types.DATE: if (parameterAsDate instanceof java.sql.Date) { setDate(parameterIndex, (java.sql.Date) parameterAsDate); } else { setDate(parameterIndex, new java.sql.Date( parameterAsDate.getTime())); } break; case Types.TIMESTAMP: if (parameterAsDate instanceof java.sql.Timestamp) { setTimestamp(parameterIndex, (java.sql.Timestamp) parameterAsDate); } else { setTimestamp(parameterIndex, new java.sql.Timestamp(parameterAsDate .getTime())); } break; } break; case Types.TIME: if (parameterObj instanceof String) { java.text.DateFormat sdf = new java.text.SimpleDateFormat( getDateTimePattern((String) parameterObj, true), Locale.US); setTime(parameterIndex, new java.sql.Time(sdf.parse( (String) parameterObj).getTime())); } else if (parameterObj instanceof Timestamp) { Timestamp xT = (Timestamp) parameterObj; setTime(parameterIndex, new java.sql.Time(xT.getTime())); } else { setTime(parameterIndex, (java.sql.Time) parameterObj); } break; case Types.OTHER: setSerializableObject(parameterIndex, parameterObj); break; default: throw new SQLException(Messages .getString("PreparedStatement.16"), //$NON-NLS-1$ SQLError.SQL_STATE_GENERAL_ERROR); } } catch (Exception ex) { if (ex instanceof SQLException) { throw (SQLException) ex; } throw new SQLException( Messages.getString("PreparedStatement.17") //$NON-NLS-1$ + parameterObj.getClass().toString() + Messages.getString("PreparedStatement.18") //$NON-NLS-1$ + ex.getClass().getName() + Messages.getString("PreparedStatement.19") + ex.getMessage(), //$NON-NLS-1$ SQLError.SQL_STATE_GENERAL_ERROR); } } }
不带targetSqlType参数的setObject()方法
public void setObject(int parameterIndex, Object parameterObj) throws SQLException { if (parameterObj == null) { setNull(parameterIndex, java.sql.Types.OTHER); } else { if (parameterObj instanceof Byte) { setInt(parameterIndex, ((Byte) parameterObj).intValue()); } else if (parameterObj instanceof String) { setString(parameterIndex, (String) parameterObj); } else if (parameterObj instanceof BigDecimal) { setBigDecimal(parameterIndex, (BigDecimal) parameterObj); } else if (parameterObj instanceof Short) { setShort(parameterIndex, ((Short) parameterObj).shortValue()); } else if (parameterObj instanceof Integer) { setInt(parameterIndex, ((Integer) parameterObj).intValue()); } else if (parameterObj instanceof Long) { setLong(parameterIndex, ((Long) parameterObj).longValue()); } else if (parameterObj instanceof Float) { setFloat(parameterIndex, ((Float) parameterObj).floatValue()); } else if (parameterObj instanceof Double) { setDouble(parameterIndex, ((Double) parameterObj).doubleValue()); } else if (parameterObj instanceof byte[]) { setBytes(parameterIndex, (byte[]) parameterObj); } else if (parameterObj instanceof java.sql.Date) { setDate(parameterIndex, (java.sql.Date) parameterObj); } else if (parameterObj instanceof Time) { setTime(parameterIndex, (Time) parameterObj); } else if (parameterObj instanceof Timestamp) { setTimestamp(parameterIndex, (Timestamp) parameterObj); } else if (parameterObj instanceof Boolean) { setBoolean(parameterIndex, ((Boolean) parameterObj) .booleanValue()); } else if (parameterObj instanceof InputStream) { setBinaryStream(parameterIndex, (InputStream) parameterObj, -1); } else if (parameterObj instanceof java.sql.Blob) { setBlob(parameterIndex, (java.sql.Blob) parameterObj); } else if (parameterObj instanceof java.sql.Clob) { setClob(parameterIndex, (java.sql.Clob) parameterObj); } else if (parameterObj instanceof java.util.Date) { setTimestamp(parameterIndex, new Timestamp( ((java.util.Date) parameterObj).getTime())); } else if (parameterObj instanceof BigInteger) { setString(parameterIndex, parameterObj.toString()); } else { setSerializableObject(parameterIndex, parameterObj); } } }
所以大家不要为了省事,而使用不带targetSqlType参数的setObject()方法。
Statement是PreparedStatement的父接口,
主要特点是:
1、易于调试;
2、不进行预编译操作,减少了进行预编译的开销。单次运行PreparedStatement要比Statement要慢一些
这里有个对比:http://www.onjava.com/lpt/a/1480
Table 19-3: OCI driver timings (in milliseconds) | ||
Inserts |
Statement |
PreparedStatement |
1 |
10 |
113 |
1,000 |
2,804 |
1,412 |
The important thing to notice about the graph is that it's not until about 65 inserts that the PreparedStatement
object outperforms the Statement
object. 65 inserts
综上:
Statement和PreparedStatement,都有其优缺点,但总体而言,强烈建议使用Statement的同学改为使用PreparedStatement,如果希望调试方便,再加个p6spy等包做辅助,看到的sql语句效果更好。毕竟许多应用中,都要考安全性、大用户量时候的性能问题。像hibernate、toplink这种jpa在使用jdbc的时候,如果数据库端支持,都很统一的使用了PreparedStatement。
如:oracle.toplink.essentials.internal.databaseaccess.DatabasePlatform类。
顺便再讲一下,程序员写出来的sql语句是最值得去关注的,一条效率差的sql语句,足以毁掉整个应用。
评论
这样,可以在类的常量定义部分,直接看到SQL语句,直接审查、直接修改。而不用到各个方法里面找。
比如:
public class Test {
public static final String SELECT_SQL="select * from tablea";
public Collection getAll() {
pstmt=conn.prepareStatement( SELECT-SQL );
}
}
------------------
权限管理圈子欢迎您:
http://accessmanager.group.iteye.com/
发表评论
-
forward,include,redirect学习
2009-04-16 23:50 1854查了一下API, forward: 有 ... -
如何测试才能看出效果?迷惑,为什么先执行的方法用的时间要长很多?
2009-04-13 23:19 945以下的代码: import java.util.ArrayLi ... -
重载equals方法就一定要要重载hashCode方法
2009-04-10 14:04 4642在进行对象之间的比较的时候,一般都会override ... -
谈使用final关键字
2009-04-05 01:20 2757使用final关键字修饰类、方法和变量的作用大家都知道。 ... -
三种不同的编译(javac命令)方式
2009-04-03 00:53 1401代码为: import java.util.Hashtable ... -
将不使用的对象置为NULL可以加快回收吗
2009-04-03 00:44 2047一直听说将不用的对象置为NULL,可以加迅被GC回收 ... -
解决eclipse与myeclipse调试的时候代码不一致的问题
2009-03-27 20:40 4194现在开发Java大部分都用eclipse,而插件用my ... -
利用jacob将word另存为html格式文件
2009-03-27 20:37 1247由于任务要有从OA与网站数据交换这个需求,在OA中编辑的都是w ... -
导出notes中的word doc附件
2009-03-21 15:37 1788在工作中,经常要将notes库中的附件导出成为本地文件,如wo ... -
用Javascript评估用户输入密码的强度
2009-03-21 15:36 693转载 用Javascript评估用户输入密码的强度收藏 密码已 ... -
apachebench介绍
2009-03-21 15:35 1166ab是Apache超文本传输协 ... -
有关有效使用final关键字的准则
2009-03-16 10:04 622final 关键字常常被误用 - 声明类和方法时使用过度 ... -
使用java调用delphi程序包装的VclZip
2009-03-06 14:46 1274在项目中使用了金格控件处理excel,由于是互联网应用 ... -
java axis调用带有soap头(soapheader)的.net webservice
2008-12-29 12:45 16031有很多同学问我使用axis调用.net带soapheader的 ...
相关推荐
Java 中 PreparedStatement 和 Statement 的区别 Java 中的 PreparedStatement 和 Statement 都是用于执行 SQL 语句的接口,但是它们之间存在一些关键的区别。 首先,从数据库执行 SQL 语句的角度来看,使用 ...
Statement和PreparedStatement之间的区别 Statement和PreparedStatement是JDBC中的两种不同的语句对象,用于执行数据库操作。虽然它们都可以执行SQL语句,但是它们之间存在着很大的区别。 首先, Statement对象...
jdbc中preparedStatement比Statement的好处
这个项目可能包含了使用`PreparedStatement`和`Statement`的例子,通过分析这些代码,你可以更好地理解两者的应用和区别。 总结,`PreparedStatement`和`Statement`在Java数据库操作中各有优势。在追求性能、安全性...
Java面试题34.jdbc中preparedStatement比Statement的好处.mp4
首先,从创建时的区别开始,Statement 需要通过 Connection 对象的 createStatement() 方法创建,而 PreparedStatement 需要通过 Connection 对象的 prepareStatement() 方法创建,并且需要带有 SQL 语句。...
NULL 博文链接:https://chaoyi.iteye.com/blog/2088080
在使用Java语言进行数据库交互时,JDBC(Java Database Connectivity)是实现...总之,理解Statement和PreparedStatement之间的区别,能够帮助我们更好地使用JDBC进行数据库操作,从而编写出更加高效、安全的Java程序。
`PreparedStatement`是`Statement`接口的子接口,用于预编译SQL语句,并可以重复执行这些预编译过的SQL语句。这不仅能够提高应用程序的性能,还能提高安全性,因为它支持参数化查询,避免了SQL注入的风险。 #### 二...
2. 批量处理:使用`Statement`或`PreparedStatement`的`addBatch()`和`executeBatch()`方法进行批量SQL操作,减少网络通信次数。 3. 数据库连接池:通过连接池管理数据库连接,避免频繁创建和关闭连接,提高系统效率...
一种可能的方法是通过日志配置,例如,启用MySQL的`Statement`和`PreparedStatement`日志,这样在执行时会打印出详细的SQL语句。 另外,开发工具如IntelliJ IDEA、Eclipse等,或者数据库管理工具如MySQL Workbench...
### PreparedStatement的详细...综上所述,无论从性能、安全性还是数据库无关性的角度,`PreparedStatement`都是比`Statement`更为优秀的选择,因此,在实际开发中,应尽可能地采用`PreparedStatement`来执行SQL语句。
- **作用**:提供了与数据库交互的基本手段,如创建`Statement`、`PreparedStatement`或`CallableStatement`等对象。 - **生命周期管理**: - **获取连接**:通常通过`DataSource`或直接使用`DriverManager`来获取...
#### 二、`PreparedStatement`与`Statement`的区别 1. **预编译的SQL语句**: - `PreparedStatement`实例包含已编译的SQL语句,这意味着当创建此类对象时,SQL语句会被解析和编译,而不是在每次执行时都进行解析。...
在Java编程中,PreparedStatement是Java SQL API中的一个接口,它是Statement接口的子接口。这个练习主要涉及如何使用PreparedStatement来插入宠物信息到数据库中。PreparedStatement的主要优势在于它的预编译能力和...
在Java的JDBC(Java Database Connectivity)中,与数据库交互的核心接口是Statement和PreparedStatement。这两个接口都是用于执行SQL语句的,但它们在特性和效率上有所不同。 Statement接口是最基本的SQL执行方式...
在Java编程语言中,`PreparedStatement`是`java.sql`包中的一个接口,它继承自`Statement`类,并提供了预编译SQL语句的功能。预编译SQL语句的主要优势在于提高了执行效率和安全性。尤其在处理动态查询或频繁执行相同...
在实际开发中,为了提高效率和安全性,我们通常会使用PreparedStatement接口来代替Statement接口。 1. **PreparedStatement简介** PreparedStatement是Statement的一个子接口,它的主要优势在于预编译。预编译的...
JDBC 中 PreparedStatement 接口提供的 execute、executeQuery 和 executeUpdate 之间的区别及用法 JDBC 中的 PreparedStatement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和 execute。...