目录
4.2第二范式(2NF):属性需要完全依赖主键(针对联合主键)
0MYSQL介绍
0.1MySQL内容介绍
①基本sql语句
②实际问题sql
③索引的介绍
④事务的概念(更新到这儿结束啦)
⑤JDBC编程:通过java代码操作数据库
⑥连接池概念:c3p0,Druid等连接池
拓展:maven使用,构建
0.2MySQL安装
Windows下MySQL安装
参考安装教程:Windows下安装MySQL详细教程 - m1racle - 博客园
(安装最好一次成功(前提把教程每一步理解干什么),重复卸载安装会导致卸载数据不完整(比如注册表),再次安装时不好安装容易失败)
1了解MySQL
通过 二维表 建立起关系
关系型数据库有微软的SQL Server、甲骨文提供的Oracle和MySQL
MySQL分为企业版和社区版,社区版是完全免费且开源的
MySQL和其他的关系型数据库的区别是,支持插件式的存储引擎,存储引擎包括innodb、myisam等
大量的公司使用的MySQL作为数据存储层方案,比如:腾讯、Facebook等。
技术层面来看,MySQL设计成C/S客户端/服务端的模型,用户可以通过MySQL 的Client向MySQL的服务端发送命令,MySQL服务端对命令进行相应,MySQL适合做集群化环境处理,方便做主从复制、读写分离操作。
mysql服务端为了提高用户的并发量,采用了是IO复用和线程池的,实现网络高并发的经典模型
2SQL语句的划分
DDL(Data Definition Language):数据定义语言,该语言定义了不同的数据库、表、列、索引等数据库对象的定义
DML(Data Manipulation Language):数据操纵语言,主要用于数据库中数据库记录的增删改查
DCL(Data Control Language):数据控制语言,对数据库设置访问权限和安全级别,grant,remove等关键字都是数据控制SQL
3MYSQL的数据类型
在MySQL中,二维表来存储数据,需要指定字段的数据类型,类型是用来规定数据大小使用
3.1 整数类型
3.2浮点类型
浮点数,和钱相关的计算,推荐使用decimal
3.3日期类型
3.4字符串类型
3.4.1char类型和varchar类型
3.4.2text类型
3.4.3enum类型
3.4.4set类型
3.5二进制类型
4数据库范式
候选码:若关系中的某一属性组的值能唯一标识一个元组,而其子集不能,则成为该属性组为候选码。
主码:若一个关系有多个候选码,则选定其中一个为主码。
主属性:候选码的诸属性成为主属性。
非主属性 :不包含在任何候选码中的属性称为非主属性。
外键(外码):一个属性,是其他表中的一个属性,当前表可以通过该属性和其他表建立联系
主键:在一个表中一个属性(一个组合属性)可以找到表中其他的属性(主键具有唯一性)
4.1第一范式(1NF)每一列要保持原子特性
第一范式:关系中的每个属性都是不可再分的原子项。
注意:不符合1NF不能称之为关系型数据库
示例:
表中存在一个字段地址字段,可以细分为省、市、区,该字段是不满足第一范式的,将表拆分成专门地址信息
用户表(name、age、address);
address不满足第一范式,进行拆分成两个表:
用户表(name、age、addressId)地址表(addressId,prince、city,..)
4.2第二范式(2NF):属性需要完全依赖主键(针对联合主键)
(消除非主属性对主码的部分函数依赖)
非主属性完全依赖于主键,如果不是依赖主键,应该拆分成新的主题,设计成一对多的关系
示例:
选课关系表(学号、姓名、年龄、课程名称、成绩、学分),联合主键(学号、课程名称)
学分只和课程名称相关,学分只部分依赖联合主键
姓名、年龄和学号相关,姓名,年龄部分依赖于联合主键
成绩是完全依赖于联合主键
不满足第二范式,进行拆分成下面三个表: 学生表(学号、姓名、年龄) 主键:学号
课程表(课程名称、学分) 主键:课程名称
选课成绩表(学号、课程名称、成绩) 主键:学号+课程名称
4.3第三范式(3NF):属性不依赖于非主属性
(消除非主属性对主码的传递函数依赖)
第三范式:保持函数依赖和无损连接。
一般的关系型数据库满足3NF就可以
示例:
学生表(学号、姓名、年龄、学院、学院电话) 主键:学号
姓名、年龄、学院等都依赖于主键可以直接查询
但学院电话是需要先查询到学院,在查询到学院电话,即学院电话不依赖于主键,存在传递依赖,将表进行拆分,消除传递依赖
学生表(学号、姓名、年龄、学院) 主键:学号
学院表(学院名称、学院电话) 主键:学院名称
4.4BC范式(BCNF):每一个表中只有一个候选键
(消除任何属性对主码的部分和传递函数依赖)
BC范式在满足前三范式的基础上的一种特殊情况,
即每个表中的只有一个候选键(数据库中每一行的值都不同,则称之为候选键)
4.5第四范式(4NF):消除表中的多值依赖
(消除非平凡且非函数依赖的多值依赖)
示例:学生表(学号、姓名、技能)
技能描述:“Java、MySQL” “JAVA、MYSQL”
需要维护数据一致性问题,进行拆分
学生表(学号、姓名)
技能表(技能ID、技能名称)
学生技能表(学号、技能ID)
通过范式可知:范式越高、表越多、表越多带来问题
1、查询时需要连接多表,增加了查询的复杂度
2、表越多,查询过程中会降低数据库的查询性能
5SQL操作
操作数据库:CRUD
C(create):创建
R(retrieve):查询
U(update):修改
D(delete):删除
5.1连接数据库
连接:
mysql -uXXX -pXXX;
例:
mysql -uroot -p123456;
mysql代表是客户端的命令 -u后面跟的是数据库用户名 -p后面是需要输入的密码
退出:
exit;
5.2库操作
1、创建数据库:
create database 数据库名称;
2、查看数据库:
show databases; -- 展现出全部的数据库
3、删除数据库:
drop database 数据库名称;
4、选择数据库:
use 数据库名称;
5、查看数据库下的表列表:
show tables; -- 展现出某数据库下所有的表
5.3表操作
5.3.1创建表
create table table_name(
属性名 数据类型 [完整性约束条件],
属性名 数据类型 [完整性约束条件]
);
-- 逗号隔开各个属性,最后一个除外
在表中给定属性时需要指定合适的类型,还可以给定完整性约束(可有可无,可以表示主键、非空、唯一性等)
完整性约束中主键约束:主键不能重复;
例:
-- 创建一个表t1,其中有俩属性,id和name,id有主键和不为空的约束条件
mysql> create table t1(id int(2) primary key not null,name varchar(10));
Query OK, 0 rows affected (0.02 sec)
-- 当第一次插入id=1时插入成功,第二次id=1时失败,id不能重复
mysql> insert into t1(id,name) values (1,'zhangsan');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t1(id,name) values (1,'lisi');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
-- id还有not null约束,因此不能只插入name,每条数据必须不能使id为null
mysql> insert into t1(name) values ('lisi');
ERROR 1364 (HY000): Field 'id' doesn't have a default value
插入数据SQL:
insert into 表名(属性1,属性2,…,属性n) values(属性值1,属性值2,…,属性n);
5.3.2查看表
法①:
desc table_name;
通过desc 命令查看表的字段,名称,类型,默认值,备注信息
mysql> desc Student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| SID | int(5) | YES | | NULL | |
| Sname | varchar(10) | YES | | NULL | |
| Sage | int(10) | YES | | NULL | |
| Ssex | varchar(2) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
法②:
show create table 表名; -- 结尾可以使用";"或者"\G"
可以查看 创建表的sql语句,存储引擎和字符集编码
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`SID` int(5) DEFAULT NULL,
`Sname` varchar(10) DEFAULT NULL,
`Sage` int(10) DEFAULT NULL,
`Ssex` varchar(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
5.3.3修改表
可以通过alter命令来修改表
①修改表名
alter table 旧表名 rename 新表名;
例:
mysql> alter table Student rename s;
Query OK, 0 rows affected (0.00 sec)
②修改字段属性名
alter table 表名 change 旧属性名 新属性名 新数据类型;
例:
mysql> alter table t1 change id ID int(2);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
③修改属性类型
alter table 表名 modify 属性名 属性类型;
例:
mysql> alter table t1 modify ID char(2);
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
④增加字段属性
alter table 表名 add 属性名 类型 [完整性约束] [after 属性];
例:
mysql> alter table t1 add sex varchar(5) default 'nan';
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0
⑤删除字段属性
alter table 表名 drop 属性名;
例:
mysql> alter table t1 drop sex ;
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
⑥调整已有字段属性的排列顺序
alter table 表名 modify 属性名1 类型 first; -- 把属性1 放在最开始
alter table 表名 modify 属性名1 类型 after 属性2 ; -- 把属性1放在属性2的后面
例:
mysql> alter table t1 modify id int(2) after name ;
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(10) | YES | | NULL | |
| id | int(2) | NO | PRI | 0 | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
5.3.4查询表
select * from 表名 [where 条件表达式] [group by 属性名[having 条件表达式]] [ order by 属性名[asc(默认)|desc]];
①带 in的 子查询
一般放在where条件后,批量查询
(not) in(元素1、元素2、…、元素n);
例:
select * from student where SID in(1,2,3,4,5);
②带 between 的范围查询
between 元素1 and 元素2;
例:
select * from student where SID between 1 and 5;
③带 like 的模糊匹配
like'字符串';
针对字符串,可以携带通配符: % 表示0个或者多个字符串,- 表示单个字符
例:
select * from student where Sname like '%1%';
④空值查询
is (not) null;
例:
select * from student where Ssex is not null;
⑤带and的多条件查询
条件表达式1 and 条件表达式2 and 条件表达式n
例:
select * from student where Sname like '%1%' and Ssex = 'nan';
⑥带 or 的多条件查询
条件表达式1 or 条件表达式2 or 条件表达式n
例:
select * from student where Sname like '%1%' or Ssex = 'nan';
⑦去重处理
select distinct 属性名;
例:
select distinct Sage from Student;
⑧对结果排序
order by 属性名[asc(默认升序)|desc];
例:
select * from student order by Sage desc;
⑨分组查询
group by 属性名 having 条件表达式;
例:
select * from student group by Ssex having Sage > 20;
!分组查询和去重有什么区别?
group by 按照指定的属性进行分组,将分组结果中一条数据返回,主要用于统计使用;
distinct 是将查询的结果把重复的去掉
group by在性能上好于distinct
⑩limit的分页查询
limit len; -- limit 带一个参数,表示不指定初始位置的limit,表示从0开始读取len长度数据开始返回
limit num,off; -- 两个参数,第一个参数表示起始位置,第二个参数表示每次读取的长度
5.3.5处理表中数据
①插入数据
-- 单挑插入数据
insert into 表名( 属性名1,属性名2,…,属性名n) values(元素1,元素2,…,元素n);
-- 批量插入数据
insert into 表名( 属性名1,属性名2,…,属性名n) values(元素1,元素2,…,元素n),(元素1,元素2,…,元素n),,,(元素1,元素2,…,元素n);
②修改数据
update 表名 set 属性名 = 新元素 where 条件表达式;
③删除数据
delete from 表名 where 条件表达式;
5.4多表查询
内连接,外连接(左连接,右连接)
表之间的关系:一对一,一对多,多对多的关系
多表联合查询
5.4.1笛卡尔积(全连接)
select * from Student,SC;
5.4.2内连接
等值连接和自然连接
等值连接
当条件“=”的连接称为等值连接,其结果返回连接表的所有列包含重复列。
select * from Student s,SC sc where s.SID = sc.ID;
显性连接:join on
select * from Student s inner join SC sc on s.SID = sc.ID;
自然连接:
要求两个字段值必须相同,并且要求对结果中重复的属性列进行去重。
select * from Student s natural join SC;
5.4.3外连接
内连接是将符合条件的结果返回,(两个表中都存在的数据)。
而外连接是不仅包含符合条件的结果,还包括左表(左连接)和右表(右连接)中所有的数据返回。
左连接:
表1 left join 表2 on 表1.** = 表2.**
查询结果需要把左表的所有数据显示出来,右表中没有的属性用null填充
右连接:
表1 right join 表2 on 表1.** = 表2.**
查询结果需要把右表中的所有数据显示出来,左表中没有与之匹配的用null填充
5.5基本函数
count():计数
avg():平均值
max():最大值
min():最小值
sum():求和
6索引
6.1索引的概念
索引 是提供了一种数据结构对数据进行索引,对数据库表中的一系列或者多系列的值进行排序,索引的好处就是提高查询效率,避免全表扫描
特点:提高查询效率,避免全表扫描
缺点:占用内存空间,因此不是越多越好,太多会导致CPU的使用率居高不下
6.2索引的分类
6.2.1普通
没有限制条件,对任何类型的字段都可以添加普通索引
6.2.2唯一性索引
使用 unique 修饰的字段,值不能重复,该字段添加的索引是唯一的
6.2.3主键索引
使用primary key 修饰的字段,会自动创建索引
主键索引属于特殊的唯一性索引。
6.2.4单列索引
给某单个属性上加索引
6.2.5多列索引(联合索引)
在多个属性上创建的索引
6.2.6全文索引
使用fulltext参数设置的是全文索引,只支持char,varchar和text类型,常使用在数据量较大的字符串类型上,为方便提高查询效率(myisam存储引擎支持)
6.3索引SQL
6.3.1添加索引
1、创建表结构的时候添加索引
create table 表名(
属性名1 类型[完整性约束],
属性名2 类型[完整性约束],
…
属性名n 类型[完整性约束],
[unique|fulltext] index [别名] (属性名)
);
2、在已创建的表上创建索引
通过create语法创建
create [unique|fulltext] index 索引名称 on 表名(属性名);
例:
create index idx_id_name on tulun(id,name);
通过alter 语法创建
alter table 表名 add [unique|fulltext] index 索引名称 (属性);
例:
alter table tulun add index idx_name(name);
6.3.2删除索引
drop index 索引名称 on table_name;
例:
drop index idx_name on tulun;
6.4索引的执行过程
关键字:explain 查看sql的执行计划
explain的使用是直接在查询SQL前添加该关键字即可
分析字段:主要是:
possible_keys表示SQL执行可能命中的索引,
key属性表示在执行过程中实际使用的索引名称,
rows:表示查询操作影响表中数据的行数
给定需求:对student表中查询姓名为'GYSX'的用户信息
在Sname不添加索引时,查询操作的执行计划
在Sname未添加索引时,在执行过程中没有使用索引,查询时是全表扫描(rows=14),当数据库表数据量特别大时,这种查询效率是比较低的
添加索引:idx_name
在分析SQL执行计划:
添加索引后,通过explain分析,执行过程中命中了idx_name的索引,执行过程只影响了一行数据,在大数据量查询是使用索引的效率有大的提高
索引如何做到提高查询效率的??
7事务
7.1事务的定义
一个事务是有一条或者多条对数据库操作的SQL语句所组成的一个不可分割的整体,只有事务中的所有操作都操作完成,才将整个事务提交的数据库,如果执行过程中有部分事务失败,那么事务就要回滚到最初的状态,因此,事务要么全部执行完成,要么全部不执行
事务案例:银行转账问题
7.2事务的特征(ACID)
①原子性(Atomic)
事务是一个不可分割的整体,即对数据的修改要么全部执行,要么全不执行,不存在部分事务执行完成
②一致性(Consistency)
一个事务执行前和执行后,数据库的数据必须保持一致性状态
例如:银行转账:A向B转账,A账户金额减少,B账户的金额增长,整个系统中金额不发生改变
③隔离性(Isolation)
当两个或者多个事务并发执行是,为了保证数据的安全性,将一个事务的内部操作与其他的事务的操作隔离开,不被其他的事务所看到。
④持久性(Durability)
事务完成之后,对数据库中的数据修改是永久性的,即使数据库出现故障重启,也应该恢复数据
7.3事务的使用
7.3.1查看事务是否自动提交
select @@autocommit;
查看MySQL事务是否自动提交,默认是自动提交
1:自动事务提交 0:表示手动事务提交
7.3.2修改是否自动提交
set autocommit=0;
使用set autocommit=0操作,设置事务为手动提交
7.3.3事务操作
①开启事务 begin 或者 start transaction
begin 和start transaction显式开启一个事务
②事务提交 commit
当事务中所有的SQL执行完成后,通过commit将事务提交到数据库
③事务回滚 rollback
在事务执行过程中当有SQL执行失败将事务回滚,回滚到最初状态
另一个窗口查看:
id=8未插入,回滚到最初状态
④保存点 savepoint point1(保存点名)
savepoint point1 设置一个保存点为point1的保存点
rollback to point1:事务回滚到保存点1
7.4常用API组件
DriverManager:这个类是驱动管理类,管理一系列数据库驱动程序,用于简历和数据库的连连接
Connection:该接口具有接触数据库所有的方法,表示和数据库通信的上下文对象
Statement:该对象将SQL提交的数据库
ResultSet:SQL查询语句的结果集通过resultSet返回给用户
SQLException:该类是和数据库交互中任何错误
8JDBC介绍
JDBC(Java Data Base Connection)Java中提供的一套操作数据库的API接口,用于java语言连接操作数据库
8.1常用API组件
DriverManager:这个类是驱动管理类,管理一系列数据库驱动程序,用于简历和数据库的连连接
Connection:该接口具有接触数据库所有的方法,表示和数据库通信的上下文对象
Statement:该对象将SQL提交的数据库
ResultSet:SQL查询语句的结果集通过resultSet返回给用户
SQLException:该类是和数据库交互中任何错误
8.2JDBC使用
1、引入MySQL驱动
通过maven引入依赖
<!--MySQL的驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
2、jdbc连接数据库编程
//1、加载数据库驱动 MySQL-》com.mysql.jdbc.Driver
Class.forName("com.mysql.jdbc.Driver");
//连接数据库
/**
* DriverManager管理连接
*Connection getConnection(String url,String user, String password)
* url:jdbc:mysql://120.0.0.1:3306/test
* user:用户名
* password:密码
*/
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "123");
System.out.println("连接成功");
//获取Statement结果
Statement statement = connection.createStatement();
//修改数据
String sql1 = "update student set Sname='tulun' where SID=18 ";
int i = statement.executeUpdate(sql1);
//查询数据库
String sql ="select * from student";
ResultSet resultSet = statement.executeQuery(sql);
//对结束处理
while (resultSet.next()) {
String sname = resultSet.getString("Sname");
System.out.println(sname);
}
//关闭资源
resultSet.close();
statement.close();
connection.close();
} catch (Exception e) {
System.out.println("连接失败");
e.printStackTrace();
}
编程步骤:
1、引入mysql-connector-java依赖包
2、引入MySQL驱动
3、DriverManager连接数据库获取Connection对象
4、通过Connection获取Statement对象进行SQL操作
5、如果是查询操作处理结果集:ResultSet
6、关闭资源
8.3常用API
Connection接口:数据库连接的对象
获取Statement对象的方法:
①PreparedStatement prepareStatement(String sql) :获取PreparedStatement对象
②Statement createStatement() :获取Statement对象
③CallableStatement prepareCall(String sql) :获取CallableStatement对象
处理事务:
void commit() 提交事务
Statement接口:用来执行SQL语句
boolean execute(String sql):提交SQL语句 返回Boolean类型 可以提交变更操作(插入、删除、修改)
int executeUpdate(String sql) :提交执行DML语言,返回结果表示影响数据库数据行数
ResultSet executeQuery(String sql):执行查询操作,返回的结果在ResultSet中
ResultSet():返回结果集
boolean next():判断是否还有数据,每调用一次获取的是数据库对应的一行记录
问题:PreparedStatement和Statement的区别
//获取Statement结果
Statement statement = connection.createStatement();
//修改数据
String sql1 = "update student set Sname='tulun' where SID=18 ";
int i = statement.executeUpdate(sql1);
/**
* PreparedStatement
* 采用预编译机制处理
* SQL和参数分别传递
* SQL上参数的位置通过占位符'?'处理
* preparedStatement.setString 起始位置为1
*/
//需要将SQL和参数分别传递,采用了预编译机制 '?'占位符
String sql2="update student set Sname = ? where SID = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql2);
preparedStatement.setString(1,"tulun1");
preparedStatement.setString(2,"18");
preparedStatement.execute();
9SQL注入问题及解决方案
9.1SQL注入
利用非法的SQL拼接来达到入侵数据库的目的
以登录为例:
/**
* 登录方法
*/
boolean doLogin(String name, String passwd) {
boolean result = false;
try {
//1、加载数据库驱动 MySQL-》com.mysql.jdbc.Driver
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "123456");
System.out.println("连接成功");
//获取Statement结果
Statement statement = connection.createStatement();
//查询数据库
String sql = "select * from user where name='"+name+"' and passwd = '"+passwd+"'";
ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()) result = true;
//关闭资源
resultSet.close();
statement.close();
connection.close();
} catch (Exception e) {
System.out.println("连接失败");
e.printStackTrace();
}
return result;
}
String name = "12345 ";
String passwd = "12343563445";
//select * from user where name = 12345 or 1=1 and passwd = 32453425
UserDao userDao = new UserDao();
boolean login = userDao.doLogin(name, passwd);
if (login) {
System.out.println("用户登录成功");
} else {
System.out.println("用户名或密码错误,请重新登录");
}
在上述代码中,用户名和密码来和SQL进行拼接查询数据库,查询操作是需要用户名和密码正确才能执行成功。
将name参数写成”name = 12345 or 1=1 and passwd=1234“ name参数拼接中通过非法的SQL拼接达到修改SQL语义,就达到了入侵数据库的目的 当name = 12345或者 1=1and passwd=1234 后面中只要任何一个成绩即可 1=1 为true ,就不在判断passwd是否正确,因此对应登录操作给定用户名,不知道密码情况下也能完成登陆
9.2注入问题的解决方案:
使用PreparedStatement解决:
// 用PreparedStatement 解决非法注入问题
String sql2 = " select * from cheche where name = ? and passwd = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql2);
preparedStatement.setString(1, name);
preparedStatement.setString(2, passwd);
ResultSet resultSet = preparedStatement.executeQuery();
将SQL及参数分别传递到MySQL服务端,会先进行SQL语义检查
能够规避SQL注入问题,建议使用prepareStatement来处理JDBC连接数据库问题
10JDBC处理事务
/**
* 事务操作
* 在COnnection中也提供相应方法
*/
connection.setAutoCommit(false); //true 自动提交 false:手动提交 首先要取消自动提交
connection.commit(); //事务提交
connection.rollback();//事务回滚
/**
* int TRANSACTION_NONE = 0; 不提供事务
*int TRANSACTION_READ_UNCOMMITTED = 1; 未提交事务
*int TRANSACTION_READ_COMMITTED = 2; 读已提交事务
*int TRANSACTION_REPEATABLE_READ = 4; 可重复事务
*int TRANSACTION_SERIALIZABLE = 8; 串行化事务
*
*
*
*
* try {
* connection.setAutoCommit(false);
* sql操作
*
* connection.commit();
*
* } execption(e){
*
* connection.rollback();
* }
*
*/
11连接池
11.1连接池的作用
在JDBC请求MySQL数据库的SQL操作都要进行连接、释放的过程,在并发量大请情况下,频繁的连接和释放势必会消耗系统性能。可以使用连接复用的方式来让连接重复使用
11.2连接池工作原理
数据库连接池的基本思想为数据连接简历一个缓冲池,预先在池中放入一定数量的连接,当有数据库操作时,在池中获取一个空闲的连接来支持数据库操作,当当前的数据库操作完成之后,将连接放回池中,
11.3连接池的优势
1、资源复用
2、更快的响应速度
3、新的资源分配手段
4、统一的连接关系,避免数据库连接泄漏
11.4连接池的使用
1、导入连接
2、参数配置
3、通过连接池获取连接
4、进行SQL操作
连接池:c3p0、dbcp、Druid
以C3p0为例讲解:
1、引入c3p0的依赖
<!--c3p0连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
2、给定c3p0的配置文件:c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--配置连接池mysql-->
<named-config name="mysql">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/ssms</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">10</property>
<!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">30</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">100</property>
<!-- 最小连接数 -->
<property name="minPoolSize">10</property>
</named-config>
</c3p0-config>
3、连接池编码:
//设置数据源DataSource
ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
try {
//获取Connection
Connection connection = dataSource.getConnection();
//获取Statement对象
Statement statement = connection.createStatement();
String sql = "select * from user where id = 25";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
Integer id1 = resultSet.getInt("id");
String account = resultSet.getString("account");
String name = resultSet.getString("name");
System.out.println("Id:" + id1 + ",name:" + name);
}
} catch (SQLException e) {
e.printStackTrace();
}
}