SQL注入和数据库的连接池druid、c3p0的使用及动态代理

沙海
沙海
沙海
165
文章
2
评论
2018年7月30日23:28:59 评论 129 3427字阅读11分25秒

内容介绍

  • ​1 preparedStatement 预编译对象
  • 2 数据库的连接
  • 3 动态代理

SQL注入

模拟用户登录功能

需求:
    我们在控制台输入用户名和密码,输入完用户名和密码后,获取输入的值,使用jdbc操作数据库,完成登录功能.
    找到了:登录成功   找不到:用户名或密码错误  
技术分析:
    jdbc
代码实现:
创建用户表:
    create table user (
      id int primary key auto_increment,
      name varchar(20),
      password varchar(20)
  );
  insert into user values(null,"tom","tom"),(null,"rose","rose"),(null,"jerry","jerry");

Statement编译对象:拼接什么样的sql就执行什么样的sql语句

问题:使用Statement对象来操作sql语句会有缺陷:会造成数据的安全隐患

比如登录中的sql拼接:select * from user where username=’jack’ #’ and password=’123′;

相当于注释掉了密码的校验,这种安全隐患我们称为:Sql注入

Sql注入:将用户输入的内容作为了sql语句的一部分 改变了原有sql语句的意义

解决:就不能使用当前的Statement对象来操作SQL语句了,得使用另一个对象–preparedStatement对象

PreparedStatement: 预编译对象

作用:也是用来执行sql语句的

语句执行者:Statement编译对象 preparedStatement预编译对象

区别:

Statement编译对象是有什么样的sql就执行什么样的sql语句,每次执行任何一条sql语句都得先让数据库去编译 其后才执行 如果执行一万条同样的查询语句 数据库要编译一万次 效率低

preparedStatement预编译对象是先将sql传递给数据库做预编译 其后拿着预编译结果传递参数执行sql,执行一万条同样的查询语句 数据库只编译一次 根据不同的参数做不用的执行

预编译的好处:

1 sql语法格式只需要编译一次,效率高

2 能让数据库提前知晓要执行的sql语句格式,只负责给数据库传参即可

语法格式:

Statement编译对象: select * from 表 where 字段1=值1 and 字段2=值2;

preparedStatement:select * from 表 where 字段1=? and 字段2=?;

?:占位符 所有的实际参数都用占位符替换了 不在是直接设值了
通过外部方法来设置实际参数的值:set字段类型(占位符的序号,要设置的值);
占位符的序号是从1开始的 
setString(1,'jack');
setString(2,'abcd/1234');

PreparedStatement对象操作数据库的增删改查

使用步骤:

1.编写sql
       String sql = "insert into user values(null,?,?…) ";
2.创建预编译对象--提前编译sql语句
       PreparedStatement pst = conn.preparedStatement(sql);
3.设置具体的参数
       pst.set字段类型(int a,值);
       a: 第几个 ? (占位符)  默认从左向右第1个开始
4.执行sql即可    
       ResultSet rs = pst.executeQuery(); // 执行查询,返回 resultSet
       int i = pst.executeUpdate(); // 执行 增 删 改 返回的是影响的行数

数据库连接池

概述

连接池:存放数据库连接的容器(集合)

连接池出现的目的

之前在使用jdbc操作数据库数据的时候,有一个步骤是获取连接(创建连接)
连接用完,还需要释放连接(销毁连接),这2个步骤太消耗资源了
创建连接=0.1
销毁连接=0.1
10000000*0.2=2000000
目标:想将获取连接和释放资源的这个时长缩短

用来优化jdbc的2个步骤的

1 优化的是jdbc的创建连接部分
2 优化的是jdbc的销毁连接部分

优化原理

在连接池一初始话的时候,就在容器中创建一定量的连接
当用户要连数据库的时候,就从容器中拿一个连接使用
使用完毕之后,不再是销毁,而是把使用后的连接还放回容器 供下一个用户去循环使用

ps:

在企业中使用的都是已经成熟并且性能很高的提供好的连接池:c3p0和druid(重点)

只要是直接研发连接池或者是别人研发连接池都需要先实现java提供的规则-DataSource接口

不论是哪个连接池都统一会有DataSource接口下的所有方法:

获取连接的方法(从连接池中获取): 连接池对象.getConnection() 
释放连接的方法(将连接归还给连接池): close() 
        只要当前要释放的连接是从连接池中拿的,当调用这个方法的时候是归还
        如果当前的要释放的连接不是从连接池中拿的,当调用这个方法的时候是销毁

c3p0连接池的使用

硬编码方式(必须要写代码实现的方式)

配置文件方式(掌握)

硬编码方式开发步骤:
         1 导包 c3p0-0.9.1.2.jar
         2 创建连接池
         3 告诉连接池要连接的数据库信息
         4 (可选)连接池的参数配置
         5 获取连接
配置文件方式(掌握)企业开发中我们配置文件会使用2种:.properties  key=value    .xml  层级关系
         1 导包 c3p0-0.9.1.2.jar
         2 src下放一个配置文件
           这个配置文件如果是xml的话,必须叫c3p0-config.xml 必须放在src
           这个配置文件是properties的话,必须叫c3p0.properties  必须放在src
        3 创建连接池获取连接
           好处:只要连接池一创建 底层会自动去src下加载名字叫c3p0-config.xmlc3p0.properties文件
        4 代码实现
           1:创建c3p0的连接池:DataSource ds=new CombopooledDataSource() 
                      使用配置文件默认的<default-config>
                      DataSource ds=new CombopooledDataSource"name名称"                     
                      使用配置文件中带名称的<named-config name="otherc3p0"> 
           2:从连接池中获取连接:  Connection con=ds.getConnection()
           3:拿着连接去操作数据库: 
           4:归还连接给连接池:    con.close()

druid连接池的使用

配置文件方式(掌握)
    1 导入1jar 
        druid-1.0.9.jar
    2 存放配置文件
         没有要求,是任何名称任何位置的properties文件即可(建议放入src下)
         原因:因为不会自动帮你去加载配置文件,需要自己手动去加载配置文件
    3 代码实现
      1:创建properties对象加载配置文件
        InputStream is=类名.class.getClassLoad.getResourceAsStream();
        Properties properties= new Properties();
        properties.load(is);        
      2: 创建druid的连接池
 DataSource ds=DruidDataSourceFactory.createDataSource(properties对象)
      3: 获取连接
        Connection con=ds.getConnection()
      4: 拿着连接去操作数据库:      
      5:归还连接给连接池: con.close()

自定义工具类(jdbcUtils)的增强

1 定义一个连接池(c3p0druid
2 提供获取连接的方法 (连接得是从连接池中拿的)
3 提供一个获取连接池的方法(直接返回连接池)--->jdbcTemplate工具类要用
4 提供释放资源的方法

动态代理

作用:用来增强一个对象的方法 (框架的底层用了很多的动态代理来增强方法业务)
代理的概念:
       代理对象:增强对象
       被代理对象:要被增强的对象
要使用jdk提供的动态代理增强一个对象的方法有条件:
必须得知道要被代理的对象是谁 被代理的对象必须得有接口
java:面向接口 先有接口后有类

使用jdk提供的动态代理:什么包都不用导 都提供好了

jdk提供工具APInewProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)  会返回一个指定接口下的代理类的代理对象
继续阅读
历史上的今天
七月
30
weinxin
资源分享QQ群
本站是一个IT技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
2020部编版人教版初中语文七年级上册课件
(新版)华师版七年级数学下册课件
0004-基于Java的美食后台管理系统的设计与实现
0001-基于Java的在线考试系统设计与实现
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: