【JDBC】day02_PreparedStatement_元数据

17 篇文章 0 订阅
6 篇文章 0 订阅

【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();
				}
			}
		}
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值