网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别

时间:2024-04-24 22:35:38

1.1.1 API详解:注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用

原因有2个:

>导致驱动被注册2次。

>强烈依赖数据库的驱动jar

解决办法:

Class.forName("com.mysql.jdbc.Driver");

1.1.2 API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果

String sql = "某SQL语句";

获取Statement语句执行平台:Statement stmt = con.createStatement();

常用方法:

n int executeUpdate(String sql); --执行insert update delete语句.

n ResultSet executeQuery(String sql); --执行select语句.

n boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.

1.1.3 API详解:处理结果集(注:执行insert、update、delete无需处理)

ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法(与索引从0开始不同个,列从1开始)来获取指定列的数据:

rs.next();//指向第一行

rs.getInt(1);//获取第一行第一列的数据

常用方法:

n Object getObject(int index) / Object getObject(String name) 获得任意对象

n String getString(int index)/ String getString(String name) 获得字符串

n int getInt(int index)/int getInt(String name) 获得整形

n double getDouble(int index)/ double getDouble(String name) 获得双精度浮点型

1.1.4 SQL注入问题

SQL注入:用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义。

假设有登录案例SQL语句如下:

SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;

此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’  OR ‘a’=’a时,则真正执行的代码变为:

SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;

此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。

为此,我们使用PreparedStatement来解决对应的问题。

preparedStatement:预编译对象,是Statement对象的子类。

特点:

性能高

会把sql语句先编译

能过滤掉用户输入的关键字。

PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换。

1.连接池目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能。

常见的连接池:DBCP、C3P0。

1.1 常用的数据源配置

1.1.1 DBCP连接池

DBCP:Apache推出的Database Connection Pool

使用步骤:

> 添加jar包  commons-dbcp-1.4.jar  commons-pool-1.5.6.jar

> 添加属性资源文件

l 配置文件名称:*.properties

l 配置文件位置:任意,建议src(classpath/类路径)

l 配置文件内容:properties不能编写中文

> 编写数据源工具类

1.1.2 C3P0连接池

C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,c3p0使用时还需要添加配置文件 c3p0-config.xml

使用步骤:

1、添加jar包

2、编写配置文件

c3p0-config.xml,放在src中(注:文件名一定不要写错)

网络协议 finally{ return问题  注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池  C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务  DBUtils事务  ThreadLocal 事务特性 并发访问 隔离级别

3、编写工具类:

网络协议 finally{ return问题  注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池  C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务  DBUtils事务  ThreadLocal 事务特性 并发访问 隔离级别

网络协议 finally{ return问题  注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池  C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务  DBUtils事务  ThreadLocal 事务特性 并发访问 隔离级别

1.1.3 概述

DBUtils是java编程中的数据库操作实用工具,小巧简单实用。

DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。

Dbutils三个核心功能介绍

l QueryRunner中提供对sql语句操作的API.

l ResultSetHandler接口,用于定义select操作后,怎样封装结果集.

l DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法

1.1.4 QueryRunner核心类

l QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection

l update(String sql, Object... params) ,执行更新数据 insert update delete

1.1.5 qResultSetHandler结果集处理类

ArrayHandler

将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值

ArrayListHandler

将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。

BeanHandler

将结果集中第一条记录封装到一个指定的javaBean中。

BeanListHandler

将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中

ColumnListHandler

将结果集中指定的列的字段值,封装到一个List集合中

KeyedHandler

将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。

MapHandler

将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值

MapListHandler

将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。

ScalarHandler

它是用于单个数据。例如select count(*) from 表操作。

l Query(String sql, ResultSetHandler<T> rsh, Object... params) ,执行查询 select

l 事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败.

l 操作:

n MYSQL中可以有两种方式进行事务的管理:

u 自动提交:MySql默认自动提交。及执行一条sql语句提交一次事务。

u 手动提交:先开启,再提交

n 方式1:手动提交

start transaction;

update account set money=money-1000 where name='jack';

update account set money=money+1000 where name='rose';

commit;

#或者

rollback;

n 方式2:自动提交,通过修改mysql全局变量“autocommit”进行控制

show variables like '%commit%';

网络协议 finally{ return问题  注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池  C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务  DBUtils事务  ThreadLocal 事务特性 并发访问 隔离级别

* 设置自动提交的参数为OFF:

set autocommit = 0;  -- 0:OFF  1:ON

l 扩展:Oracle数据库事务不自动提交

1.1.6 JDBC事务操作

Connection对象的方法名

描述

conn.setAutoCommit(false)

开启事务

conn.commit()

提交事务

conn.rollback()

回滚事务

//事务模板代码

public void demo01() throws SQLException{

// 获得连接

Connection conn = null;

try {

//#1 开始事务

conn.setAutoCommit(false);

//.... 加钱 ,减钱

//#2 提交事务

conn.commit();

} catch (Exception e) {

//#3 回滚事务

conn.rollback();

} finally{

// 释放资源

conn.close();

}

}

如果发生异常了, 在service被捕捉了 servlet层发现不了异常了,  需要从service层

Throw new  runtimeException(“”)  把异常抛给servlet

1.1.7 DBUtils事务操作

Connection对象的方法名

描述

conn.setAutoCommit(false)

开启事务

new QueryRunner()

创建核心类,不设置数据源(手动管理连接)

query(conn , sql , handler, params )  或

update(conn, sql , params)

手动传递连接

DbUtils.commitAndClose(conn)  或

DbUtils.rollbackAndClose(conn)

提交并关闭连接

回滚并关闭连接

1.1.8 相关知识:ThreadLocal

java.lang.ThreadLocal 该类提供了线程局部 (thread-local) 变量,用于在当前线程*享数据。

网络协议 finally{ return问题  注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池  C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务  DBUtils事务  ThreadLocal 事务特性 并发访问 隔离级别

1.1.9 分析

1.1.10 事务特性:ACID

l 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

l 一致性(Consistency)事务前后数据的完整性必须保持一致。

l 隔离性(Isolation)事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

l 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

1.1.11 并发访问问题

如果不考虑隔离性,事务存在3中并发访问问题。

  1. 脏读:一个事务读到了另一个事务未提交的数据.
  2. 不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。
  3. 虚读 /幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。

1.1.12 隔离级别:解决问题

l 数据库规范规定了4种隔离级别,分别用于描述两个事务并发的所有情况。

  1. read uncommitted 读未提交,一个事务读到另一个事务没有提交的数据。

a) 存在:3个问题(脏读、不可重复读、虚读)。

b) 解决:0个问题

  1. read committed 读已提交,一个事务读到另一个事务已经提交的数据。

a) 存在:2个问题(不可重复读、虚读)。

b) 解决:1个问题(脏读)

  1. repeatable read :可重复读,在一个事务中读到的数据始终保持一致,无论另一个事务是否提交。

a) 存在:1个问题(虚读)。

b) 解决:2个问题(脏读、不可重复读)

  1. serializable 串行化,同时只能执行一个事务,相当于事务中的单线程。

a) 存在:0个问题。

b) 解决:3个问题(脏读、不可重复读、虚读)

l 安全和性能对比

n 安全性:serializable > repeatable read > read committed > read uncommitted

n 性能 : serializable < repeatable read < read committed < read uncommitted

l 常见数据库的默认隔离级别:

n MySql:repeatable read

n Oracle:read committed