ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL注入问题及解决方案及连接池

2021-12-13 22:04:58  阅读:174  来源: 互联网

标签:name 解决方案 resultSet lisi SQL 连接池 String


目录

SQL注入问题及解决方案

SQL注入问题

SQL注入问题解决方案

连接池

连接池的工作原理

连接池的作用

连接池的优势

连接池的使用

以c3p0为例讲解连接池的使用


SQL注入问题及解决方案

SQL注入问题

SQL注入问题:利用非法的SQL拼接来达到入侵数据库的目的

示例:
登录查询操作

public class UserDao {
    boolean doLogin(String name ,String password) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java_test", "root", "******");
            System.out.println("连接成功");
            Statement statement = connection.createStatement();

   //正确的查询语句
            String sql = "select * from user where name = '"+name+"' and password = '"+password+"'";
            ResultSet resultSet = statement.executeQuery(sql);

            if(resultSet.next()) return true;

            // 关闭资源
            resultSet.close();
            statement.close();
            connection.close();

        } catch (Exception e) {
            System.out.println("连接失败");
            e.printStackTrace();
        }


        return false;
    }

 传入正确的参数,则返回true,查询成功;

 public static void main(String[] args) {
        UserDao userDao = new UserDao();
        boolean lisi = userDao.doLogin("lisi", "200");
        System.out.println(lisi);
    }

 

若参数错误,如密码错误

boolean lisi = userDao.doLogin("lisi", "2000");

 

 若插入错误的SQL语句,即使参数传入错误也能查询成功

String sql = "select * from user where name = '"+name+"' and password  = '"+password+"'";

UserDao userDao = new UserDao();
boolean lisi = userDao.doLogin("lisi ’#", "2000");

 

 这就是SQL注入问题了

在上述代码中,是使用用户名和密码来和SQL进行拼接查询数据库,查询操作是需要用户名和密码正确才能执行成功。

本应该通过sql的非法拼接改变SQL语句的语义,就达到了入侵数据库的目的 。

当参数变成  “ lisi ’# ” 时,“‘#”会将后面的内容注释掉,就不在判断passwd是否正确,因此对应登录操作给定用户名,不知道密码情况下也能完成登陆

SQL注入问题解决方案

使用preparedStatement代替Statement

String sql = "select * from user where name = ? and password = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,password);
            ResultSet resultSet = preparedStatement.executeQuery();

            if(resultSet.next()) return true;

boolean lisi = userDao.doLogin("lisi'# ", "2000");
      

  

在创建preparedStatement对象时,就将sql语句传入,进行预编译,prepared Statement采用预编译处理机制,SQL和参数分别传递,SQL上参数的位置通过占位符'?'处理;preparedStatement . setString起始位置为1 ,当传入参数时,特殊值就不会被起作用了。

连接池

连接池的工作原理

数据库连接池的基本思想:为数据建立一个连接池,预先在池中放入一定数量的连接,当有数据库操作时,在池中获取一个空闲的连接来支持数据库的操作,当当前的数据库操作完成后,将连接放回池中。

连接池的作用

在JDBC请求MySQL数据库的操作都要进行连接、释放的过程,在并发量大的情况下,频繁的连接和释放势必会消耗系统的性能。可以使用连接复用的方式让来连接重复使用。

连接池的优势

1.资源复用

2.更快的响应速度

3.新的资源分配手段

4.统一的连接关系,避免数据库连接泄露

连接池的使用

1.导入连接

2.参数配置

3.通过连接池获取连接

4.进行SQL操作

以c3p0为例讲解连接池的使用

1.引入c3p0连接

        <!--c3p0连接池-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

2.给定c3p0的配置文件 :c3p0-config.xml (名字不能修改)

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--配置连接池mysql-->
    <named-config name="mysql">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/ssms</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 初始化连接数 -->
        <property name="initialPoolSize">10</property>
        <!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime">30</property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize">100</property>
        <!-- 最小连接数 -->
        <property name="minPoolSize">10</property>
    </named-config>

</c3p0-config>

3.连接池编码

 //设置数据源DataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");

        try {
            //获取Connection
            Connection connection = dataSource.getConnection();

            //获取Statement对象
            Statement statement = connection.createStatement();

            String sql = "select * from user where id = 25";
            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()) {
                Integer id1 = resultSet.getInt("id");
                String account = resultSet.getString("account");
                String name = resultSet.getString("name");
                System.out.println("Id:" + id1 + ",name:" + name);
            }


        } catch (SQLException e) {
            e.printStackTrace();
        }

标签:name,解决方案,resultSet,lisi,SQL,连接池,String
来源: https://blog.csdn.net/weixin_52717049/article/details/121902989

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有