【JDBC】day02_PreparedStatement_元数据
1.PreparedStatement
1)Statement将SQL语句发送给数据库后,数据库首先要理解该SQL语句的含义,然后制定一个执行计划,这个过程时比较耗时耗资源的,当指定完毕后,数据库就会执行这个计划然后将结果返回.
所以,若使用Statement执行若干条语义相同但是数据不同的SQL时,数据库会认为它们时不同的SQL语句,而为每一条SQL都制定执行计划这对数据库来讲开销是非常大的!
再加上Statement还存在SQL注入攻击的风险,所以得出结论:Statement只适合执行静态SQL语句.(SQL中不含有动态数据)
2)当SQL语句中含有动态信息时,由于Statement不适合做,所以JDBC提供了另一种专门用来执行动态SQL语句的Statement:PreparedStatement
PreparedStatement是Statement的子类.其需要执行预编译SQL语句(动态数据用?代替),然后每次执行SQL语句时只需要将动态信息传给数据库即可,数据库会重用执行计划.
3)创建PreparedStatement的同时,就要先将预编译SQL语句发送给数据库,这时,数据库就会理解该SQL的含义,并制定执行计划,由于有?的存在,该SQL还不能执行.但好处是我们每次只需要将?需要的值传递给数据库即可,这样可以重用该执行计划(因为语义没变).减小了数据库开销,也提高了SQL执行效率.
* 预编译SQL注意事项:
* ?不需要加单引号,不需要在这里关心数据类型
* ?只能是"值"的占位替代,不能作为其他内容的占位.原因是
* 预编译的SQL语义必须确定.
package day02;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 当SQL语句中含有动态信息时,由于Statement不适合做,所以JDBC提供了
* 另一种专门用来执行动态SQL语句的Statement:PreparedStatement
* PreparedStatement是Statement的子类.其需要执行预编译SQL语句(动态
* 数据用?代替),然后每次执行SQL语句时只需要将动态信息传给数据库即可,
* 数据库会重用执行计划.
*
*/
public class JDBCDemo2 {
public static void main(String[] args) {
Connection conn = null;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.201.203:1521:orcl",
"openlab","open123");
/*
* 预编译的SQL语句,动态信息用?代替
*/
String sql = "INSERT INTO userinfo_qxl " +
"(id,username,password,email,account) " +
"VALUES" +
"(seq_userinfo_qxl_id.NEXTVAL,?,'123',?,?)";
/*
* 创建PreparedStatement的同时,就要先将预编译SQL语句发送给
* 数据库,这时,数据库就会理解该SQL的含义,并制定执行计划,由于
* 有?的存在,该SQL还不能执行.但好处是我们每次只需要将?需要的
* 值传递给数据库即可,这样可以重用该执行计划(因为语义没变).减小
* 了数据库开销,也提高了SQL执行效率.
*
* 预编译SQL注意事项:
* ?不需要加单引号,不需要在这里关心数据类型
* ?只能是"值"的占位替代,不能作为其他内容的占位.原因是
* 预编译的SQL语义必须确定.
*/
PreparedStatement ps = conn.prepareStatement(sql);
for(int i=201;i<=300;i++){
ps.setString(1,"test"+i);
ps.setString(2,"test"+i+"@qq.com");
ps.setInt(3,1000+i*10);
ps.executeUpdate();
}
System.out.println("INSERT OVER");
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.元数据
1)获取结果集中的元数据
* 通过元数据,可以得到结果集中有多少个字段,字段叫什么名,字段是什么类型等等信息.
2)通过结果集获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
3)通过元数据查看结果集中总共有多少个字段?
int colCount = rsmd.getColumnCount();
package day02;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 获取结果集中的元数据
* 通过元数据,可以得到结果集中有多少个字段,字段叫什么名,
* 字段是什么类型等等信息.
*
*/
public class JDBCDemo5 {
public static void main(String[] args) {
Connection conn = null;
try{
conn = DBUtil.getConnection();
Statement state = conn.createStatement();
String sql = "SELECT * " +
"FROM userinfo_qxl ";
ResultSet rs = state.executeQuery(sql);
/*
* 通过结果集获取元数据
*/
ResultSetMetaData rsmd = rs.getMetaData();
/*
* 通过元数据查看结果集中总共有多少个字段?
*/
int colCount = rsmd.getColumnCount();
System.out.println("colCount:"+colCount);
for(int i=1;i<=colCount;i++){
String colName = rsmd.getColumnName(i);
System.out.println(i+"--"+colName);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}