JDBC课程4--使用PreparedStatement进行增删查改, JDBCTools新增对应的的功能,模拟SQL注入
Posted 好好学习,天天向上
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC课程4--使用PreparedStatement进行增删查改, JDBCTools新增对应的的功能,模拟SQL注入相关的知识,希望对你有一定的参考价值。
主要内容:
熟悉了使用PreparedStatement的优势,没有使用封装和使用封装的方法进行实现了;
以及JDBCTools新增update_sql(String sql,Object...args) 和query_sql(String sql,Object...args)两个功能模块,分别实现了SQL的update和select的功能.
了解了sql注入,以及实现了模拟注入和PreparedStatement阻止注入的样例.
PreparedStatement的使用步骤:
1.创建PreparedStatement,创建同时传入一个sql
* String sql="insert into examstudent values(?,?,?)";
* //2.调用PreparedStatement 的setXXX(int index,Object val)设置占位符的值,
* Index从1开始,
* //3.使用方法执行SQL语句: 执行 查询 或者 升级 : executeQuery() 或executeUpdate()
* //因此,省略了SQl语句
1 使用PreparedStatement, 没有使用封装和使用封装的方法进行实现
package day_19; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; /* SQL 的date()需要传入参数值: preparedStatement().setDate(new java.util.Date().getTime()); */ /**PreparedStatement 优势:减轻sql语句的大量书写, * 1/是Statement的子接口,可以使用其所有方法 * 2/可以传入带占位符的SQL语句,并且提供了补充占位符变量的方法. * 3/可以有效地防止SQL注入! * 4/提高性能,使用一次就编译好了sql母句,节省时间; * -------------------- * //1.创建PreparedStatement,创建同时传入一个sql * String sql="insert into examstudent values(?,?,?)"; * //2.调用PreparedStatement 的setXXX(int index,Object val)设置占位符的值, * Index从1开始, * //3.使用方法执行SQL语句: 执行 查询 或者 升级 : executeQuery() 或executeUpdate() * //因此,省略了SQl语句 */ public class testPreparedStatement { @Test //使用封装进JDBCTools的update_sql(sql,args1)的方法进行测试;最后直接进行preparedStatement.executeUpdate(); public void test1(){ String sql="insert into author(id,author_name,nation,second_nation) " + "values(?,?,?,?)"; Object args1[]=new Object[]{4,"刘慈欣","北京","河北"}; Object args2[]=new Object[]{5,"瑞","元星","阿斯加特"}; JDBCTools.update_sql(sql,args1); JDBCTools.update_sql(sql,args2); } //没有使用封装的方法进行 public void test2(){ Connection connection=null; PreparedStatement preparedStatement=null; try { connection=JDBCTools.getConnection(); String sql="insert into author(id,author_name,nation) " + "values(?,?,?,?)"; preparedStatement =connection.prepareStatement(sql); preparedStatement.setInt(1, 3); preparedStatement.setString(2, "山枫叶纷飞233"); preparedStatement.setString(3, "中国"); //执行Update更新语句 preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.release(null,preparedStatement,connection); } } }
2 JDBC的工具类
package day_19; import java.io.InputStream; import java.sql.*; import java.util.Properties; /**操纵JDBC的工具类,其中封装了一些工具方法 * Version 1 : getConnection() : 通过读取配置文件从数据库服务器获取一个连接; * Version 2 : release() : 关闭数据库资源的ResultSet/Statement/Statement * Version 3 : update_sql() : 添加preparedStatement的select的sql的方法 * Version 4: query_sql() : 执行preparedStatement的的查询操作! */ public class JDBCTools { /*** 执行sql 语句,使用Preparedstatement * @param sql * @param args */ public static void update_sql(String sql,Object...args){//添加preparedStatement的update更新sql的方法,同理可以实现 : 增删改 Connection connection=null; PreparedStatement preparedStatement=null; try { connection = JDBCTools.getConnection(); preparedStatement=connection.prepareStatement(sql); for(int i=0;i<args.length;i++){ preparedStatement.setObject(i+1, args[i]); } preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { release(null,preparedStatement ,connection); } } //添加preparedStatement的select的sql的方法 public static void query_sql(String sql,Object...args){//执行preparedStatement的的查询操作! Connection connection=null; PreparedStatement preparedStatement=null; try { connection = JDBCTools.getConnection(); preparedStatement=connection.prepareStatement(sql); for(int i=0;i<args.length;i++){ preparedStatement.setObject(i+1, args[i]); } ResultSet resultSet=null; resultSet=preparedStatement.executeQuery();//执行查询操作! if(resultSet.next()) System.out.println("RsultSet查询已经就绪!"); else System.out.println("数据表为空或者404!"); } catch (Exception e) { e.printStackTrace(); } finally { release(null,preparedStatement ,connection); } } public static void release(ResultSet rs,Statement statement, Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement!=null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e2) { e2.printStackTrace(); } } } public static Connection getConnection() throws Exception{ //1.准备数据库的连接的四个字符串 String driverClass=null,jdbcUrl=null,user=null,password=null; //jdbc:mysql:///books ;也可以将localhost省略掉! //2.读取类路径下的jdbc.properties 文件 InputStream in= JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties"); Properties properties =new Properties(); properties.load(in); driverClass =properties.getProperty("driver"); jdbcUrl=properties.getProperty("jdbcUrl"); user = properties.getProperty("user"); password = properties.getProperty("password"); //3.加载数据库驱动程序(注册驱动),driver对应的实现类中有注册驱动的静态代码块 // Class.forName(driverClass); // //或这么手动加载,也可以注册多个数据库连接的代码块 //DriverManager.registerDriver( Class.forName(driverClass).newInstance()); //4.通过DriverManager 的getConnection()方法获取数据库连接。 Connection connection=DriverManager.getConnection(jdbcUrl,user,password); System.out.print(connection); //[email protected] return connection; } }
3 testSQLInjection
package day_19; import org.junit.Test; import javax.swing.text.DocumentFilter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class testSQLInjection { /**使用 * */ @Test //因为匹配结果恒真,就可以进行SQL注入!使用PreparedStatement可以避免这个问题! public void testSQLInjection(){ String username = "a‘ OR PASSWORD = "; String password = " OR ‘1‘=‘1"; String sql = "SELECT * FROM users WHERE username = ‘" + username + "‘ AND " + "password = ‘" + password + "‘"; System.out.println(sql); Connection connection=null; Statement statement=null; ResultSet resultSet=null; try { connection=JDBCTools.getConnection(); statement=connection.createStatement(); resultSet=statement.executeQuery(sql); if(resultSet.next()) System.out.println("登陆成功!"); else System.out.println("404 ! "); /*******/ System.out.println("PreparedStatement测试结果为:"); String sql2 = "SELECT * FROM users WHERE username = ? AND password = ?"; JDBCTools.query_sql(sql2,username,password); } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.release(resultSet, statement,connection ); } } }
以上是关于JDBC课程4--使用PreparedStatement进行增删查改, JDBCTools新增对应的的功能,模拟SQL注入的主要内容,如果未能解决你的问题,请参考以下文章
如何将 JDBC4PreparedStatement 与期望 OUT 参数的 MySQL 存储过程一起使用?
JDBC课程4--使用PreparedStatement进行增删查改, JDBCTools新增对应的的功能,模拟SQL注入