使用Statement操作数据表的弊端

  • 通过调用Connection对象的createStatement()方法创建Statement对象,该对象用于执行静态的SQL语句,并且返回执行结果。
  • Statement接口中定义了如下的方法用于执行SQL:
    • 执行更新操作INSERT、UPDATE、DELETE:

int executeUpdate(String sql) throws SQLException;

  • 执行查询操作SELECT:

ResultSet executeQuery(String sql) throws SQLException;

  • 但是使用Statement操作数据表存在弊端:
    • ① 存在拼接SQL操作,非常繁琐。
    • ② 存在SQL注入问题。
  • SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令(如:SELECT user, password FROM user_table WHERE user=’a’ AND password = ‘123 OR ‘1’ = ‘1’) ,从而利用系统的 SQL 引擎完成恶意行为的做法。
  • 对于Java而言,要防范SQL注入,只要用PreparedStatement(从Statement扩展而来) 取代Statement就可以了。

使用PreparedStatement实现CRUD操作 - 图1

原表:
image.png

Create

  1. public class JDBC_test1{
  2. private void Create(Connection connection) throws SQLException {
  3. //预编译SQL语句
  4. String SQL = "INSERT INTO t_user(id,username,password,email) values(?,?,?,?)";
  5. PreparedStatement preparedStatement = connection.prepareStatement(SQL);
  6. //填充占位符
  7. preparedStatement.setInt(1,2);
  8. preparedStatement.setString(2,"tan");
  9. preparedStatement.setString(3,"8080");
  10. preparedStatement.setString(4,"@tan.com");
  11. preparedStatement.setInt(1,4);
  12. preparedStatement.setString(2,"luo");
  13. preparedStatement.setString(3,"123456");
  14. preparedStatement.setString(4,"@luo.com");
  15. //执行操作
  16. preparedStatement.execute();
  17. //关闭资源
  18. if(preparedStatement!=null){preparedStatement.close();}
  19. if(connection!=null){connection.close();}
  20. }
  21. public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
  22. //加载配置文件
  23. InputStream inputStream=JDBC_test1.class.getClassLoader().getResourceAsStream("jdbc.properties");
  24. Properties properties=new Properties();
  25. properties.load(inputStream);
  26. //读取配置文件
  27. String url = properties.getProperty("url");
  28. String username = properties.getProperty("username");
  29. String password = properties.getProperty("password");
  30. String driverClassName = properties.getProperty("driverClassName");
  31. //加载驱动
  32. Class<?> aClass = Class.forName(driverClassName);
  33. //获取连接
  34. Connection connection= DriverManager.getConnection(url,username,password);
  35. //调用方法
  36. JDBC_test1 jdbc_test1=new JDBC_test1();
  37. jdbc_test1.Create(connection);
  38. }
  39. }
  40. }

image.png
以下操作类似,只给出方法

Delete

  1. //删除操作
  2. private void Delete(Connection connection) throws SQLException {
  3. //预编译SQL语句
  4. String SQL ="DELETE FROM t_user WHERE id=1";
  5. PreparedStatement preparedStatement = connection.prepareStatement(SQL);
  6. //执行
  7. preparedStatement.execute();
  8. //关闭资源
  9. if(preparedStatement!=null){preparedStatement.close();}
  10. if(connection!=null){connection.close();}
  11. }

image.png

Update

  1. //更新操作
  2. private void Update(Connection connection) throws SQLException {
  3. //预编译SQL语句
  4. String SQL = "UPDATE t_user set email=? WHERE id=?";
  5. PreparedStatement preparedStatement=connection.prepareStatement(SQL);
  6. //填充占位符
  7. preparedStatement.setString(1,"tan@gmail.com");
  8. preparedStatement.setInt(2,2);
  9. //执行
  10. preparedStatement.execute();
  11. //关闭资源
  12. if(preparedStatement!=null){preparedStatement.close();}
  13. if(connection!=null){connection.close();}
  14. }

image.png

Retrieve

  1. private void Retrieve(Connection connection) throws SQLException {
  2. //预编SQL语句
  3. String SQL ="SELECT * FROM t_user";
  4. PreparedStatement preparedStatement=connection.prepareStatement(SQL);
  5. //执行
  6. ResultSet resultSet=preparedStatement.executeQuery();
  7. while (resultSet.next()){
  8. System.out.println("id="+resultSet.getObject("id"));
  9. System.out.println("username="+resultSet.getObject("username"));
  10. System.out.println("password="+resultSet.getObject("password"));
  11. System.out.println("email="+resultSet.getObject("email"));
  12. }
  13. //关闭资源
  14. if(preparedStatement!=null){preparedStatement.close();}
  15. if(connection!=null){connection.close();}
  16. }

image.png