• 2022-08-19 Mysql--preparedStatement(预编译)


    我们之前用的Statement对象向数据库发送要执行的语句,但是Statement有很多的不足

    1.大量的字符串拼接,代码可读性降低。

    2.sql注入:

    SQL注入有一个BUG:

            就是通过字符串的拼接,可以得到一个恒等的sql语句,可以跳过某些判断:

            ( "b' or '1' = '1" )--------这个语句返回值一定是true,所以可以通过任何的验证

    例如:

    这样无论用户名是什么都可以登陆成功。

    1. public static void main(String[] args) {
    2. login("zxcvzxcvzxcv","b' or '1' = '1");
    3. }
    4. public static void login(String username,String password) {
    5. Connection conn = null;
    6. Statement stmt = null;
    7. ResultSet rs = null;
    8. try {
    9. conn = JDBCUtil.getConnection();
    10. stmt = conn.createStatement();
    11. String sql = "select * from user where username = '"
    12. + username + "' and password = '" + password + "'";
    13. System.out.println("sql:" + sql);
    14. rs = stmt.executeQuery(sql);
    15. if(rs.next()){
    16. System.out.println("登录成功,欢迎回来:" + username);
    17. }else {
    18. System.out.println("账号或密码错误!");
    19. }
    20. } catch (SQLException e) {
    21. throw new RuntimeException(e);
    22. } finally {
    23. JDBCUtil.close(conn,stmt,rs);
    24. }
    25. }

    PreparedStatement(预编译(预加载)接口)

    预编译语句PreparedStatement 是java.sql中的一个接口,它是Statement的子接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由DBMS首先进行编译后再执行。预编译语句和Statement不同,在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样首先将其编译。 

    使用: 

    1.通过connection获取的对象

    2.是Statement接口的子接口

    3.sql语句中可以传参。用?占位,通过setXXX方法来给?赋值

            eg:setString(索引,值);

    4.提高性能

    5.避免sql注入

    例子:

    1. public void test03() {
    2. Connection conn = null;
    3. PreparedStatement pstmt = null;
    4. ResultSet rs = null;
    5. try {
    6. conn = JDBCUtil.getConnection();
    7. String sql = "select * from user where username = ? and password = ?";
    8. pstmt = conn.prepareStatement(sql);
    9. pstmt.setString(1,"aaa");
    10. pstmt.setString(2,"b' or '1' = '1");
    11. rs = pstmt.executeQuery();
    12. if(rs.next()) {
    13. System.out.println("登录成功...");
    14. }else {
    15. System.out.println("账号或密码错误...");
    16. }
    17. }catch (SQLException e) {
    18. throw new RuntimeException(e);
    19. }finally {
    20. JDBCUtil.close(conn,pstmt,rs);
    21. }
    22. }

  • 相关阅读:
    数据库顶会 VLDB 2023 论文解读:字节跳动如何解决超大规模流式任务运维难题
    .netcore基础知识(一)
    【21天Python进阶学习挑战赛】[day3]json标准库大总结
    0x23根据地址读取内存服务
    【云原生之K8S】k8s资源限制以及探针检查
    Docker镜像加载原理
    uniapp 微信小程序仿抖音评论区功能,支持展开收起
    英语单词记忆(词缀 / 前缀)
    jsDate总的毫秒数(时间戳)
    leetcode236. 二叉树的最近公共祖先
  • 原文地址:https://blog.csdn.net/weixin_49627122/article/details/126429943