• JDBC之PreparedStatement 详解


    简介

    PreparedStatement 是一个特殊的Statement对象,如果我们只是来查询或者更新数据的话,最好用PreparedStatement代替Statement,因为它有以下有点:

    1. 简化Statement中的操作
    2. 提高执行语句的性能
    3. 可读性和可维护性更好
    4. 安全性更好。
    5. 使用PreparedStatement能够预防SQL注入攻击,所谓SQL注入,指的是通过把SQL命令插入到Web表单提交或者输入域名或者页面请求的查询字符串,最终达到欺骗服务器,达到执行恶意SQL命令的目的。注入只对SQL语句的编译过程有破坏作用,而执行阶段只是把输入串作为数据处理,不再需要对SQL语句进行解析,因此也就避免了类似select * from user where name='aa' and password='bb' or 1=1的sql注入问题的发生。

    Statement 和 PreparedStatement之间的关系和区别.

    • 关系:PreparedStatement继承自Statement,都是接口
    • 区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高

    入门使用

    创建PreparedStatement

    创建一个PreparedStatement PreparedStatement对象的创建也同样离不开 DriverManger.getConnect()对象,因为它也是建立在连接到数据库之上的操作。

          /** 1. init PreparedStatement*/
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
            String username = "root";
            String password = "root";
            Connection connection = DriverManager.getConnection(url, username, password);
            String sql = "update user set username=? where id = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
    

    设置入参

    往PreparedStatement里写入参数

    看上面那个sql 字符串,中间有几个?,它在这里有点占位符的意思,然后我们可以通过PreparedStatement的setString(),等方法来给占位符进行赋值,使得sql语句变得灵活。

            /** 2. prepare param*/
            preparedStatement.setString(1, "feifz");
            preparedStatement.setInt(2, 2);
    

    参数中的第一个参数分别是1和2,它代表的是第几个问号的位置。如果sql语句中只有一个问号,那就不用声明这个参数。

    执行更新

     /** 3. execute update*/
      int result = preparedStatement.executeUpdate();
      System.out.printf("更新记录数:"+result+"
    ");
    

    结果:

    更新记录数:1
    

    执行查询

    如果是执行查询数据库的话,也像Statement对象执行excuteQuery()一样返回一个ResultSet结果集。

    /** 4. execute select*/
    String sql2 = "select * from user";
            ResultSet resultSet = preparedStatement.executeQuery(sql2);
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String dept = resultSet.getString("dept");
                System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
            }
    

    执行结果:

    id:1username->Fant.J,dept-> 测试部
    id:2username->feifz,dept-> 研发部
    id:3username->xixi,dept-> 产品部
    id:4username->hah,dept-> 集成部
    id:5username->zeze,dept-> 研发部
    

    完整代码

    package com.github.feifuzeng.middleware.mybatis.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    /**
     * @author feifz
     * @version 1.0.0
     * @Description PreparedStatement简单demo
     * @createTime 2019年08月29日 20:21:00
     */
    public class PrepareStatementSimpleDemo {
    
        public static void main(String[] args) throws Exception {
    
            /** 1. init PreparedStatement*/
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
            String user = "root";
            String password = "root";
            Connection connection = DriverManager.getConnection(url, user, password);
            String sql = "update user set username=? where id = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
            /** 2. prepare param*/
            preparedStatement.setString(1, "feifz");
            preparedStatement.setInt(2, 2);
    
            /** 3. execute update*/
            int result = preparedStatement.executeUpdate();
            System.out.printf("更新记录数:"+result+"
    ");
    
            /** 4. execute select*/
    
            String sql2 = "select * from user";
            ResultSet resultSet = preparedStatement.executeQuery(sql2);
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String dept = resultSet.getString("dept");
                System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
            }
    
    
        }
    }
    
    

    参考

    1. https://juejin.im/post/5abb78c8f265da23994e9643

    结语

    欢迎关注微信公众号『码仔zonE』,专注于分享Java、云计算相关内容,包括SpringBoot、SpringCloud、微服务、Docker、Kubernetes、Python等领域相关技术干货,期待与您相遇!

  • 相关阅读:
    DockerAPI版本不匹配的问题
    Linux文件系统
    队列

    多维数组
    字符串
    线性表
    ARM编辑、编译工具
    南京IT公司
    数据结构:用单链表实现的队列(2)
  • 原文地址:https://www.cnblogs.com/feifuzeng/p/13626497.html
Copyright © 2020-2023  润新知