内容介绍
- 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语句文章源自JAVA秀-https://www.javaxiu.com/495.html
问题:使用Statement对象来操作sql语句会有缺陷:会造成数据的安全隐患文章源自JAVA秀-https://www.javaxiu.com/495.html
比如登录中的sql拼接:select * from user where username=’jack’ #’ and password=’123′;文章源自JAVA秀-https://www.javaxiu.com/495.html
相当于注释掉了密码的校验,这种安全隐患我们称为:Sql注入文章源自JAVA秀-https://www.javaxiu.com/495.html
Sql注入:将用户输入的内容作为了sql语句的一部分 改变了原有sql语句的意义文章源自JAVA秀-https://www.javaxiu.com/495.html
解决:就不能使用当前的Statement对象来操作SQL语句了,得使用另一个对象–preparedStatement对象文章源自JAVA秀-https://www.javaxiu.com/495.html
PreparedStatement: 预编译对象
作用:也是用来执行sql语句的文章源自JAVA秀-https://www.javaxiu.com/495.html
语句执行者:Statement编译对象 preparedStatement预编译对象文章源自JAVA秀-https://www.javaxiu.com/495.html
区别:文章源自JAVA秀-https://www.javaxiu.com/495.html
Statement编译对象是有什么样的sql就执行什么样的sql语句,每次执行任何一条sql语句都得先让数据库去编译 其后才执行 如果执行一万条同样的查询语句 数据库要编译一万次 效率低文章源自JAVA秀-https://www.javaxiu.com/495.html
preparedStatement预编译对象是先将sql传递给数据库做预编译 其后拿着预编译结果传递参数执行sql,执行一万条同样的查询语句 数据库只编译一次 根据不同的参数做不用的执行文章源自JAVA秀-https://www.javaxiu.com/495.html
预编译的好处:文章源自JAVA秀-https://www.javaxiu.com/495.html
1 sql语法格式只需要编译一次,效率高文章源自JAVA秀-https://www.javaxiu.com/495.html
2 能让数据库提前知晓要执行的sql语句格式,只负责给数据库传参即可文章源自JAVA秀-https://www.javaxiu.com/495.html
语法格式:文章源自JAVA秀-https://www.javaxiu.com/495.html
Statement编译对象: select * from 表 where 字段1=值1 and 字段2=值2;文章源自JAVA秀-https://www.javaxiu.com/495.html
preparedStatement:select * from 表 where 字段1=? and 字段2=?;文章源自JAVA秀-https://www.javaxiu.com/495.html
?:占位符 所有的实际参数都用占位符替换了 不在是直接设值了 通过外部方法来设置实际参数的值:set字段类型(占位符的序号,要设置的值); 占位符的序号是从1开始的 setString(1,'jack'); setString(2,'abcd/1234');
PreparedStatement对象操作数据库的增删改查
使用步骤:文章源自JAVA秀-https://www.javaxiu.com/495.html
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(); // 执行 增 删 改 返回的是影响的行数
数据库连接池
概述
连接池:存放数据库连接的容器(集合)文章源自JAVA秀-https://www.javaxiu.com/495.html
连接池出现的目的
之前在使用jdbc操作数据库数据的时候,有一个步骤是获取连接(创建连接) 连接用完,还需要释放连接(销毁连接),这2个步骤太消耗资源了 创建连接=0.1 销毁连接=0.1 10000000*0.2=2000000 目标:想将获取连接和释放资源的这个时长缩短
用来优化jdbc的2个步骤的文章源自JAVA秀-https://www.javaxiu.com/495.html
1 优化的是jdbc的创建连接部分 2 优化的是jdbc的销毁连接部分
优化原理
在连接池一初始话的时候,就在容器中创建一定量的连接 当用户要连数据库的时候,就从容器中拿一个连接使用 使用完毕之后,不再是销毁,而是把使用后的连接还放回容器 供下一个用户去循环使用
ps:文章源自JAVA秀-https://www.javaxiu.com/495.html
在企业中使用的都是已经成熟并且性能很高的提供好的连接池:c3p0和druid(重点)文章源自JAVA秀-https://www.javaxiu.com/495.html
只要是直接研发连接池或者是别人研发连接池都需要先实现java提供的规则-DataSource接口文章源自JAVA秀-https://www.javaxiu.com/495.html
不论是哪个连接池都统一会有DataSource接口下的所有方法:文章源自JAVA秀-https://www.javaxiu.com/495.html
获取连接的方法(从连接池中获取): 连接池对象.getConnection() 释放连接的方法(将连接归还给连接池): close() 只要当前要释放的连接是从连接池中拿的,当调用这个方法的时候是归还 如果当前的要释放的连接不是从连接池中拿的,当调用这个方法的时候是销毁
c3p0连接池的使用
硬编码方式(必须要写代码实现的方式)文章源自JAVA秀-https://www.javaxiu.com/495.html
配置文件方式(掌握)文章源自JAVA秀-https://www.javaxiu.com/495.html
硬编码方式开发步骤: 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.xml或c3p0.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 导入1个jar包 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 定义一个连接池(c3p0或druid) 2 提供获取连接的方法 (连接得是从连接池中拿的) 3 提供一个获取连接池的方法(直接返回连接池)--->jdbcTemplate工具类要用 4 提供释放资源的方法
动态代理
作用:用来增强一个对象的方法 (框架的底层用了很多的动态代理来增强方法业务) 代理的概念: 代理对象:增强对象 被代理对象:要被增强的对象 要使用jdk提供的动态代理增强一个对象的方法有条件: 必须得知道要被代理的对象是谁 被代理的对象必须得有接口 java:面向接口 先有接口后有类
使用jdk提供的动态代理:什么包都不用导 都提供好了文章源自JAVA秀-https://www.javaxiu.com/495.html
jdk提供工具API:newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 会返回一个指定接口下的代理类的代理对象文章源自JAVA秀-https://www.javaxiu.com/495.html

评论