JDBC与Statement和PreparedStatement的区别
一、先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。具体步骤:
1.首先导入java.sql.*;这个包。
2.然后加载驱动,创建连接,得到Connection接口的的实现对象,比如对象名叫做conn。
3.然后再用conn对象去创建Statement的实例,方法是:Statement stmt = conn.creatStatement("SQL语句字符串");
Statement 对象用于将 SQL 语句发送到数据库中。实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL语句的包容器:Statement、PreparedStatement(它从 Statement 继承而来)和CallableStatement(它从 PreparedStatement 继承而来)。它们都专用于发送特定类型的 SQL 语句:Statement 对象用于执行不带参数的简单 SQL 语句;PreparedStatement 对象用于执行带或不带参数的预编译 SQL 语句;CallableStatement 对象用于执行对数据库已存储过程的调用。
综上所述,总结如下:Statement每次执行sql语句,数据库都要执行sql语句的编译,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.但存在sql注入风险。PreparedStatement是预编译执行的。在执行可变参数的一条SQL时,PreparedStatement要比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率高。安全性更好,有效防止SQL注入的问题。对于多次重复执行的语句,使用Prepared
Statement效率会更高一点。执行SQL语句是可以带参数的,并支持批量执行SQL。由于采用了Cache机制,则预编译的语句,就会放在Cache中,下次执行相同的SQL语句时,则可以直接从Cache中取出来。
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET name= ? WHERE ID = ?");
pstmt.setString(1, "李四");
pstmt.setInt(2, 1);
pstmt. executeUpdate();
那么CallableStatement扩展了PreparedStatement的接口,用来调用存储过程,它提供了对于输入和输出参数的支持,CallableStatement 接口还有对 PreparedStatement 接口提供的输入参数的sql查询的支持。
PreparedStatement: 数据库会对sql语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率(但尽量采用
使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用。
从安全性上来看,PreparedStatement是通过?来传递参数的,避免了拼sql而出现sql注入的问题,所以安全性较好。
在开发中,推荐使用 PreparedStatement
二、
本人的几点浅见,各位大大不喜勿喷。
先说下这俩到底是干啥的吧。其实这俩干的活儿都一样,就是创建了一个对象然后去通过对象调用executeQuery方法来执行sql语句。说是CreateStatement和PrepareStatement的区别,但其实说的就是Statement和PrepareStatement的区别,相信大家在网上已经看到过不少这方面的资料和博客,我在此处提几点,大家看到过的,就当重记忆,没看到就当补充~下面开始谈谈他们的区别。
最明显的区别,就是执行的sql语句格式不同。我们往上放两段代码来看看他们的区别把:
代码背景:我们有一个数据库,里面有一个user表,有username,userpwd两列。我们要查出这两列的数据。
这是使用CreateStatement方法创建了stmt对象,再通过他查询的一部分语句片段。
String sql = "select * from users where username= '"+username+"' and userpwd='"+userpwd+"'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
而下面则是使用了PrepareStatement方法创建了pstmt对象,再通过这个对象查询的一部分语句片段。
String sql = "select * from users where username=? and userpwd=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, userpwd);
rs = pstmt.executeQuery();
相信写到这,大家很多人就能看出来了,原来PrepareStatement跟Statement的主要区别就是把上面sql语句中的变量抽出来了。这就是我要说的第一大优点,PrepareStatement可以提高代码的可读性。
下面说说第二点优点。ParperStatement提高了代码的灵活性和执行效率。
PrepareStatement接口是Statement接口的子接口,他继承了Statement接口的所有功能。它主要是拿来解决我们使用Statement对象多次执行同一个SQL语句的效率问题的。ParperStatement接口的机制是在数据库支持预编译的情况下预先将SQL语句编译,当多次执行这条SQL语句时,可以直接执行编译好的SQL语句,这样就大大提高了程序的灵活性和执行效率。
最后但也是最重要的一个大大的比Statement好的优点,那就是安全!
你说啥?这还关安全啥事儿,那我给你一行代码,你来给我说说这是干嘛的。
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);
这是验证用户名密码的,对吧。但要是我们把'or '1' = 1'当作密码传进去,你猜猜会发生啥。
select * from user where username = 'user' and userpwd = '' or '1' = '1';
发现了吧!这是个永真式,因为1永远等于1。所以不管怎样都能获取到权限。哇。这就坏咯!这还不是最坏的,你再看!
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);
依旧是这行代码。这次我们把'or '1' = 1';drop table book;当成密码传进去。哇!又坏了!这次直接把表给删了。但是,你如果用PrepareStatement的话就不会出现这种问题。你传入的这些数据根本不会跟原来的数据有任何的交集,也不会发生这些问题。
对数据库进行增删改查的过程中的通用的流程:
(1)创建Connection对象、SQL查询命令字符串;
(2)对Connection对象传入SQL查询命令,获得PreparedStatement对象;
(3)对PreparedStatement对象执行executeUpdate()或executeQurey()获得结果;
(4)先后关闭PreparedStatement对象和Connection对象。
可见,使用JDBC时,最常打交道的是Connection、PreparedStatement这两个类,以及select中的ResultSet类。查阅Java API手册可以了解其具体的意义和方法。
下面引用的Java API的资料出自http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/index.html。
Connection
java.sql
接口 Connection
- 所有超级接口:
- Wrapper
public interface Connectionextends Wrapper与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
Connection对象的数据库能够提供描述其表、所支持的 SQL 语法、存储过程、此连接功能等等的信息。此信息是使用getMetaData方法获得的。
PreparedStatemnt
java.sql
接口 PreparedStatement
- 所有已知子接口:
- CallableStatement
public interface PreparedStatementextends Statement表示预编译的 SQL 语句的对象。
SQL 语句被预编译并存储在
PreparedStatement对象中。然后可以使用此对象多次高效地执行该语句。常用方法
boolean execute()
在此 PreparedStatement 对象中执行 SQL 语句,该语句可以是任何种类的 SQL 语句。
ResultSet executeQuery()
在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
int executeUpdate()
在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。
ResultSet
java.sql
接口 ResultSet
- 所有超级接口:
- Wrapper
- 所有已知子接口:
- CachedRowSet, FilteredRowSet, JdbcRowSet, JoinRowSet, RowSet, SyncResolver, WebRowSet
public interface ResultSetextends Wrapper表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
JDBC与Statement和PreparedStatement的区别的更多相关文章
- JDBC中的Statement和PreparedStatement的区别
JDBC中的Statement和PreparedStatement的区别
- Statement与PreparedStatement的区别
Statement与PreparedStatement的区别 PreparedStatement预编译SQL语句,性能好. PreparedStatement无序拼接SQL语句,编程更简单. Pr ...
- 浅析Statement和PreparedStatement的区别
当我们使用java程序来操作sql server时会使用到Statement和PreparedStatement,俩者都可以用于把sql语句从java程序中发送到指定数据库,并执行sql语句.那么如何 ...
- Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入?
问题一:Statement和PreparedStatement的区别 先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接 ...
- Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入? (转)
问题一:Statement和PreparedStatement的区别 先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接 ...
- [转] JDBC中的Statement和PreparedStatement的区别
以Oracle为例吧 Statement为一条Sql语句生成执行计划,如果要执行两条sql语句select colume from table where colume=1;select colume ...
- jdbc中Statement和PreparedStatement有什么区别?哪个性能更好?
Statement和PreparedStatement的功能主要是对sql语句的执行 区别 (1)Statement每执行一条sql语句就需要生成一条执行计划,执行100条就需要100条执行计划Pre ...
- JDBC中的Statement 和PreparedStatement的区别?
PreparedStatement是预编译的SQL语句,效率高于Statement. PreparedStatement支持操作符,相对于Statement更加灵活. PreparedStatemen ...
- 7.秋招复习简单整理之请你讲讲 Statement 和 PreparedStatement 的区别?哪个性能更好?
Statement和PreparedStatement都是数据库用于执行SQL语句的句柄,但是PreparedStatement代表一个预编译的SQL. 以下是PreparedStatement和St ...
随机推荐
- Scrum之初体验
一.前言 入职两个月,作为新人,没有参加过一次早晨的scrum会议. 最大的感触就是,有一天中午,带我的开发哥哥突然说产品今天下午提测,我突然就懵了. 这算是我体会的最大的团队中人没有参加scrum, ...
- Web前端面试指导(八):iframe有那些缺点
本题的特点 这道题目的特点就是不按照正常的套路来提问,一般都是问优点,这里比较反常问iframe的缺点,很多同学肯定很不习惯这种问答,因为平时只关注有点,这么一问就懵逼了! 本题解答的思路及要点 ① ...
- 隐藏 google 地图 Logo 隐藏 百度 地图 Logo
Google 地图 var isFirstLoad=true; //地图瓦片加载完成之后的回调 google.maps.event.addListener(map, 'tilesloaded', fu ...
- 关于maven包的引入net.sf.json的问题
最开始通过在pom.xml文件中加入 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId& ...
- Fiddler-修改HTTP请求参数
在进行 App 测试时,经常需要修改请求参数,以获得不同的显示效果,以查看相应的页面显示处理.例如:可以通过修改 HTTP请求 的参数,来获取不同的响应结果. 下面以修改 HTTP请求的商品系统编号为 ...
- solidity语言3
#函数类型(function type) function (<parameter types>) {internal|external(public)} [pure|constant|v ...
- how reset smartphone data.
question:how reset meizu smartphone solution one:hard step 1. power off your MEIZU smartphone. ste ...
- Exchange 2016中的削减内容
一.从Exchange 2013到Exchange 2016所废弃的功能. 在Exchange 2016中已经有部分Exchange 2013的功能不在提供支持. 1.体系结构 功能 注释和缓解操作 ...
- Sql Server中一次更新多列数据
UPATE yourTableName SET column1 = xx, column2 = yy , column3 = zz WHERE yourCondition 举个例子,比如有这样一张表: ...
- Android(java)学习笔记42:Map集合的获取功能
1. Map集合的获取功能: package cn.itcast_01; import java.util.Collection; import java.util.HashMap; import ...