java JDBC 编程之ResultSet , Statement 和 PrepareStatement

这里写自定义目录标题

ResultSet[结果集]

基本介绍

  1. 表示数据库结果集的数据表,通常通过执行查询数据库的指令生成
  2. ResultSet 对象持有一个光标指向当前数据行,最初光标位于第一行之前
  3. next() 方法将光标移向下一行,当没有更多行的时候返回false,因此可以用while循环来遍历结果集

案例

演示查询数据库jdbc中的actor表,返回actor表的id,name,sex,borndate 列

    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
        //获取配置信息
        Properties properties = new Properties();
        properties.load(new FileReader("src/mysql.properties"));
        String url=properties.getProperty("url");
        String user=properties.getProperty("user");
        String password=properties.getProperty("password");
        String driver=properties.getProperty("driver");
        //利用反射加载Driver类
        Class.forName(driver);
        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //发送sql查询语句
        //查询数据库jdbc中的actor表,返回actor表的id,name,sex,borndate 列
        //结果应为:
        /*
                +----+------+-----+---------------------+
                | id | name | sex | borndate            |
                +----+------+-----+---------------------+
                |  1 | tom  | 男  | 2001-10-05 00:00:00 |
                |  2 | jack | 男  | 2002-02-25 00:00:00 |
                +----+------+-----+---------------------+
         */
        String select="select id, name, sex, borndate from actor;";
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(select); //返回查询过后的结果集(也就是表的数据)
        //对resultSet 遍历得到数据
        // 可以认为在resultSet对象中,有一个光标指向表头,resultSet.next()就是把光标移向下一行,如果到头了,就返回false
        while (resultSet.next()){
            int id = resultSet.getInt(1);//得到表的第一列数据,由于第一返回的第一列是id ,所以用整型来接收
            String name = resultSet.getString(2);
            String sex = resultSet.getString(3);
            Date borndate = resultSet.getDate(4);
            System.out.println("\t"+id+"\t"+name+"\t"+sex+"\t" +borndate+"\t");//打印数据
        }
        //关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }

输出:

	1	tom	男	2001-10-05	
	2	jack	男	2002-02-25	

Statement

基本介绍:

  1. Statement 用于执行静态的sql语句,并返回其生成的结果的对象.
  2. 在连接建立后,需要对数据库进行访问,执行,命名或是sql语句,可以通过:
    Statement [存在SQL注入]
    PreparedStatement [预处理]
    CallableStatement [存储过程]
  3. Statement对象执行sql语句,存在SQL注入风险
  4. SQL注入是指某些系统没有对用户输入的数据进行充分的检查,而在用户的输入数据中执行非法的sql语句,攻击数据库
  5. 要防范SQL注入,只要用PreparedStatement(Statement扩展而来)来取代Statement就好了

演示SQL注入:

 //演示SQL注入
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
        //获取配置信息
        Properties properties = new Properties();
        properties.load(new FileReader("src/mysql.properties"));
        String url=properties.getProperty("url");
        String user=properties.getProperty("user");
        String password=properties.getProperty("password");
        String driver=properties.getProperty("driver");
        //利用反射加载Driver类
        Class.forName(driver);
        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //获取用户输入的用户名和密码
        //这里只有用户名是tom,密码是123是合法的
        Scanner input = new Scanner(System.in);
        System.out.print("请输入用户名: ");
        String user_name  = input.nextLine();
        System.out.print("请输入密码: ");
        String user_password=input.nextLine();
        //执行sql语句
        String select ="select * from admin where `user`='"+user_name+
                "' and pwd='"+user_password+"';";
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(select);
        if(resultSet.next()){//如果查询到了数据,就打印登录成功,否则登录失败
            System.out.println("登录成功");
        }
        else {
            System.out.println("该用户不存在...");
        }
    }

上面这段代码要求用户输入用户名和密码,如果查询到用户输入的用户名和密码,就提示登录成功,否则提示该用户不存在.
如果像下面这样输入,则会提示登录成功:

请输入用户名: tom
请输入密码: 123
登录成功

如果像下面这样输入,则会提示该用户不存在:

请输入用户名: jack
请输入密码: 123
该用户不存在...

如果像下面这样输入,也会提示登录成功,但数据库中并没有该用户,于是就被SQL注入了:

请输入用户名: 1' or
请输入密码: or '1'='1
登录成功

PrepareStatement [预处理]

基本介绍:

  1. PreparedStatement执行的SQL语句的参数用"?"表示,调用PreparedStatement对象的setXxx()方法来设置这些参数, setXxx()方法有两个参数,第一个参数是设置sql语句中参数的索引(从1开始),第二个参数是设置sql语句参数的值
  2. 执行查询语句,调用executeQuery()方法返回ResultSet对象
  3. 执行更新(增,删,修改),调用executeUpdate()方法

预处理好处

  1. 不再使用+拼接SQL语句
  2. 有效解决了SQL注入问题
  3. 大大减少了编译次数,提高了效率

示例

 //PrepareStatement演示
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
        //获取配置信息
        Properties properties = new Properties();
        properties.load(new FileReader("src/mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
        //注册驱动
        Class.forName(driver);
        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //获取用户输入
        Scanner input = new Scanner(System.in);
        System.out.print("请输入用户名: ");
        String user_name  = input.nextLine();
        System.out.print("请输入密码: ");
        String user_password=input.nextLine();
        //发送SQL语句
        //在使用PereparedStatement的对象(实际上是实现了preparedStratement接口的类的对象)发送sql语句时,要用"?"做占位符
        String sql="select `user`,pwd from `admin` where `user`=? and `pwd`=?;";
        //在这里就将sql语句传入,以便对"?"做处理
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //用实际值填充占位符"?",第一个参数是:要填入数据的占位符"?"的位置(从1开始),第二个参数是数据
        preparedStatement.setString(1,user_name);
        preparedStatement.setString(2,user_password);
        //执行查询语句,使用executeQuery方法,返回结果集.(这里的实参不要填入sql语句,如果填入会将带"?"的sql语句填入,出现异常)
        //如果执行dml(插入,删除,更改)语句,用executeUpdate方法
        ResultSet resultSet = preparedStatement.executeQuery();
        if(resultSet.next()){
            System.out.println("登录成功");
        }
        else {
            System.out.println("登录失败");
        }
        //关闭连接
        resultSet.close();
        preparedStatement.close();
        connection.close();

    }

当想做SQL注入时,结果无法成功

请输入用户名: 1' or
请输入密码: or '1'='1
登录失败
全部评论

相关推荐

头像
11-06 10:58
已编辑
门头沟学院 嵌入式工程师
双非25想找富婆不想打工:哦,这该死的伦敦腔,我敢打赌,你简直是个天才,如果我有offer的话,我一定用offer狠狠的打在你的脸上
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务