zoukankan      html  css  js  c++  java
  • Java PreparedStatement

    PreparedStatement是一个用于运行sql语句的标准接口的对象。它是继承与Statement。依据里氏代换原则。用Statement运行的语句,一定能够用Prepared替换了。那么他们之间有什么不同呢。

    PreparedStatement

    • 使用參数化的方式,能够用?表明变量的值位置,运行时依据位置提供变量的值。
    • 该对象是预编译的,多次运行的效率高
    • 安全性方面,高于Statement

    Statement

    • 运行没有參数,能够动态的运行sql
    • 没有预编译,每次都是运行。多次运行的效率低 

    以上是他们各自的特点。各自具有长处同一时候也具有自身的缺点。所以我们应依据不同的场合详细使用,不能说谁的长处多就使用谁,详细情况应该详细分析。比如,一个组合的sqlsql是动态的,因为Statement本身具有动态的运行sql特点,若安全性不高,首先考虑它还是非常好的选择。


    以下我们就做个对照 依据id查询

    Statement写法

    stringsql ="select * from people p where p.i = "+id;

    PreparedStatement写法

    stringsql ="select * from people p where p.id = ? ";
    preparedstatement ps= connection.preparestatement(sql);

    这个写法非常熟悉,.NET中是常见的。所以并没有学习什么新奇的东西。

    以上两种写法是截然不同的。记得在vb中我经常使用的是statment的写法,那么还不知道什么是sql注入,等师父验收的使用,不费吹灰之力就进入了我的系统。而假设使用PreparedStatement就不存在这样的方式。验证例如以下

    String sql ="select * from tb_name where name= '"+varname+"' andpasswd='"+varpasswd+"'";
    select* from tb_name = '任意' and passwd = '' or '1' = '1';

    由于'1'='1'肯定成立,所以能够不论什么通过验证。甚至知道表明就能够删除里面的全部数据了。

    当然了这是statement的缺点。而假设你使用预编译语句.你传入的不论什么内容就不会和原来的语句发生不论什么匹配的关系.仅仅要全使用预编译语句,你就用不着对传入的数据做不论什么过虑.而假设使用普通的statement,有可能要对drop,;等做费尽心机的推断和过虑.

    怎样使用PreparedStatement

    1引入特定包

    importjava.sql.PreparedStatement;

    importjava.sql.ResultSet;

    2实例化PreparedStatement和结果集

    PreparedStatementprepstmt = null;

    ResultSetrs = null;

    3得到sql语句

    conn 为Connection类型

    prepstmt= conn.prepareStatement(String StrSQl);

    4运行sql,得到结果集

    rs 为ResultSet类型。

    rs= prepstmt.executeQuery(); 

    一个完整的事例

    importjava.sql.Connection;
    importjava.sql.PreparedStatement;//
    import java.sql.ResultSet;//结果集包
    importjava.sql.SQLException;
    importjava.sql.Statement;
    importjava.sql.Timestamp;
    importjava.util.ArrayList;
    importjava.util.Date;
    importjava.util.List;
     
    importcom.bjpower.drp.sysmgr.domain.User;
    importcom.bjpower.drp.util.DbUtil;
    importcom.bjpower.drp.util.PageModel;
     
    /**
     * 依据用户代码查询用户
     * @param userId
     * @return
     * @throws SQLException
     */
    publicUser findUserById(String userId) throws Exception {
    StringBuffersql= new StringBuffer();
    sql.append("selectuser_id, user_name, password, contact_tel, email, create_date from t_user  where user_id= ?");
    Connection conn=null;//连接
    PreparedStatement pstmt=null;//实例化PreparedStatement 
    ResultSet rs= null;//实例化结果集,存放PreparedStatement查询的结果
    User user=null;//返回的User实体对象
    try{
    conn= DbUtil.getconnection();//创建数据库连接
    pstmt=conn.prepareStatement(sql.toString());//得到sql语句
    pstmt.setString(1, userId);//传入參数
    rs=pstmt.executeQuery();//运行sql语句,得到结果集
    //User对象得到结果集中的值
    if(rs.next()){
    user=newUser();
     
    user.setUserId(rs.getString("user_id"));
    user.setUserName(rs.getString("user_name"));
    user.setPassword(rs.getString("password"));
    user.setContactTel(rs.getString("contact_tel"));
    user.setEmail(rs.getString("email"));        
    user.setCreateDate(rs.getTimestamp("create_date"));        
    }
    }catch(SQLExceptione){
    e.printStackTrace(); 
    }finally{
    //关闭连接
    DbUtil.close(rs);
    DbUtil.close(pstmt);
    DbUtil.close(conn);
    }
    returnuser;
    }
     

    小结

    以上是PreparedStatement的基本使用。非常向自己在.net中编写的sqlParameter的结合体。知识都是类似的,这次并没什么新东西。回想对照下,仅仅是多了几个包的引用。继续加油了。


  • 相关阅读:
    高性能Javascript 选择器API学习笔记
    Backbone学习笔记二 Events
    递归用函数、存储过程实现的效果
    用触发器实现动态新增列
    局域网自动备份删除
    游标变量用法经典
    如何区分大小写字母、全角半角
    列的分拆显示
    2005的行列转换
    批量分离和附加数据库
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4250991.html
Copyright © 2011-2022 走看看