今日知识

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到了吗?

JDBC基础02的更多相关文章

  1. javascript基础02

    javascript基础02 1.数据类型 数据类型的描述在上篇的扩展中有写到链接 由于ECMAScript数据类型具有动态性,因此的确没有再定义其他数据类型的必要.这句话很重要. 如果以后再数据类型 ...

  2. javaSE基础02

    javaSE基础02 一.javac命令和java命令做什么事情? javac:负责编译,当执行javac时,会启动java的编译程序,对指定扩展名的.java文件进行编译,生成了jvm可以识别的字节 ...

  3. java基础学习05(面向对象基础02)

    面向对象基础02 实现的目标 1.String类的使用2.掌握this关键字的使用3.掌握static关键字的使用4.了解内部类 String类 实例化String对象一个字符串就是一个String类 ...

  4. jdbc基础 (五) 连接池与数据源 DBCP以及C3P0的使用

    一.连接池的概念和使用 在实际应用开发中,特别是在WEB应用系统中,如果JSP.Servlet或EJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必须经历建立数据库连接.打开数据库.存取数 ...

  5. jdbc基础 (四) 批处理

    批处理,就是字面上的意思,一次性处理一批sql语句. 直接看例子吧: package com.cream.ice.jdbc; import java.sql.Connection; import ja ...

  6. jdbc基础 (三) 大文本、二进制数据处理

    LOB (Large Objects)   分为:CLOB和BLOB,即大文本和大二进制数据 CLOB:用于存储大文本 BLOB:用于存储二进制数据,例如图像.声音.二进制文件 在mysql中,只有B ...

  7. jdbc基础 (二) 通过properties配置文件连接数据库

    csdn博文地址:jdbc基础 (二) 通过properties配置文件连接数据库 上一篇描述了对mysql数据库的简单操作,下面来看一下开发中应该如何灵活应用. 因为jdbc对数据库的驱动加载.连接 ...

  8. JDBC基础教程

    本文实例讲述了JDBC基础知识与技巧.分享给大家供大家参考.具体分析如下: 1.什么是JDBC? 通俗来讲JDBC技术就是通过java程序来发送SQL语句到数据库,数据库收到SQL语句后执行,把结果返 ...

  9. Java 中 JDBC 基础配置

    Java 中 JDBC 基础配置 <resource auth="Container" driverclassname="oracle.jdbc.driver.Or ...

随机推荐

  1. 课上练习 script

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. WIN10 64位下VS2015 C#直接添加 halcon 12导出的CS文件实现视觉检测

    C# halcon 12 联合编程的 实例 1.先调试好halcon程序,我以读取图片的程序为例.

  3. How to add jdk8 in Eclipse Indigo

    I just read How to have Eclipse use JDK8 to compile a project? What i added jdk8 to eclipse as,  Fro ...

  4. Type inference

    Type inference refers to the automatic detection of the data type of an expression in a programming ...

  5. Node.js 常用Mongoose方法

    Node.js 手册查询-Mongoose 方法 一.Schema 一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力.可以说是数据属性模型(传统意义的表结构 ...

  6. 09 Django组件之用户认证组件

    没有学习Django认证组件之前使用装饰器方法 from django.shortcuts import render, HttpResponse, redirect from app01.MyFor ...

  7. struts 2 action result类型

    最近在管理公司老项目的时候发现如下代码: <bean name="detailPlayer" class="PlayAction" method=&quo ...

  8. Golang - 流程控制

    目录 Golang - 流程控制 1. 选择结构 2. 循环结构 3. 跳转语句 Golang - 流程控制 1. 选择结构 if else语句: //package 声明开头表示代码所属包 pack ...

  9. (13)处理静态资源(默认资源映射)【从零开始学Spring Boot】

    Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性. 建议大家使用Spring Boot的默认配置方式,如果需要特殊处理的再通 ...

  10. mysql use index () 优化查询的例子

    USE INDEX在你查询语句中表名的后面,添加 USE INDEX 来提供你希望 MySQ 去参考的索引列表,就可以让 MySQL 不再考虑其他可用的索引.Eg:SELECT * FROM myta ...