JDBC Statement PreparedStatement CallableStatement
时间:2022-03-14 03:47
在 JDBC 应用程序中,JDBC 语句对象用于将 SQL 语句发送到数据库服务器。一个语句对象与一个连接相关联,应用程序与数据库服务器之间的通信由语句对象来处理。
JDBC 中有三种类型的语句对象:
1. 常规语句(General statement)
2. 预置语句(Prepared statement)
3. 可调用语句(Callable statement)
语句对象与一个连接相关联,所以要创建一个语句对象,首先应该建立一个数据库连接。连接的获取见上一篇博客。
关于这三种语句,个人觉得最有价值的就是 预置语句,下面说说为什么
1)预置语句 可以避免sql参数注入。如果使用常规的statement,那么用户可以注入sql语句,把一个本应该是传入参数的变量变成了SQL注入变量。然而,如果使用预置语句,那么变量的值是不可能传入SQL的。这个在查询的时候如果你把条件设为 or 1=1 得到体现。
2)预置语句 可以高效操作,原因是语句只要编译一次。对于一条模板SQL,我们可能需要执行多次,每次只是传入的参数不一样,那么如果我们使用常规语句则会每次执行时在数据库编译一次,然而,如果采用预置语句,则只会编译一次,这样效率大大提高。
3)预置语句 可以批量操作。对于一些特殊的业务逻辑处理,我们可能会一次更新多条数据,然而如果我们每次都去获取语句执行SQL的话效率必然降低,但是,如果采用预置语句的批量操作,效率会提高很多。
4)关于可更新的结果集以及可滚动的结果集,在下一篇博客中结果集说明,注意批量操作与结果集的滚动与更新并不是预置语句独有的优点,常规语句也可以实现,预置语句两个特点就是预编译和防止SQL语句作为变量注入。
下面是对三种语句的详细介绍,内容转载自
可以使用连接的 createStatement
方法创建这种语句。这种语句专用于不需要传递任何值作为参数的 SQL 语句。
package Callable; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; public class out1 { static Connection conn; public static void main(String[] args) { getConnect(); System.out.println("Connection Established"); createProc(); runthis(); System.out.println("\n=============Finished============="); System.exit(0); } private static void getConnect() { try { Class.forName("com.informix.jdbc.IfxDriver"); String url = "jdbc:informix-sqli://host name or ip :porn number/database name:informixserver=dbservername;"; System.out.println("URL: "+url); conn = DriverManager.getConnection(url); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } } private static void createProc() { String str=null; Statement stmt = null; try { stmt = conn.createStatement(); } catch (SQLException e2) { e2.printStackTrace(); } str="drop function c_out_proc"; try { stmt.executeUpdate (str); } catch (SQLException e1) { } str = "create function c_out_proc ( i int, OUT d varchar(20) ) \n" + "returning float; \n" + "define f float; \n" + "let d= \"Hello OUT\"; \n" + "let f=i*2; \n" + "return f; \n" + "end function; \n"; try { stmt.executeUpdate (str); System.out.println("Function created \n"); } catch (SQLException e) { System.out.println("Error on creating function: " + e.toString()); System.exit(1); } } private static void runthis() { CallableStatement cstmt = null; String command = "{? = call c_out_proc(?, ?)} "; try { cstmt = conn.prepareCall (command); cstmt.setInt(1, 2); cstmt.registerOutParameter(2, Types.VARCHAR); ResultSet rs = cstmt.executeQuery(); if (rs == null) { System.out.println("rs is null *** this is BAD."); System.exit(0); } else { rs.next(); System.out.println(rs.getFloat(1)); System.out.println(cstmt.getString(2)); } } catch (SQLException e) { e.printStackTrace(); } } } |