jdbc-PrepareStatement+数据库连接池的介绍

jdbc-PrepareStatement

  1. PrepareStatement的作用

    预编译SQL语句并执行;预防SQL注入问题

  2. SQL注入的说明:

    sql注入是通过操作输入来修改事先准备定义好的SQL语句,用以达到执行代码对服务器进行进攻的方法
    比如我们在进行登录时:需要输入账号和密码,当我们在输入密码为 ‘or’1’='1时会产生sql注入,看下面分析:

@Test
public void testLogin() throws  Exception {
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///db1?useSSL=false";
    String username = "root";
    String password = "1234";
    Connection conn = DriverManager.getConnection(url, username, password);

    // 接收用户输入 用户名和密码
    String name = "sjdljfld";
    String pwd = "' or '1' = '1";
    String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
    // 获取stmt对象
    Statement stmt = conn.createStatement();
    // 执行sql
    ResultSet rs = stmt.executeQuery(sql);
    // 判断登录是否成功
    if(rs.next()){
        System.out.println("登录成功~");
    }else{
        System.out.println("登录失败~");
    }

    //7. 释放资源
    rs.close();
    stmt.close();
    conn.close();
}

看该条语句:“select * from tb_user where username = '”+name+“’ and password = '”+pwd+“'”;
将我们输入的账号密码写入(账号随意,密码会产生sql注入): password = ’ ‘or’1’='1 ’ ==>
password = ’ ‘or’1’=‘1’ ; ‘’ => 假 或 ‘1’=‘1’ 真 所以得到的结果为真,所以就算输入的不是真正的密码,最终也能够实现登录。

现在我们使用?(占位符)来防止sql注入:

// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);

我们通过PrepareStatement对象的setXxx()方法来设置参数?的值,如下:

  // 接收用户输入 用户名和密码
    String name = "zhangsan";
    String pwd = "' or '1' = '1";

    // 定义sql
    String sql = "select * from tb_user where username = ? and password = ?";
    // 获取pstmt对象
    PreparedStatement pstmt = conn.prepareStatement(sql);
    // 设置?的值
    pstmt.setString(1,name);
    pstmt.setString(2,pwd);
    // 执行sql
    ResultSet rs = pstmt.executeQuery();
    // 判断登录是否成功
    if(rs.next()){
        System.out.println("登录成功~");
    }else{
        System.out.println("登录失败~");
    }

我就很好奇为啥这样就不会产生sql注入?PrepareStatement是如何实现的?
PrepareStatement是将特殊字符进行了转义,转义的sql如下:

select * from tb_user where username = 'sjdljfld' and password = '\'or \'1\' = \'1'

PrepareStatement的优点:
预编译SQL,性能更高
防止SQL注入:将敏感字符进行转义

java代码操作数据库流程如图:
在这里插入图片描述
开启预编译功能:
在代码中编写url时需要加上以下参数。而我们之前根本就没有开启预编译功能,知识解决了sql注入漏洞

useServerPrepstmts=true

配置MYSQL执行日志(重启mysql服务后生效)

  • 在mysql配置文件(my.ini)中添加如下配置
  log-output=FILE
  general-log=1
  general_log_file="D:\mysql.log"
  slow-query-log=1
  slow_query_log_file="D:\mysql_slow.log"
  long_query_time=2

小结

  • 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
  • 执行时就不用再进行这些步骤了,速度更快
  • 如果sql模板一样,则只需要进行一次检查、编译

4,数据库连接池

  • 数据库连接池是个容器,负责分配、管理数据库连接(Connection)

  • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

  • 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏

  • 好处

  • 资源重用

  • 提升系统响应速度

  • 避免数据库连接遗漏

数据库连接池实现

  • 标准接口:DataSource

    官方(SUN) 提供的数据库连接池标准接口,由第三方组织实现此接口。该接口提供了获取连接的功能:

    Connection getConnection()
    

    那么以后就不需要通过 DriverManager 对象获取 Connection 对象,而是通过连接池(DataSource)获取 Connection 对象。

  • 常见的数据库连接池

    • DBCP
    • C3P0
    • Druid

    我们现在使用更多的是Druid,它的性能比其他两个会好一些。

  • Druid(德鲁伊)

    • Druid连接池是阿里巴巴开源的数据库连接池项目

    • 功能强大,性能优秀,是Java语言最好的数据库连接池之一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈毓辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值