MySQL介绍(基本操作、事务、索引、JDBC的介绍、连接池等)

目录

0MYSQL介绍

0.1MySQL内容介绍

0.2MySQL安装

1了解MySQL

2SQL语句的划分

3MYSQL的数据类型

3.1 整数类型

3.2浮点类型

3.3日期类型

3.4字符串类型

3.5二进制类型

4数据库范式

4.1第一范式(1NF)每一列要保持原子特性

4.2第二范式(2NF):属性需要完全依赖主键(针对联合主键)

4.3第三范式(3NF):属性不依赖于非主属性

4.4BC范式(BCNF):每一个表中只有一个候选键

4.5第四范式(4NF):消除表中的多值依赖

5SQL操作

5.1连接数据库

5.2库操作

5.3表操作

5.3.1创建表

5.3.2查看表

5.3.3修改表

5.3.4查询表

5.3.5处理表中数据

5.4多表查询

5.4.1笛卡尔积(全连接)

5.4.2内连接

5.4.3外连接

5.5基本函数

6索引

6.1索引的概念

6.2索引的分类

6.2.1普通

6.2.2唯一性索引

6.2.3主键索引

6.2.4单列索引

6.2.5多列索引(联合索引)

6.2.6全文索引

6.3索引SQL

6.3.1添加索引

6.3.2删除索引

6.4索引的执行过程

7事务

7.1事务的定义

7.2事务的特征(ACID)

7.3事务的使用

7.3.1查看事务是否自动提交

7.3.2修改是否自动提交

7.3.3事务操作

7.4常用API组件

8JDBC介绍

8.1常用API组件

8.2JDBC使用

8.3常用API

9SQL注入问题及解决方案

9.1SQL注入

9.2注入问题的解决方案:

10JDBC处理事务

11连接池

11.1连接池的作用

11.2连接池工作原理

11.3连接池的优势

11.4连接池的使用


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中,二维表来存储数据,需要指定字段的数据类型,类型是用来规定数据大小使用

img

3.1 整数类型

img

3.2浮点类型

img

浮点数,和钱相关的计算,推荐使用decimal

3.3日期类型

img

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(

属性名 数据类型 [完整性约束条件],

属性名 数据类型 [完整性约束条件]

);

 -- 逗号隔开各个属性,最后一个除外

在表中给定属性时需要指定合适的类型,还可以给定完整性约束(可有可无,可以表示主键、非空、唯一性等)

img

完整性约束中主键约束:主键不能重复;

例:

-- 创建一个表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前添加该关键字即可

img

分析字段:主要是:

possible_keys表示SQL执行可能命中的索引,

key属性表示在执行过程中实际使用的索引名称,

rows:表示查询操作影响表中数据的行数

给定需求:对student表中查询姓名为'GYSX'的用户信息

在Sname不添加索引时,查询操作的执行计划

img

在Sname未添加索引时,在执行过程中没有使用索引,查询时是全表扫描(rows=14),当数据库表数据量特别大时,这种查询效率是比较低的

添加索引:idx_name

img

在分析SQL执行计划:

img

添加索引后,通过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:表示手动事务提交

img

7.3.2修改是否自动提交

set autocommit=0;

使用set autocommit=0操作,设置事务为手动提交

img

7.3.3事务操作

开启事务  begin 或者 start transaction

begin 和start transaction显式开启一个事务

img

事务提交 commit

当事务中所有的SQL执行完成后,通过commit将事务提交到数据库

img

img

事务回滚 rollback

在事务执行过程中当有SQL执行失败将事务回滚,回滚到最初状态

img

另一个窗口查看:

img

id=8未插入,回滚到最初状态

保存点 savepoint point1(保存点名)

savepoint point1 设置一个保存点为point1的保存点

rollback to point1:事务回滚到保存点1

img

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();
        }
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值