MySQL与JDBC基础

©Copyright 思思不羡仙 Date:2021-04

1. MySQL环境

1.1 安装卸载

  1. 使用 cd 命令至zip解压文件夹目录(不能有中文)

  2. 安装MySQL mysqld --install

  3. 启动MySQL服务 net start mysql

    错误解决方法

  • 若出现错误 NET HELPMSG 3534 需要使用 mysqld --initialize-insecure 使root用户初始化密码为空,注意此时若路径下有data文件夹应删除
  • 若SQLyog出现 错误码2058 则需要更改加密规则,ALTER USER 'root'@'localhost' IDENTIFIED BY '你的密码' PASSWORD EXPIRE NEVER; 使密码永不过期,ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; 更新用户密码,并刷新权限 FLUSH PRIVILEGES;

1.2 服务启动及关闭

  • 启动服务 net start mysql
  • 关闭服务 net stop mysql

1.3 登录及退出

  • 登录 mysql -u userName -p password
  • 登录远程服务器 mysql -h 127.0.0.1 -u userName -p password
  • 退出 exit \ quit

1.4 安装目录介绍

  • bin:二进制可执行文件,cmd执行命令时使用
  • data:MySQL的日志及数据文件
  • include:C语言的头文件
  • lib:一些支持的库文件,类似jar包
  • share:MySQL的错误信息

2. SQL基础操作

2.1 SQL基本概述

2.1.1 定义

结构化查询语言 Structured Query Language,定义了操作所有关系型数据库的规则(只要是关系型数据库都需要遵守)

2.1.2 SQL基础通用语法
  1. SQL语句可以单行或多行书写,以分号结尾

  2. 可使用空格和缩进来增强语句的可读性

  3. MySQL 数据库的SQL语句不区分大小写,关键字建议使用大写

  4. 3种注释

    show database; -- 查询所有的数据库名称
    show database; # 查询所有的数据库名称
    show database; /* 查询所有的数据库名称*/
    
2.1.3 SQL的分类
  • DDL (Data Definition Language) 数据定义语言

    操作数据库与表

  • DML (Data Manipulation Language) 数据操作语言

    增删改表中的数据

  • **DQL **(Data Query Language) 数据查询语言

    查询表中的数据

  • DCL (Data Control Language) 数据控制语言

    数据库访问授权

2.2 DDL操作数据库与表

本部分均分为创建、查询、修改及删除,即CRUD

2.2.1 操作数据库

创建 Create

create database 数据库名称;						-- 创建数据库
create database if not exists 数据库名称;		-- 创建数据库,判断不存在,再创建
create database 数据库名称 character set 字符集名; -- 创建数据库,并指定字符集

可将几条语句合并使用,如 create database if not exists name character set utf8;

查询 Retrieve

show databases;				-- 查询数据库的名称
show create database;		-- 查询某个数据库的创建语句(查询某个数据库的字符集)

修改 Update

alter database 数据库名称 character set 字符集名称;	-- 修改数据库的字符集

删除 Delete

drop database 数据库名称;			-- 删除数据库
drop database if exists 数据库名称;	-- 判断数据库是否存在,存在再删除

使用数据库

select database();		-- 查询当前正在使用的数据库名称
use 数据库名称;		     -- 使用数据库
2.2.2 操作表

创建 Create

create table 表名(		-- 创建表
	列名1 数据类型1,
    列名2 数据类型2,
	...
    列名n 数据类型n
);

注意:最后一列不能加逗号

create table 表名 like 被复制的表名;	-- 复制表
  • 数据类型总结
数据类型解释
int整数类型
double(a,b)小数类型
date日期类型,只包含年月日(yyyy-MM-dd
datetime日期类型,包含年月日时分秒(yyyy-MM-dd HH:mm:ss
timestamp时间戳类型,包含年月日时分秒(yyyy-MM-dd HH:mm:ss),加参数 DEFAULT CURRRENT_TIMESTAMP 若是空值则自动赋值为当前时间
varchar(length)字符串类型
create table student(	id int,	name varchar(32),		-- 最大32个字符	age int,	score double(4,1),		-- 小数最多有4位,小数点后2位(最大值99.99)	birthday date,	insert_time timestamp);

查询 Retrieve

show databases;				-- 查询数据库所有的表名称desc 表名;				   -- 查询表结构

修改 Update

  1. 修改表名

    alter table 表名 rename to 新的表名;
    
  2. 修改表的字符集

    alter table 表名 character set 字符集名称;
    
  3. 添加一列

    alter table 表名 add 列名 数据类型;
    
  4. 修改列名称、类型

    alter table 表名 change 列名 新列名 新数据类型;		-- 同时修改列名、数据类型alter table 表名 modify 列名 新数据类型;			  -- 修改数据类型
    
  5. 删除列

    alter table 表名 drop 列名;
    

删除 Delete

drop table 表名;				-- 删除表drop table if exists 表名;	-- 判断表是否存在,存在再删除

2.3 DML增删改表中的数据

2.3.1 添加数据
insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);

注意事项

  • 列名与值需要一一对应
  • 如果列名后没有表名,则默认给所有列添加值
  • 除了数字类型,其他需要使用引号 "1970-01-01"
2.3.2 删除数据
delete from 表名 [where 条件];

注意事项

  • 如果不加 [where 条件],则删除表中所有记录

  • 如果要删除所有记录

    delete from 表名;		-- 不推荐使用,有多少条记录就会执行多少次删除操作truncate table 表名; 	-- 推荐使用,效率更高,先删除表,然后再创建一张一样的空表
    
2.3.3 修改数据
update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];

注意事项

​ 如果不加任何条件,则会将表中所有记录全部修改

2.4 DQL查询表中的数据

2.4.1 基础语法
  1. select 字段列表
  2. from 表名列表
  3. where 条件列表
  4. group by 分组字段
  5. having 分组之后的条件
  6. order by 排序
  7. limit 分页限定
2.4.2 基础查询
  • 多个字段的查询
select 字段名1,字段名2,字段3... from 表名;

如果需要查询表中的所有字段,则可以使用 * 来替代字段列表,一般情况下不建议使用,因为可读性较差

  • 去除重复 distinct
select distinct 段名1,字段名2,字段3... from 表名;
  • 计算列

一般可以使用四则运算计算一些列的值(数值型)

select 字段, ifnull(字段1) + 字段2 from 表名;

null 参与的运算,计算结果都为 null ,故需要使用 ifnull(表达式1,表达式2) 来使 null 值变为0或需要的值,表达式1为判断是否为 null

  • 起别名 as
select 字段名 as 别名 from 表名;select 字段名 别名 from 表名;

如上述例子,as 可被省略后面直接接别名

2.4.3 条件查询

概述

where 子句后跟条件便是条件查询

运算符

运算符说明
><<=>==<><>!= 均为不等于,其余与Java一致
between A and B等价于 >= A && <= B
in(A,B,C...)等价于 A or B or C...
like模糊查询
is nullnull 值不能使用 !== 判断,故使用此运算符
and 或 &&
or||
not!
模糊查询

例如查询一个班中姓”张“的有哪些人,便需使用模糊查询,会用到以下两种占位符

  • % :匹配任意多个字符
  • _ :匹配一个字符
select * from student where name like "张%";  -- 两个字或三个字均可查询select * from student where name like "张__"; -- 若是三个字则需使用两个"_"select * from student where name like "%张%"; -- 名字包含"张"的人
2.4.4 排序查询

语法规定

order by 排序字段1 排序方式1, 排序字段2 排序方式2...、order by 排序字段1 排序方式1 排序方式2, 排序字段3 排序方式3...

此处的排序方式可以是多样的

  • ASC :升序(默认的)
  • DESC :降序

注意事项

如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件,以此类推

select * from stu order by math ASC chinese ASC english DESC

先按math升序排列,若排列顺序相同再按chinese升序排列,若排列顺序依然相同最后才按英语降序排列

2.4.5 聚合函数

将一列数据作为一个整体,进行纵向的计算,比如用所有人的数学成绩求班级数学平均分

  1. count :计算个数
  2. max:计算最大值
  3. min:计算最小值
  4. sum:计算和
  5. avg:计算平均值
select count(段名) from 表名;select max(段名) from 表名;select min(段名) from 表名;select sum(段名) from 表名;select avg(段名) from 表名;

注意事项

聚合函数的计算,排除 null 值,若需计算有以下三种方法:

  1. 选择不包含非空的列(主键)进行计算

  2. 使用 IFNULL 函数

    select count(ifnull(english,0)) from student;
    
  3. 使用 * 字符,只要一行中有一个字段不为空,就进行计数(不推荐)

    select count(*) from student;
    
2.4.6 分组查询

分组查询是指使用 group by 语句对查询信息进行分组,相同数据作为一组(比如性别字段的男生分一组,女生分一组,这一组实质是一个表,一个表中的一个字段才能使用 count()

语法规定

group by 分组字段;

注意事项

  • 分组查询的字段:分组字段、聚合函数
select sex, avg(math) from student group by sex;

分组字段是对相同一类数据的统计,与查询该类数据内的个体无关,如使用分组字段 + 聚合函数可以统计男女生分别有多少个,但如果加入“马化腾”这一个体,这个个体在统计中没有意义

  • havingwhere 的区别
  1. where 在分组之前进行限定,如果不满足条件,则不参与分组,having 在分组之后进行限定,如果不满足结果,则不会被查询出来

  2. where 后不可以跟聚合函数,having 可以进行聚合函数的判断

select sex, avg(math), count(id) from student where math > 70 group by sex having count(id) > 2;# 按照性别分组,分别查询男、女同学的平均分,分数低于70分的人,不参与分组,分组之后,人数要大于2个人select sex, avg(math), count(id) stuSUM from student where math > 70 group by sex having stuSUM > 2;# 一般在聚合函数后起别名(stuSUM),便于对条件的判断
2.4.7 分页查询

语法规定

limit 开始的索引, 每页查询的条数;select * from student limit 0,3; -- 第1页select * from student limit 3,3; -- 第2页

开始索引的计算

开始的索引 =(当前的页码 - 1)* 每页显示的条数

注意事项

limit 是一个MySQL“方言”,其他数据库的分页操作语句有所不同

2.5 约束

2.5.1 概念

对表中的数据进行限定,保证数据的正确性、有效性和完整性

约束的分类

  1. 主键约束:primary key
  2. 非空约束:not null
  3. 唯一约束:unique
  4. 外键约束:foreign key
2.5.2 非空约束
  • 关键字:not null
  • 解释:值不能为空

创建表时添加

create table stu(	id int,	name varchar(20) not null);

创建表完后添加

alter table stu modify name varchar(20) not null;

删除非空约束

alter table stu modify name varchar(20);
2.5.3 唯一约束
  • 关键字:unique
  • 解释:值不能重复

创建表时添加

create table stu(	id int,	phoneNumber unique);

创建表完后添加

alter table stu modify phoneNumber unique;

删除唯一约束(也被称为唯一索引)

alter table stu drop index phoneNumber;

注意:唯一约束限定的列的值可以有多个 null

2.5.4 主键约束
  • 关键字:primary key
  • 解释:表中记录的唯一标识,必须满足非空且唯一,一张表只能有一个字段为主键

创建表时添加

create table stu(	id int primary key,	name varchar(20));

创建表完后添加主键

alter table stu id int primary key;

删除主键

alter table stu drop primary key;

注意:与其他两种约束方式删除不相同

自动增长

如果某一列是数值类型的,使用 auto_increment 可以来完成值得自动增长,一般用于主键

# 在创建时实现自增长create table stu(			id int primary key auto_increment,			name varchar(20));# 删除自增长alter table stu id int	-- 主键无法使用此方法删除,因此这样删除的仅是auto_increment# 创建完后添加自增长alter table stu id int auto_increment;
2.5.5 外键约束
  • 关键字:foreign key
  • 解释:让表与表产生关系,从而保证数据的正确性

创建表时添加

create table 表名(	外键列	constraint 外键约束名称 foreign key (外键字段名) references 主表名称(主表列名称));

注意:一般情况下,外键一般关联主表的主键,也可是主表其他类作唯一约束的列

删除外键

alter table 表名 drop primary key 外键约束名称;

创建表后添加外键

alter table 表名 add constraint 外键约束名称 foreign key (外键字段名) references 主表名称(主表列名称);# 省略外键名称写法,在创建表时也可这样写alter table 表名 add foreign key (外键字段名) references 主表名称(主表列名称);

注意:添加外键时需要注意外键字段数据是否与主表数据一致(外键可以为 null 但不可以是主表中不存在的值)

级联操作

级联操作需要谨慎使用,容易造成数据意外丢失及耗费大量系统资源

  • 添加级联操作

    alter table 表名 add constraint 外键约束名称 foreign key (外键字段名) references 主表名称(主表列名称) on update cascade on delete cascade;
    
  • 分类

    • 级联更新:on update cascade
    • 级联删除:on delete cascade

3. SQL进阶操作

3.1 数据库的设计

3.1.1 多表之间的关系

一对一(了解)

  • 举例:人和身份证
  • 分析:一个人只有一个身份证,一个身份证只能对应一个人
  • 实现:在任意一方添加唯一外键指向另一方的主键,一般将两张表合为一张

一对多(重要)

  • 举例:部门和员工
  • 分析:一个部门有多个员工,一个员工只能对应一个部门
  • 实现:在多的一方建立外键,指向一的一方的主键

多对多(重要)

  • 举例:学生和课程
  • 分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
  • 实现:多对多关系实现需要借助第三张中间表,中间表至少包含两个字段,这两个字段(联合主键)作为第三张表的外键,分别指向两张表的主键
# 联合主键举例create table tab_favorite (     rid int,     date datetime,     uid int,     primary key(rid,uid),	-- 创建联合主键,rid ⇄ uid 不能重复     foreign key (rid) references tab_route(rid),	-- 将rid与主表关联     foreign key(uid) references tab_user(uid)		-- 将uid与主表关联);
3.1.2 三大范式

设计数据库时,需要遵循的规范;要遵循后边的范式要求,必须先遵循前边的所有范式要求

第一范式

每一列都是不可分割的原子数据项(没有复合列)

第二范式

在第一范式的基础上,非码属性必须完全依赖于码(在第一范式的基础上消除非主属性对主码的部分函数依赖)

  • 函数依赖

A → B,如果通过 A 属性(属性组)的值,可以确定唯一 B 属性的值,则称 B 依赖于 A

学号 → 姓名;学号 + 课程名称 → 分数

  • 完全函数依赖

A → B, 如果 A 是一个属性组,则 B 属性值的确定需要依赖于 A 属性组中所有的属性值

学号 + 课程名称 → 分数(学号和名称属性组被分数完全依赖)

  • 部分函数依赖

A → B, 如果 A 是一个属性组,则 B 属性值的确定只需要依赖于 A 属性组中某一些值即可

学号 → 姓名;学号 + 课程名称 → 姓名;

  • 传递函数依赖

A → B, B → C,如果通过 A 属性(属性组)的值,可以确定唯一 B 属性的值,在通过 B 属性(属性组)的值可以确定唯一 C 属性的值,则称 C 传递函数依赖于A

学号 → 系名,系名 → 系主任

如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码

主属性:码属性组中的所有属性

非主属性:除码属性组的属性

第三范式

在第二范式基础上,任何非主属性不依赖于其它非主属性(在第二范式基础上消除传递依赖)

3.2 数据库的备份和还原

备份语法

mysqldump -u用户名 -p密码 数据库名称 > 保存的路径

还原语法

  1. 创建数据库

    create database database1;
    
  2. 使用数据库

    use database1;
    
  3. 执行文件

    source C:\a.sql;	-- 文件路径
    

3.3 多表查询

查询语法

select	列名列表from	表名列表where	查询条件

笛卡尔积

  • 有两个集合 A,B,取这两个集合的所有组成情况,即 A × B,完成多表查询需要消除笛卡尔积中的无效数据
3.3.1 内连接查询
  • **隐式内连接:**使用 where 关键字消除无用的数据

    where 比较的数据是当前行对应数据

# 仅查询emp表与dept表外键id相对应的数据select * from emp,dept where emp.dept_id = dept.id;# 一般查询时不会查询所有数据,故*处需修改select emp.name,emp.gender,dept.name from emp,dept where emp.dept_id = dept.id;#标准查询格式(一般起别名查询)select	t1.name,	t1.gender,	t2.namefrom	emp t1,	dept t2where 	t1.dept_id = t2.id;
  • 显式内连接:
select 字段列表 from 表名1 [inner] join 表名2 on 条件

注意:此处的 inner 关键字可以省略

注意事项

  1. 从哪些表中查询数据
  2. 条件是什么(怎么算是有效数据,怎么算是无效数据)
  3. 查询哪些字段
3.3.2 外连接查询
  • 左外连接(多用)

查询的是左表所有数据以及其交集部分,在左表含有 null 值时也可查询

select 字段列表 from 表1 left [outer] join 表2 on 条件;
  • 右外连接

查询的是右表所有数据以及其交集部分,在右表含有 null 值时也可查询

select 字段列表 from 表1 right [outer] join 表2 on 条件;

注意事项

  1. leftright 关键字为基准区分左右概念,两种语句实现相同效果,一般掌握左外即可

  2. 在左外连接和右外连接时都会以一张表为基表,该表的内容会全部显示,然后加上两张表匹配的内容。如果基表的数据在另一张表没有记录,那么在相关联的结果集行中列显示为 NULL

3.3.3 子查询

查询中嵌套查询,称嵌套查询为子查询

  • 子查询的结果为单行单列

子查询可以作为条件,使用运算符去判断, 运算符:><<=>==

# 查询小于平均工资的人select * from emp where emp.salary < (select avg(salary) from emp);
  • 子查询的结果为多行单列的

子查询可以作为条件,使用运算符 in 来判断,如in(2,3,4)

# 查询财务部和市场部所有的员工信息select * from emp where dept_idin(select id from dept where name = '财务部' or name = '市场部');
  • 子查询结果是多行多列的

子查询可以作为一张虚拟表参与查询,放置于 from 关键字后

# 查询员工入职日期是2011-11-11日之后的员工信息和部门信息select * from dept as t1, (select * from emp where emp.joindate > '2011-11-11') as t2where t1.id = t2.dept_id;# 也可使用普通内连接select * from dept,emp where dept.joindate > '2011-11-11' and dept_id = dept.id;

3.4 事物

3.4.1 事物的基本介绍

如果一个包含多个步骤的业务操作被事务管理,那么这些操作要么同时成功,要么同时失败

事物的使用

  1. 开启事务:start transaction
  2. 回滚:rollback
  3. 提交:commit
start transaction;update account set balance = balance - 500 where name = 'Alice';update account set balance = balance + 500 where name = 'Alice';commit;

事务默认自动提交

  • 自动提交

    • MySQL数据库默认是自动提交事务
    • 一条DML(增删改)语句会自动提交一次事务,若使用了 start transaction 语句,没有 commit 关闭窗口或退出后MySQL默认不会自动提交事物
  • 手动提交

    • Oracle 数据库默认是手动提交事务
    • 需要先开启事务,再提交
  • 修改事务的默认提交方式

# 查看事务的默认提交方式(0为手动,1为自动)select @@autocommit;#修改默认提交方式set @@autocommit = 0;
3.4.2 事物的四大特征
  1. **原子性:**是不可分割的最小操作单位,要么同时成功,要么同时失败
  2. **持久性:**当事务 commitrollback 后,数据库会持久化的保存数据
  3. **隔离性:**多个事务之间,相互独立,同一时间仅有一个请求用于同一数据
  4. **一致性:**在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
3.4.3 事物的隔离级别

多个事务之间是相互独立的,如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题

存在问题

  • **脏读:**一个线程中的事务读取到了另外一个线程中未提交的数据
  • **虚读:**一个线程中的事务读取到了另外一个线程中提交的 update 的数据
  • **幻读:**指一个线程中的事务读取到了另外一个线程中提交的 insert 的数据

隔离级别

隔离级别字符串脏读虚读幻读
read uncommitted 未提交读可能可能可能
read committed 已提交读(Oracle默认)不可能可能可能
repeatable read 可重复读(MySQL默认)不可能不可能可能
serializable 可串行化(类似多线程锁)不可能不可能不可能

注意:隔离级别从小到大安全性越来越高,但是效率越来越低

# 查询隔离级别select @@transaction_isolation;		-- MySQL8.0select @@tx_isolation;				-- MySQL5.6# 设置隔离级别set global transaction isolation level 级别字符串;

3.5 DCL管理用户及授权

简称说明

  • DDL:操作数据库和表
  • DML:增删改表中数据
  • DQL:查询表中数据
  • DCL:管理用户,授权
  • DBA:数据库管理员
3.5.1 管理用户

查询用户

  1. 切换到mysql数据库

    use mysql;
    
  2. 查询user表

    select * from user;
    

注意:% 表示可以在任意主机使用用户登录数据库,本机为 localhost

添加用户

create user '用户名'@'主机名' identified by '密码';

删除用户

drop user '用户名'@'主机名';

修改用户密码

update user set password = password('新密码') where user = '用户名';set password for '用户名'@'主机名' = password('新密码');
3.5.2 授权

查询权限

show grants for '用户名'@'主机名';

授予权限

grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';# 授予全部权限grant * on * to '用户名'@'主机名';

撤销权限

revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';

4. JDBC基础

4.1 概念

Java DataBase Connectivity 即 Java 数据库连接,使用 Java 语言操作数据库

**JDBC本质:**官方定义的一套操作所有关系型数据库的接口,各个数据库厂商去实现这套接口,提供数据库驱动 jar 包,我们可以使用这套接口编程,真正执行的代码是驱动 jar 包中的实现类

4.2 快速入门

使用步骤

  1. 导入驱动 jar 包:mysql-connector-java-8.0.23.jar
  2. 注册驱动
  3. 获取数据库连接对象 Connection
  4. 定义 SQL 语句(注意分号不能漏)
  5. 获取执行 SQL 语句的对象 Statement
  6. 执行 SQL ,接收返回结果
  7. 处理结果
  8. 释放资源

代码实现

public class DemoJDBC{	public static void main(String[] args) throws Exception {        // 注册驱动        Class.forName("com.mysql.cj.jdbc.Driver");        // 获取数据库连接对象        Connection con = DriverManager.getConnection(            "jdbc:mysql://localhost:3306/db3", "root", "root");        // 定义SQL语句,注意末尾分号不能漏       	String sql = "update account set balance = 1 where name = 'Alice';";         // 获取执行SQL的对象 Statement        Statement st = con.createStatement();        // 执行SQL        int count = st.executeUpdate(sql);        // 处理结果        System.out.println(count);        // 释放资源        stmt.close();        conn.close();    }}

4.3 详解各个对象

4.3.1 DriverManager
  • 驱动管理对象,MySQL 5后无需注册驱动
  1. **注册驱动:**告诉程序该使用哪一个数据库驱动 jar

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

    com.mysql.jdbc.Driver 类中存在静态代码块,因此此处可以简写成上述形式

  2. 获取数据库连接:

    static Connection getConnection(String url,String user,String password);
    
    参数作用
    String url指定连接的路径
    String user用户名
    String password密码

    此处的 String url 具有如下格式:

    "jdbc:mysql://ip地址(域名):端口号/数据库名称"
    

    如果是本机的服务器(默认端口3306),可简化为如下形式:

    "jdbc:mysql:///数据库名称"
    
4.3.2 Connection
  • 数据库连接对象
  1. 获取执行 SQL 的对象

    • Statement createStatement()

    • PreparedStatement prepareStatement(String sql)

  2. 管理事物

    • setAutoCommit(boolean autoCommit) 调用方法时参数设为 false 为手动提交事物

    • commit() 提交事物

    • rollback() 回滚事物

4.3.3 Statement
  • 执行 SQL 的对象

常用方法

  • boolean execute(String sql) 可以执行任意的 SQL
  • int executeUpdate(String sql) 执行 DML、DDL 语句
    • 返回值是影响的行数,故返回值 > 0 则执行成功
    • 一般不使用此方法编写DDL语句,创建表一般直接在数据库中操作
  • ResultSet executeQuery(String sql) 执行 DQL 语句
    • 返回的为结果集对象

使用范例

public class DemoStatment {    public static void main(String[] args) {        Connection connection = null;        Statement statement = null;        try {            Class.forName("com.mysql.cj.jdbc.Driver");            connection = DriverManager.getConnection(            	"jdbc:mysql://localhost:3306/db3", "root", "root"            );            String sql = "insert into account values (null,'Cindy',3000);";            statement = connection.createStatement();            int i = statement.executeUpdate(sql);            if (i > 0) {                System.out.println("添加成功!");            } else {                System.out.println("添加失败!");            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException throwables) {            throwables.printStackTrace();        } finally {            if (statement != null && connection != null) {                try {                    connection.close();                    statement.close();                } catch (SQLException throwables) {                    throwables.printStackTrace();                }            }        }    }}
4.3.4 ResultSet
  • 结果集对象,封装查询结果

常用方法

  1. boolean next() 游标下移一行,判断是否为最后一行末尾,是返回 false,不是返回 true
  2. getXxx(参数) 获取数据
    • Xxx代表数据类型,如int,String等,对应为 getInt()getString()(首字母大写)
    • 参数为String代表列名称,参数为int代表列编号**(从1开始)**

在查询一个完整的表时,我们可以创建一个类,来存放表中的所有数据,每一行置为一个对象并将其存入一个集合当中(一般为ArrayList),若需遍历则对该集合进行遍历即可

使用范例

public class DemoResultSet {    public static void main(String[] args) {        Connection connection = null;        Statement statement = null;        ResultSet resultSet = null;        try {            Class.forName("com.mysql.cj.jdbc.Driver");            connection = DriverManager.getConnection(                "jdbc:mysql://localhost:3306/db3", "root", "root"            );            String sql = "select * from account;";            statement = connection.createStatement();            resultSet = statement.executeQuery(sql);            String name;            double balance;            while (resultSet.next()) {                balance = resultSet.getDouble("balance");                name = resultSet.getString("name");                System.out.println("name = " + name + "; balance = " + balance);            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException throwables) {            throwables.printStackTrace();        } finally {            if (statement != null && connection != null) {                try {                    connection.close();                    statement.close();                    resultSet.close();                } catch (SQLException throwables) {                    throwables.printStackTrace();                }            }        }    }}
4.3.5 PreparedStatement
  • 执行预编译的 SQL 对象

Statment存在的问题

在拼接SQL时,有一些SQL的特殊关键字参与字符串的拼接,会造成安全性问题,如用户输入 a' or 'a' = 'a 可使判断条件永真

使用方法

与Statment基本一致,只是不使用字符串的拼接,而是使用 ? 作占位符进行预编译SQL语句的执行

以下步骤为与Statment不同地方

  1. 定义SQL语句
select * from user where username = ? and password = ? ;
  1. 获取执行SQL语句的对象
PreparedStatement pst = Connection.prepareStatement(String sql);
  1. ? 赋值:SetXxx(参数1,参数2)
    • Xxx为数据类型
    • 参数1:占位符的位置(以1开始编号)
    • 参数2:占位符的直

使用该类的优点

  • 可以防止SQL注入带来的安全问题
  • 效率更高

一般都会使用PreparedStatement来完成增删改查的所有操作

4.4 抽取JDBC工具类

  • **目的:**简化书写

  • 分析:

    1. 注册驱动抽取
    2. 抽取一个方法获取连接对象
    3. 抽取一个方法释放资源

代码实现

import java.io.FileReader;import java.io.IOException;import java.sql.*;import java.util.Properties;public class ConnectorUtils {    private static String url;    private static String user;    private static String password;    private static String driver;    static{        try {            Properties properties = new Properties();            ClassLoader classLoader = ConnectorUtils.class.getClassLoader();            /*            【配置文件】            	url = jdbc:mysql://数据库ip:端口号/数据库名                user = 用户名                password = 密码                driver = 驱动            */            String path = classLoader.getResource("jdbc.properties").getPath();            properties.load(new FileReader(path));            url = properties.getProperty("url");            user = properties.getProperty("user");            password = properties.getProperty("password");            driver = properties.getProperty("driver");            Class.forName(driver);        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public static Connection getConnection() {        Connection connection = null;        try {            connection = DriverManager.getConnection(url, user, password);        } catch (SQLException throwables) {            throwables.printStackTrace();        }        return connection;    }    public static void Close(Statement statement, Connection connection, ResultSet resultSet) {        if (statement != null) {            try {                statement.close();            } catch (SQLException throwables) {                throwables.printStackTrace();            }        }        if (connection != null) {            try {                connection.close();            } catch (SQLException throwables) {                throwables.printStackTrace();            }        }        if (resultSet != null) {            try {                resultSet.close();            } catch (SQLException throwables) {                throwables.printStackTrace();            }        }    }    public static void Close(Statement statement, Connection connection) {        if (statement != null) {            try {                statement.close();            } catch (SQLException throwables) {                throwables.printStackTrace();            }        }        if (connection != null) {            try {                connection.close();            } catch (SQLException throwables) {                throwables.printStackTrace();            }        }    }}

4.5 JDBC管理事物

使用Connection对象来管理事物

  1. 开启事物:调用该方法设置参数为 false ,即开启事务

    setAutoCommit(boolean autoCommit)

  2. 提交事物:当所有sql都执行完提交事务

    commit()

  3. 回滚事物:在catch中回滚事务

    rollback()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值