Java教程

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

本文主要是介绍SQL注入问题及解决方案及连接池,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

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();
        }

这篇关于SQL注入问题及解决方案及连接池的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!