JDBC基础02
2024-10-01 08:08:34
今日知识
1. sql注入问题
2. jdbc批处理
3. 事务
SQL注入问题解决
1.什么是sql注入。
* 用户通过相关的特殊关键字sql语句非法访问数据库
*例如:
Xxx(' or '1'='1 ):sql语句中跟括号的内容,就达到了注入的目的。
2. 原因
仔细分析一下,数据库注入成功的根本原因是,我们把sql语句中的参数(用户的输入)和sql命令拼接成了一个sql语句,因为一个sql语句中既可以有sql的命令又可以有参数,因此,用户的输入也可以被当做sql的语句来解析执行。
那么,既然知道了sql注入成功的原因,我们就反其道而行之,不让用户输入的参数被当做sql命令解析,而是只把它当做普通字符串来解析。
由此,java中引入了prepareStatement,利用preparestatement来防止sql注入的核心思想就是,不把用户的输入当做sql命令来解析和执行。
3. PreparedStatement继承自Statement,可以通过Connection的prepareStatement方法得到。
例如:
//2.定义sql语句
String sql="insert into account values(null,?,?)";
//定义sql语句执行对象,防止注入
PreparedStatement st=con.prepareStatement(sql);
//给? 赋值
st.setString(1, xxx);
st.setString(2, xxx);
//执行sql
rs=st.executeQuery(sql);
4. 分析
prepareStatement很明显的将sql命令语句与参数分开处理,其执行过程是:
1. 首先在sql语句真正执行之前,先把sql命令送到数据库中进行预编译,生成相应 的数据库命令。
2. 然后在获取sql中的参数,然后真正执行该sql语句。
这样一来,用户输入的参数,只被当做参数而非命令来解析,就可以避免数据库注入这样的问题发生。
**缺点**:不过,这样一来,单次执行PreparedStatement需要与数据库通信两次,效率,比之于单词执行Statement要低。
JDBC批处理
1. 第一种方式
-- 把sql语句加入到批命令中
*statement.addBatch(sql)
-- 执行批处理SQL语句
*executeBatch()方法:执行批处理命令
*clearBatch()方法:清除批处理命令
例如;
//2.定义sql语句
String sql="insert into account values(null,'你好',2000)";
String sql1="insert into account values(null,'你好',2000)";
String sql2="insert into account values(null,'你好',2000)";
//定义sql语句执行对象
st=con.createStatement();
//把sql语句加入到批命令中
st.addBatch(sql);
st.addBatch(sql1);
st.addBatch(sql2);
//执行批处理命令
st.executeBatch();
**优点**:
可以向数据库发送多条不同的SQL语句。
**缺点**:
SQL语句没有预编译。
当向数据库发送多条语句相同,但仅参数不同的SQL语句时,重复写很多条sql语句
2. 第二种方式
*PreparedStatement.addBatch()
例如:
//2.定义sql语句
String sql="insert into account values(null,?,?)";
//定义sql语句执行对象,防止注入
PreparedStatement st=con.prepareStatement(sql);
for (int i = 6; i < 12; i++) {
st.setString(1, "aaa" + i);
st.setString(2, "100" + i);
//加入到批命令中
st.addBatch();
if (i%100==0){
//每一百行清理一次
st.executeBatch();
st.clearBatch();
}
}
//执行批处理命令
st.executeBatch();
优点:与数据库通信次数在批量操作时,PreparedStatment的通信次数远少于Statment。
缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。
事务
1. 概念:
* 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
2. 操作:
1. 开启事务: start transaction;
*con.setAutoCommit(false):开启事务
2. 回滚:rollback;
*在catch中回滚事务
3. 提交:commit;
*当所有sql都执行完提交事
3. 例如
try{
//1.获取con
con= JDBCUtils.getConnection();
//开启事务
con.setAutoCommit(false);
//2.定义SQL
String sql="update account set balance=balance-? where id=?";
//3.获取sql 执行对象
pstm=con.prepareStatement(sql);
//赋值操作 张三 -500
pstm.setDouble(1,500);
pstm.setInt(2,1);
pstm.executeUpdate();
int i=3/0;
//赋值操作 李四 +500
pstm.setDouble(1,-500);
pstm.setInt(2,2);
pstm.executeUpdate();
//提交事务
con.commit();
}catch (Exception e){
//事务回滚
try {
if (con!=null){
con.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
JDBCUtils.releaseResource(con,pstm,null);
}
}
2.事务的四大特性
1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
3. 隔离性:多个事务之间。相互独立。
4. 一致性:事务操作前后,数据总量不变
3. 事务的隔离级别(了解)
* 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
* 存在问题:
1. 脏读:一个事务,读取到另一个事务中没有提交的数据
2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
* 隔离级别:
1. read uncommitted:读未提交
* 产生的问题:脏读、不可重复读、幻读
2. read committed:读已提交 (Oracle)
* 产生的问题:不可重复读、幻读
3. repeatable read:可重复读 (MySQL默认)
* 产生的问题:幻读
4. serializable:串行化
* 可以解决所有的问题
* 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
* 数据库查询隔离级别:
* select @@tx_isolation;
* 数据库设置隔离级别:
* set global transaction isolation level 级别字符串;
* 演示:
set global transaction isolation level read uncommitted;
start transaction;
-- 转账操作
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;
你get到了吗?
最新文章
- Java 用LinkdeList实现52张扑克牌
- U3D-页游-检测机制-webplayer-调试方法
- DataTable添加行和列
- Android:什么是Holo?【Translated By KillerLegend】
- socket.io+angular.js+express.js做个聊天应用(四)
- 国内外MD5在线解密网站
- Linux NetHogs监控工具介绍(转)
- Pig性能优化
- 一行一行分析JQ源码学习笔记-02
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(一)System.out.print与Log
- hihoCoder 1051 补提交卡(贪心,枚举)
- 基于VC的MFC界面开发
- nagios 监控内存使用情况
- centos7通过yum安装mysql,并授权远程连接 【转】
- 爬取WX小程序的数据
- tkinter内嵌Matplotlib系列(二)之函数曲线绘制
- Best quotes from The Vampire Diary(《吸血鬼日记》经典台词)
- SNF快速开发平台MVC-EasyUI3.9之-DataGrid表格控件如何增加右键菜单
- C# 实现邮件代发
- Oozie的详细启动步骤(CDH版本的3节点集群)
热门文章
- Spark on Yarn集群搭建
- JavaScript+CSS交互
- THREE.js代码备份——webgl - custom attributes [lines](自定义字体显示、控制字图的各个属性)
- 【sqli-labs】 less19 POST - Header Injection - Referer field - Error based (基于头部的Referer POST报错注入)
- eslint推荐编码规范和airbnb推荐编码规范
- Python2X和Python3X 除法运算符的使用:
- phpstorm 使用
- vue实现单页应用demo
- Xshell连接linux服务器不成功的乌龙问题
- 在Ubuntu环境下搭建esp32开发环境