《Java SQL 操纵指南:深入明白 Statement 用法与优化》

打印 上一主题 下一主题

主题 999|帖子 999|积分 2997

在 Java 数据库编程中,Statement 是用于实行 SQL 语句的接口,允许程序与数据库进行交互。本文将详细先容 Statement 的基本概念、常见用法以及 PreparedStatement 和 CallableStatement 等相关接口。
1. Statement 基本先容


Statement 接口继承了 AutoCloseable 和 Wrapper 接口,使其具备自动关闭和封装功能。


  • AutoCloseable:提供 close() 方法,确保 Statement 在不再利用时释放资源。
  • Wrapper:提供 isWrapperFor(Class<?>) 和 unwrap(Class<T>) 方法,允许 Statement 作为其他数据库 API 的封装。
        别的,Statement 还包含多个重要属性,如 cursorName、poolable、connection 等。
Statement 是 JDBC 提供的用于实行 SQL 语句的接口,主要特点如下:

  • 适用于实行静态 SQL 语句,每次实行都需要编译。
  • 通过 executeQuery() 实行查询语句,返回 ResultSet。
  • 通过 executeUpdate() 实行更新语句,返回影响的行数。
  • 存在 SQL 注入风险,发起利用 PreparedStatement 取代。
2. Statement 的基本用法

  1. package JDBC;
  2. import java.io.FileInputStream;
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.ResultSet;
  6. import java.sql.Statement;
  7. import java.util.Properties;
  8. import java.util.Scanner;
  9. //JDBC注入机制演示
  10. public class Statement_ {
  11.     public static void main(String[] args) throws Exception {
  12. //        Class.forName("com.mysql.jdbc.Driver");
  13.         Scanner scanner = new Scanner(System.in);
  14.         System.out.println("Enter SQL nameusr statement");
  15.         String username =scanner.nextLine();
  16.         System.out.println("Enter SQL pwd statement");
  17.         String pwd =scanner.nextLine();
  18.         Properties properties = new Properties();
  19.         properties.load(new FileInputStream("src\\JDBC\\mysql.properties"));
  20.         String url = (String) properties.get("url");
  21.         String user =(String) properties.get("user");
  22.         String password =(String) properties.get("password");
  23.         String driver =(String) properties.get("driver");
  24. //        实例化
  25.         Class.forName(driver);
  26.         Connection connection = DriverManager.getConnection(url, user, password);
  27. //        得到statement
  28.         Statement statement = connection.createStatement();
  29. //        组织查询语句
  30.         String sql = "select * from sql_injection where NAME='"+username+"'and  pwd = '"+pwd+"';" ;
  31.         System.out.printf(sql+"\n");
  32.         ResultSet resultSet = statement.executeQuery(sql);
  33.         if (resultSet.next()) {
  34.             System.out.println("查询成功");
  35.         }
  36.         else {
  37.             System.out.println("查询失败");
  38.         }
  39. //        关闭连接,安全操作
  40.         resultSet.close();
  41.         statement.close();
  42.         connection.close();
  43.     }
  44. }
复制代码
 2.1 主要方法




  • execute(String sql): 实行 SQL 语句,返回 boolean,如果实行的是查询语句,返回 true,否则返回 false。
  • executeQuery(String sql): 仅用于 SELECT 语句,返回 ResultSet。
  • executeUpdate(String sql): 仅用于 INSERT、UPDATE 或 DELETE 语句,返回受影响的行数。
  • addBatch(String sql): 添加 SQL 语句到批处理下令中。
  • executeBatch(): 实行批处理下令,返回每条 SQL 语句影响的行数。
  • clearBatch(): 扫除已添加的批处理下令。
  • setQueryTimeout(int seconds): 设置查询超时时间。
  • getMoreResults(): 查抄是否存在多个 ResultSet。
  • close(): 关闭 Statement,释放资源。
2.2 实行更新操纵

可以利用 executeUpdate() 进行 INSERT、UPDATE 和 DELETE 操纵,例如:
  1. Statement stmt = conn.createStatement();
  2. int rowsAffected = stmt.executeUpdate("UPDATE users SET age = 30 WHERE id = 1");
  3. System.out.println("更新影响的行数: " + rowsAffected);
复制代码

3. Statement 的问题与优化

3.1 SQL 注入风险

利用 Statement 直接拼接 SQL 语句大概会导致 SQL 注入攻击,例如:
  1. USE mydatabase;
  2. SHOW DATABASES;
  3. SHOW TABLES;
  4. CREATE TABLE sql_injection  ( -- 管理表
  5.         NAME VARCHAR(32) NOT NULL UNIQUE,
  6.         pwd VARCHAR(32) NOT NULL DEFAULT ''
  7. )CHARACTER SET utf8;
  8. DROP TABLE sql_injection;
  9. DESC sql_injection;
  10. INSERT INTO sql_injection VALUES( 'wangya' ,'1314520'
  11. );
  12. SELECT * FROM sql_injection;
  13. SELECT *  FROM  sql_injection
  14.         WHERE NAME='wangya' AND pwd='1314520';
  15. -- sql 注入演示
  16. -- 用户输入密码为: 1' or
  17. -- 输入密码为:or '1'= '1
  18. SELECT *  FROM  sql_injection
  19.         WHERE NAME='1' OR' or AND pwd='OR '1'= '1';
  20. SELECT *  FROM  sql_injection
  21.         WHERE NAME='wangya' OR pwd='1314520'  OR '1'='1' ;
复制代码

以上代码大概被攻击者利用,绕过暗码验证。
总结

Statement 是 Java 数据库操纵的基本接口,但由于其存在 SQL 注入风险,在现实开发中推荐利用 PreparedStatement。别的,CallableStatement 适用于调用存储过程,提高数据库访问服从。了解并正确利用这些接口,可以提升数据库操纵的安全性和性能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表