由数据库对sql的执行说JDBC的Statement和PreparedStatement

简介:
1.每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.

2.PreparedStatement在conn.prepareStatement(sql)时就把sql语句传给它,这样它会在数据库端进行预编译(包含占位符),下次execute或者executeQuery时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行。其实这并不是说只有一个Connection中多次执行的预编译语句被缓存,这是PreparedStatement借助数据库的编译sql语句的原理来实现的优先做法而已。
  Statement在conn.createStatement()时不传sql语句,而是在execute或者executeQuery时传过去死的sql语句。这样使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.
 
3.使用Statement要给它传死的拼接的sql语句,其实这样做是很不安全的,有发生恶意sql语句注入的危险。比如:
  String sql="select * from t_user where name='zhangs' and passwd='zhangs123'"
  而我恶意给你注入一个"or 1=1",就成了
  String sql="select * from t_user where name='zhangs' and passwd='zhangs123' or 1=1"
  这样,你的密码就失去了功效。
  
  小结,PreparedStatement在使用上的优势是显而易见的,当然,它的开销会比Statement达一些,但我觉得功能第一,任何情况下还是首选PreparedStatement。
   下面是我分别用两个Statement和PreparedStatement写的用来增删改查的操作:
/** 
* Statement是先用Connection得到一个空的执行器,在执行的时候给它传拼好的死的sql 
* @author Administrator 

*/
 
public  class StatementCRUDtest { 

   /** 
    * 操作表jdbc_users 
    * @param args 
    */
 
   public  static  void main(String[] args) { 
    User u= new User(); 
    u.setId(45); 
    u.setName( "statement"); 
    u.setPasswd( "yf123"); 
    u.setPhone( "13821930"); 
    u.setEmail( "yf@163.com"); 
     //insert(u); 
     
     //delete(2); 
     
     //reset(u); 
     
    System.out.println(getById(45)); 
  } 
   /**增*/ 
   public  static  void insert(User user){ 
    Connection conn= null
    Statement stmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      stmt=conn.createStatement(); //Statement创建时就是一个空的执行器 
       /**在execute或者executeQuery时执行死的sql语句*/ 
       /**这只能是拼好的字符串,而不能动态的传参数,并且在数据库中每次肯定穿的是不同的sql语句,因此每次都要解析编译*/ 
      stmt.execute( "insert into jdbc_users values ("+user.getId()+ ",'"+user.getName()+ "','"+user.getPasswd()+ "','"+user.getPhone()+ "','"+user.getEmail()+ "')"); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(stmt!= null){ try{stmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**删*/ 
   public  static  void delete(Integer id){ 
    Connection conn= null
    Statement stmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      stmt=conn.createStatement(); //Statement创建时就是一个空的执行器 
       /**在execute或者executeQuery时执行死的sql语句*/ 
       /**这只能是拼好的字符串,而不能动态的传参数,并且在数据库中每次肯定穿的是不同的sql语句,因此每次都要解析编译*/ 
      stmt.execute( "delete from jdbc_users where id="+id); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(stmt!= null){ try{stmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**改*/ 
   public  static  void reset(User user){ 
    Connection conn= null
    Statement stmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      stmt=conn.createStatement(); //Statement创建时就是一个空的执行器 
       /**在execute或者executeQuery时执行死的sql语句*/ 
       /**这只能是拼好的字符串,而不能动态的传参数,并且在数据库中每次肯定穿的是不同的sql语句,因此每次都要解析编译*/ 
      String sql= "update jdbc_users set name='"+user.getName()+ "',passwd='"+user.getPasswd()+ "',phone='"+user.getPhone()+ "',email='"+user.getEmail()+ "' where id="+user.getId(); 
      System.out.println(sql); 
      stmt.execute(sql); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(stmt!= null){ try{stmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**查*/ 
   public  static User getById(Integer id){ 
    Connection conn= null
    Statement stmt= null
    ResultSet rs= null
    User u= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      stmt=conn.createStatement(); //Statement创建时就是一个空的执行器 
       /**在execute或者executeQuery时执行死的sql语句*/ 
       /**这只能是拼好的字符串,而不能动态的传参数,并且在数据库中每次肯定穿的是不同的sql语句,因此每次都要解析编译*/ 
      String sql= "select * from jdbc_users where id="+id; 
      System.out.println(sql); 
      rs=stmt.executeQuery(sql); 
       while(rs.next()){ 
        u= new User(); 
        u.setId(rs.getInt( "id")); 
        u.setName(rs.getString( "name")); 
        u.setPhone(rs.getString( "phone")); 
        u.setPasswd(rs.getString( "passwd")); 
        u.setEmail(rs.getString( "email")); 
      } 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(stmt!= null){ try{stmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
     return u; 
  } 

/** 
* PreparedStatement是在创建pstm的时候就给它传一个动态的sql,参数是通过pstm设置的。执行时,只需要空执行一下就可以. 
* @author Administrator 

*/
 
public  class PreparedStatementCRUDtest { 

   /** 
    * 操作表jdbc_users 
    * @param args 
    */
 
   public  static  void main(String[] args) { 
    User u= new User(); 
    u.setId(21); 
    u.setName( "statement"); 
    u.setPasswd( "yf123"); 
    u.setPhone( "13821930"); 
    u.setEmail( "yf@163.com"); 
     //insert(u); 
     
     //delete(42); 
     
     //reset(u); 
     
    System.out.println(getById(21)); 
  } 
   /**增*/ 
   public  static  void insert(User user){ 
    Connection conn= null
    PreparedStatement pstmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      String sql= "insert into jdbc_users values(?,?,?,?,?)"
      pstmt=conn.prepareStatement(sql); //PreparedStatement创建时就传过去一个sql语句,这样就可以预编译 
       /**然后设置sql中好占位符的值,这里是动态的传参数*/ 
      pstmt.setInt(1, user.getId()); 
      pstmt.setString(2, user.getName()); 
      pstmt.setString(3, user.getPasswd()); 
      pstmt.setString(4, user.getPhone()); 
      pstmt.setString(5, user.getEmail()); 
       /**设置好后,就全封装到pstm里了,只要空执行就可以了*/ 
      pstmt.execute(); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(pstmt!= null){ try{pstmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**删*/ 
   public  static  void delete(Integer id){ 
    Connection conn= null
    PreparedStatement pstmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      String sql= "delete from jdbc_users where id=?"
       /**PreparedStatement创建时就传过去一个sql语句,这样就可以预编译*/ 
      pstmt=conn.prepareStatement(sql); 
       /**然后设置sql中好占位符的值,这里是动态的传参数*/ 
      pstmt.setInt(1, id); 
       /**设置好后,就全封装到pstm里了,只要空执行就可以了*/ 
      pstmt.execute(); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(pstmt!= null){ try{pstmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**改*/ 
   public  static  void reset(User u){ 
    Connection conn= null
    PreparedStatement pstmt= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      String sql= "update jdbc_users set name=?,passwd=?,phone=?,email=? where id=?"
       /**PreparedStatement创建时就传过去一个sql语句,这样就可以预编译*/ 
      pstmt=conn.prepareStatement(sql); 
       /**然后设置sql中好占位符的值,这里是动态的传参数*/ 
      pstmt.setString(1, u.getName()); 
      pstmt.setString(2, u.getPasswd()); 
      pstmt.setString(3, u.getPhone()); 
      pstmt.setString(4, u.getEmail()); 
      pstmt.setInt(5, u.getId()); 
       /**设置好后,就全封装到pstm里了,只要空执行就可以了*/ 
      pstmt.execute(); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(pstmt!= null){ try{pstmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
  } 
    
   /**查*/ 
   public  static User getById(Integer id){ 
    Connection conn= null
    PreparedStatement pstmt= null
    ResultSet rs= null
    User u= null
     try { 
      Class.forName( "oracle.jdbc.driver.OracleDriver"); 
       //conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL10","scott","yf123"); 
      conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:ORCL10""SCOTT""yf123"); 
      String sql= "select * from jdbc_users where id=?"
      pstmt=conn.prepareStatement(sql); //Statement创建时就是一个空的执行器 
       /**在execute或者executeQuery时执行死的sql语句*/ 
       /**这只能是拼好的字符串,而不能动态的传参数,并且在数据库中每次肯定穿的是不同的sql语句,因此每次都要解析编译*/ 
      pstmt.setInt(1, id); 
      rs=pstmt.executeQuery(); 
       while(rs.next()){ 
        u= new User(); 
        u.setId(rs.getInt( "id")); 
        u.setName(rs.getString( "name")); 
        u.setPhone(rs.getString( "phone")); 
        u.setPasswd(rs.getString( "passwd")); 
        u.setEmail(rs.getString( "email")); 
      } 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } finally
       if(pstmt!= null){ try{pstmt.close();} catch(Exception e){}} 
       if(conn!= null){ try{conn.close();} catch(Exception e){}} 
    } 
     return u; 
  } 



     本文转自NightWolves 51CTO博客,原文链接: http://blog.51cto.com/yangfei520/304484 ,如需转载请自行联系原作者

相关文章
|
10天前
|
SQL 机器学习/深度学习 人工智能
从“写SQL”到“聊数据”:NL2SQL如何用自然语言解锁数据库?
本文系统性地阐述了自然语言转SQL(NL2SQL) 技术如何让非技术背景的业务分析师实现数据自助查询,从而提升数据驱动决策的效率与准确性。
从“写SQL”到“聊数据”:NL2SQL如何用自然语言解锁数据库?
|
4月前
|
SQL 存储 关系型数据库
第二篇:关系型数据库的核心概念与 SQL 基础
本篇内容深入浅出地讲解了关系型数据库的核心概念与SQL基础,适合有一定计算机基础的学习者。文章涵盖数据库的基本操作(CRUD)、数据类型、表的创建与管理等内容,并通过实例解析SELECT、INSERT、UPDATE、DELETE等语句的用法。此外,还推荐了多种学习资源与实践建议,帮助读者巩固知识。学完后,你将掌握基础数据库操作,为后续高级学习铺平道路。
184 1
|
5月前
|
SQL 数据库 数据安全/隐私保护
数据库数据恢复——sql server数据库被加密的数据恢复案例
SQL server数据库数据故障: SQL server数据库被加密,无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密,文件名字被篡改。
|
3月前
|
SQL 关系型数据库 MySQL
Go语言数据库编程:使用 `database/sql` 与 MySQL/PostgreSQL
Go语言通过`database/sql`标准库提供统一数据库操作接口,支持MySQL、PostgreSQL等多种数据库。本文介绍了驱动安装、连接数据库、基本增删改查操作、预处理语句、事务处理及错误管理等内容,涵盖实际开发中常用的技巧与注意事项,适合快速掌握Go语言数据库编程基础。
201 62
|
2月前
|
SQL 缓存 监控
SqlRest让SQL秒变Http API,还支持20+数据库(含国产数据库)
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
|
2月前
|
SQL 存储 数据库
SQL Server Management Studio (SSMS) 21 - 微软数据库管理工具
SQL Server Management Studio (SSMS) 21 - 微软数据库管理工具
337 0
|
6月前
|
SQL Java 数据库连接
【YashanDB知识库】statement级别的触发器在jdbc接口调用executeBatch时被多次触发
statement级别的触发器在jdbc接口调用executeBatch时被多次触发
|
2月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
173 0
|
3月前
|
SQL 人工智能 关系型数据库
GitHub 热门!MindsDB 破解 AI + 数据库瓶颈,究竟有什么惊艳亮点?只需 SQL 即可实现智能预测
MindsDB 是一款将 AI 能力直接注入数据库的开源工具,支持 MySQL、PostgreSQL 等多种数据库连接,通过 SQL 即可完成模型训练与预测。它提供 AutoML 引擎、LLM 集成、联邦查询等功能,简化 MLOps 流程,实现数据到智能的无缝衔接。项目在 GitHub 上已获 32.4k 星,社区活跃,适用于客户流失预警、推荐系统、情感分析等场景。开发者无需深入模型细节,即可快速构建智能解决方案。项目地址:https://github.com/mindsdb/mindsdb。
228 0
|
5月前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。

热门文章

最新文章