04.JDBC编程之指定变量&批处理
来源:互联网 发布:攻壳机动队95知乎 编辑:程序博客网 时间:2024/06/05 20:37
转载请标明出处:http://blog.csdn.net/u012637501
一、指定SQL语句中的变量
1.PreparedStatement接口
PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。 包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN参数的值在 SQL 语句创建时未被指定。相反的,该语句为每个 IN 参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX 方法来提供。另外,作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数。
由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率。为此,在JDBC应用中应该始终以PreparedStatement代替Statement,即尽量不要使用Statement。
Interface PreparedStatement(java.sql)
boolean
execute()
Executes the SQL statement in this
PreparedStatement
object, which may be any kind of SQL statement.ResultSet
executeQuery()
Executes the SQL query in this
PreparedStatement
object and returns the ResultSet
object generated by the query.int
executeUpdate()
Executes the SQL statement in this
PreparedStatement
object, which must be an SQL Data Manipulation Language (DML) statement, such as INSERT
, UPDATE
or DELETE
; or an SQL statement that returns nothing, such as a DDL statement.void
setDouble(int parameterIndex, double x)
Sets the designated parameter to the given Java
double
value.void
setFloat(int parameterIndex, float x)
Sets the designated parameter to the given Java
float
value.void
setInt(int parameterIndex, int x)
Sets the designated parameter to the given Java
int
value.void
setLong(int parameterIndex, long x)
Sets the designated parameter to the given Java
long
value.void
setNull(int parameterIndex, int sqlType)
Sets the designated parameter to SQL
NULL
.void
setShort(int parameterIndex, short x)
Sets the designated parameter to the given Java
short
value.void
setSQLXML(int parameterIndex, SQLXML xmlObject)
Sets the designated parameter to the given
java.sql.SQLXML
object.void
setString(int parameterIndex, String x)
Sets the designated parameter to the given Java
String
value.void
setURL(int parameterIndex, URL x)
Sets the designated parameter to the given
java.net.URL
value2.优点
(1)代码的可读性和可维护性
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次。下面分别使用Statement、PrepareStatement执行一条SQL语句
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 对象实例
(2)PreparedStatement尽最大可能提高性能
语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个函数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果,以保存有更多的空间存储新的预编译语句。
(3)最重要的一点是极大地提高了安全性
即使到目前为止,仍有一些人连基本的恶义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,;等做费尽心机的判断和过虑.
3.源码实战:
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- /*MySQL数据库编程
- * 实例(4):使用PreparedStatement灵活指定SQL语句中的变量*/
- public class JDBC_PreparedStatement {
- public static void main(String[] args) {
- if(args.length!=3) //输入不正确,非正常退出
- {
- System.out.println( "Parament Error,Please Input Again!");
- System.exit(-1);
- }
- String nameParam=args[0]; //获取命令行第一个参数
- int ageParam=Integer.parseInt(args[1]); //获取命令行第二个参数,并转换为整型
- int scoreParam=Integer.parseInt(args[2]);//获取命令行第三个参数,并转换为整型
- //0.连接数据库相关参数
- String url="jdbc:mysql://localhost:3306/jdbc_test_db"; //数据库URL(资源定位唯一标识符)
- String DBusername="root"; //数据库用户名
- String DBpasswd="111111"; //数据库密码
- //1.加载数据库驱动,将Driver注册到DriverManager中
- try{
- Class.forName("com.mysql.jdbc.Driver");
- }catch(ClassNotFoundException e){
- e.printStackTrace();
- }
- //2.通过数据库URL连接到数据库
- Connection conn=null;
- PreparedStatement prestmt=null;
- try{
- conn=DriverManager.getConnection(url, DBusername, DBpasswd);
- //3.获取PreparedStatement对象
- String sql="insert into test(name,age,score) values(?,?,?)";
- prestmt=conn.prepareStatement(sql);
- prestmt.setString(1, nameParam); //分别给变量设值
- prestmt.setInt(2, ageParam);
- prestmt.setInt(3, scoreParam);
- prestmt.execute();
- }catch(SQLException e){
- e.printStackTrace();
- }
- //5.释放JDBC资源
- if(prestmt!=null) //关闭声明
- {
- try{
- prestmt.close();
- }catch(SQLException e){
- e.printStackTrace();
- }
- }
- if(conn!=null) //关闭连接
- {
- try{
- conn.close();
- }catch(SQLException e){
- e.printStackTrace();
- }
- }
- }
- }
(1)设置命令行参数
右击工程->Run as->Open Run Dialog->Main Class选择"JDBC_PreparedStatement"
(2)运行结果
二、批处理SQL语句
(1)源代码
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- /*MySQL数据库编程
- * 实例(5):JDBC批量处理DML语句.分别尝试Statement、PreparedStatement*/
- public class JDBC_Batch {
- public static void main(String[] args) {
- //0.连接数据库相关参数
- String url="jdbc:mysql://localhost:3306/jdbc_test_db"; //数据库URL(资源定位唯一标识符)
- String DBusername="root"; //数据库用户名
- String DBpasswd="111111"; //数据库密码
- //1.加载数据库驱动,将Driver注册到DriverManager中
- try{
- Class.forName("com.mysql.jdbc.Driver");
- }catch(ClassNotFoundException e){
- e.printStackTrace();
- }
- //2.通过数据库URL连接到数据库
- Connection conn=null;
- PreparedStatement prestmt=null;
- try{
- conn=DriverManager.getConnection(url, DBusername, DBpasswd);
- //3.获取PreparedStatement对象
- String sql="insert into test(name,age,score) values(?,?,?)";
- prestmt=conn.prepareStatement(sql);
- prestmt.setString(1,"aaa");
- prestmt.setInt(2, 19);
- prestmt.setInt(3, 55);
- prestmt.execute(); //a.添加第一条插入记录
- prestmt.setString(1,"bbb");
- prestmt.setInt(2, 20);
- prestmt.setInt(3, 66);
- prestmt.execute(); //a.添加第二条插入记录
- prestmt.setString(1,"ccc");
- prestmt.setInt(2, 21);
- prestmt.setInt(3, 77);
- prestmt.execute(); //a.添加第三条插入记录
- }catch(SQLException e){
- e.printStackTrace();
- }
- //5.释放JDBC资源
- if(prestmt!=null) //关闭声明
- {
- try{
- prestmt.close();
- }catch(SQLException e){
- e.printStackTrace();
- }
- }
- if(conn!=null) //关闭连接
- {
- try{
- conn.close();
- }catch(SQLException e){
- e.printStackTrace();
- }
- }
- }
- }
(2)运行结果
说明分析:
这里使用的是SQL语句静态插入数据,我们也可以使用Statement的addBatch方法实现JDBC批量处理SQL语句
Statement stmt=conn.createStatement();
stmt.addBatch("insert into test(name,age,score) values('ppp',30,88)");
stmt.addBatch("insert into test(name,age,score) values('ooo',31,89)");
stmt.addBatch("insert into test(name,age,score) values('qqq',32,90)");
stmt.executeBatch(); //批量执行SQL语句
参考资料:
http://blog.sina.com.cn/s/blog_77eba18f01019csh.html
http://docs.oracle.com/javase/8/docs/api/index.html
0 0
- 04.JDBC编程之指定变量&批处理
- jdbc之批处理
- JDBC之批处理数据
- jdbc之批处理
- 批处理编程清除指定文件
- JDBC进阶之批处理 Batch
- JavaWeb学习心得之JDBC批处理
- Shell编程之getopts指定变量取值
- JDBC高级编程——批处理更新
- JDBC高级编程——批处理更新
- Windows批处理学习之批处理简单编程
- JDBC之批处理、事务、存储过程
- jdbc学习总结五之批处理
- JDBC批处理
- jdbc批处理
- JDBC批处理
- JDBC批处理
- jdbc批处理
- Java 基础 第二天
- 日常笔记
- 查找pop pop ret call dword ptr [esp+nn]指令的方法
- helloworld
- jvm 垃圾收集器
- 04.JDBC编程之指定变量&批处理
- JAVA知识(005)--分支和循环3
- 旅行家的预算
- android 事件分发机制(View)
- 上述代码是A对话框中“确定”按钮,在调用C对话框之前要先要自动弹出B对话框,怎么办?
- hdu 2838 Cow Sorting 树状数组
- 疯狂Java之学习笔记(20)-----------类型转换
- 中间件学习——基础知识一步曲
- Lotus Notes疑难杂症全攻略