Java之MySQL(No.25)
1、常规软件开发分类(General Software Development Classification)
1.1、前台(Reception)
也称为“前端(Front-End)”,一般为页面,主要显示数据。
1.2、后台(Backstage)
也称为“后端(Back-End)”,一般为连接点,连接前端(控制视图跳转或传递前端数据)以及连接数据库(JDBC)。
1.3、数据库(DataBase)
一般为后台存储数据(如:txt、excel、word等)。
1.4、注意事项(Matters Needing Attention)
- 1.4.1、初级程序员:只会写业务代码,以及数据库的CRUD操作(即,增加[Create]、检索[Retrieve]、更新[Update]和删除[Delete])。
- 1.4.2、中级程序员:在初级程序员基础上,还会操作系统、数据结构与算法。
- 1.4.3、高级程序员:在中级程序员基础上,还会离散数学、数字电路、体系结构、编译原理以及实战经验。
2、数据库(DataBase)
即“数据仓库”,是一种可以存储数据与管理数据的软件。其一般分为两种(关系型数据库与非关系型数据库)。
2.1、关系型数据库(Relational DataBase)
一般存储行列数据,通过表与表之间、行与列之间的关系来存储数据。
- 2.1.1、MySQL。
- 2.1.2、Oracle。
- 2.1.3、SQL Server。
- 2.1.4、DB2。
- 2.1.5、SQLite。
- …。
2.2、非关系型数据库(Not Only SQL)
一般存储对象数据,通过对象自身的属性来存储数据。
- 2.2.1、Redis。
- 2.2.2、MongDB。
- …。
3、MySQL数据库管理系统(MySQL DataBase Management System)
MySQL是一种关系型数据库管理系统(DataBase Management System)软件。
MySQL是由瑞典MySQL AB公司开发,现属于Oracle旗下产品。
MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。且由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型或大型网站的开发都选择MySQL作为网站数据库。
4、MySQL5.7非安装版配置(MySQL5.7 Non Installation Version Configuration)
4.1、软件下载。
官网下载地址(https://dev.mysql.com/downloads/mysql/5.7.html)。
4.2、软件配置。
-
4.2.1、解压已下载软件压缩包,将解压文件放到自定义环境目录路径下(如"E:\Environment\Java\MySQL\mysql-5.7.35")。
-
4.2.2、配置软件的系统环境变量,如下图所示。
-
4.2.3、在自定义环境目录路径下(如"E:\Environment\Java\MySQL\mysql-5.7.35")新建ini配置文件(其名称为“my.ini”,即“E:\Environment\Java\MySQL\mysql-5.7.35\my.ini”),其配置内容如下所示。
[mysql] # 设置mysql客户端默认字符集 # default-character-set=utf8 [mysqld] skip-grant-tables # 设置3306端口 port = 3306 # 设置mysql的安装目录 basedir=E:\Environment\Java\MySQL\mysql-5.7.35\ # 设置mysql数据库的数据的存放目录 datadir=E:\Environment\Java\MySQL\mysql-5.7.35\data\ # 允许最大连接数 # max_connections=20 # 服务端使用的字符集默认为8比特编码的latin1字符集 # character-set-server=utf8 # 创建新表时将使用的默认存储引擎 # default-storage-engine=INNODB
-
4.2.4、启动管理员模式下的CMD命令窗口,然后输入CMD命令(mysqld install),安装MySQL服务,如下图所示。
-
4.2.5、输入CMD命令(mysqld --initialize-insecure --user=mysql),初始化MySQL数据库文件,如下图所示。
-
4.2.6、输入CMD命令(net start mysql),启动MySQL服务,如下图所示。
-
4.2.7、输入CMD命令(mysql -uroot -p),首次登录MySQL,如下图所示。
-
4.2.8、分别输入CMD命令1(use mysql;)、CMD命令2(update user set authentication_string=password(“123456”) where user=‘root’😉、CMD命令3(flush privileges;),修改MySQL登录密码,如下图所示。
-
4.2.9、修改ini配置文件(即“E:\Environment\Java\MySQL\mysql-5.7.35\my.ini”),其内容如下所示。
[mysql] # 设置mysql客户端默认字符集 # default-character-set=utf8 [mysqld] # 将“skip-grant-tables”注释掉后代表登录MySQL时必须验证密码,否则登录MySQL时不验证密码 # skip-grant-tables # 设置3306端口 port = 3306 # 设置mysql的安装目录 basedir=E:\Environment\Java\MySQL\mysql-5.7.35\ # 设置mysql数据库的数据的存放目录 datadir=E:\Environment\Java\MySQL\mysql-5.7.35\data\ # 允许最大连接数 # max_connections=20 # 服务端使用的字符集默认为8比特编码的latin1字符集 # character-set-server=utf8 # 创建新表时将使用的默认存储引擎 # default-storage-engine=INNODB
-
4.2.10、输入CMD命令(exit),退出MySQL登录,如下图所示。
-
4.2.11、输入CMD命令(net stop mysql),停止MySQL服务,如下图所示。
-
4.2.12、输入CMD命令(net start mysql),重新启动MySQL服务,如下图所示。
-
4.2.13、输入CMD命令(mysql -uroot -p123456),重新登录MySQL(修改密码已生效),如下图所示。
5、SQLyog下载、安装、配置(SQLyog Download And Installation And Configuration)
参考网址(http://www.xue51.com/soft/2982.html)。
6、SQLyog使用(SQLyog Use)
参考网址(https://blog.csdn.net/su2231595742/article/details/107967198)。
7、四大SQL语言(Four SQL Languages)
7.1、数据查询语言(DQL,Data Query Language)
数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块:SELECT <字段名表>FROM <表或视图名>WHERE <查询条件>。
7.2、数据操纵语言(DML,Data Manipulation Language)
数据操纵语言DML主要有三种形式:1、插入(INSERT);2、更新(UPDATE);3、删除(DELETE)。
7.3、数据定义语言(DDL,Data Definition Language)
数据定义语言DDL用来创建数据库中的各种对象,如表、视图、索引、同义词、聚簇(CREATE TABLE / VIEW / INDEX / SYN / CLUSTER)等。且DDL操作是隐性提交的,不能rollback。
7.4、数据控制语言(DCL,Data Control Language)
数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等,如下所示。
-
7.4.1、GRANT:授权。
-
7.4.2、ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。ROLLBACK回滚命令使数据库状态回到上次最后提交的状态。其格式为:SQL>ROLLBACK。
-
7.4.3、 COMMIT [WORK]:提交。在数据库的插入、删除和修改操作时,只有当事务在提交到数据库时才算完成。在事务提交前,只有操作数据库的这个人才能有权看到所做的事情,别人只有在最后提交完成后才可以看到。提交数据有三种类型:显式提交、隐式提交及自动提交。下面分别说明这三种类型。
-
7.4.3.1、显式提交。
用COMMIT命令直接完成的提交为显式提交。其格式为:SQL>COMMIT。
-
7.4.3.2、隐式提交。
用SQL命令间接完成的提交为隐式提交。这些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
-
7.4.3.3、自动提交。
若把AUTOCOMMIT设置为ON,则在插入、修改、删除语句执行后,系统将自动进行提交,这就是自动提交。其格式为:SQL>SET AUTOCOMMIT ON。
-
8、操作MySQL数据库(Operation MySQL DataBase)
MySQL关键字不区分大小写,且单行注释符号为--,多行注释为/**/。
8.1、创建数据库
CREATE DATABASE IF NOT EXISTS db_1;
8.2、删除数据库
DROP DATABASE IF EXISTS db_1;
8.3、使用数据库
-- 使用反引号标注表名或字段名
USE `test`;
8.4、查看数据库
SHOW DATABASES;-- 查看所有的数据库
9、MySQL数据库列类型(MySQL DataBase Column Type)
9.1、数值
名称 | 描述 | 长度 | 备注 |
---|---|---|---|
tinyint | 十分小的整数 | 1个字节 | |
smallint | 较小的整数 | 2个字节 | |
mediumint | 中等大小的整数 | 3个字节 | |
int | 标准的整数 | 4个字节 | 常用 |
bigint | 较大的整数 | 8个字节 | |
float | 单精度浮点数 | 4个字节 | |
double | 双精度浮点数 | 8个字节 | 存在精度问题,一般不适用于金融计算 |
decimal | 字符串形式的浮点数 | 16个字节 | 一般适用于金融计算 |
9.2、字符串
名称 | 描述 | 长度大小范围 | 备注 |
---|---|---|---|
char | 固定大小字符串 | 0~255 | |
varchar | 可变大小字符串 | 0~65535 | 常用 |
tinytext | 微型文本 | 0~255 | 二进制存储 |
text | 文本串 | 0~65535 | 二进制存储,保存大文本 |
9.3、日期时间
名称 | 描述 | 备注 |
---|---|---|
date | 日期格式(如:YYYY-MM-DD) | |
time | 时间格式(如:HH:mm:ss) | |
datetime | 日期时间格式(如:YYYY-MM-DD HH:mm:ss) | 常用 |
timestamp | 时间戳(即,从1970年1月1日到现在的毫秒数,全世界统一) | 较常用 |
year | 年份 |
9.4、null
即,空值,或没有值,或未知,且不要使用null进行运算,其结果只能为null。
10、MySQL数据库字段属性(MySQL DataBase Field Properties)
10.1、unsigned
即,无符号整数,不能为负数。
10.2、zerofill
即,数据不足的位数,使用0来填充<如字段为int(2)时,若输入数值1,则最终数值自动填充为01>。
10.3、自增
即,通常用来设计唯一的主键,且必须为整数,其每次生成数值会自动累加。
10.4、非空
即,不允许数据为空。
10.5、默认
即,数据默认值。
10.6、注意事项
一般每个表都会存在以下5个字段,用来表示一个记录存在的意义,如下所示:
1、主键(id,唯一标识)
2、乐观锁(version,版本)
3、伪删除(is_delete,标志位)
4、创建时间(gmt_create,创建时间)
5、修改时间(gmt_update,修改时间)
11、创建MySQL数据库及表(Create MySQL DataBase And Table)
其sql语句,如下所示。
-- 创建school数据库
CREATE DATABASE IF NOT EXISTS `school` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 创建student数据表
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '12321' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '电子邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '创建学生数据表';
-- 查看创建school数据库的sql语句
SHOW CREATE DATABASE `school`;
-- 查看创建student数据表的sql语句
SHOW CREATE TABLE `student`;
-- 显示student数据表结构
DESC `student`;
12、MySQL数据表类型(MySQL Data Table Type)
MySQL中所有数据库文件都存在data目录下,一个文件夹对应一个数据库,其本质还是文件的存储。
12.1、MySQL引擎(MySQL Engine)
MySQL引擎,一般常用“MYISAM引擎”与“INNODB引擎”。
12.1.1、物理存储区别(Physical Storage Differences)
-
12.1.1.1、MYISAM引擎。
在data目录下,其数据库表中只有一个.frm文件,以及上级目录下的ibdata1文件*。
-
12.1.1.2、INNODB引擎。
在data目录下,其数据库表中有三个文件,如下所示。
- 12.1.1.2.1、*.frm文件(表结构的定义文件)。
- 12.1.1.2.2、*.myd文件(数据文件)。
- 12.1.1.2.3、*.myi文件(索引文件)。
12.1.2、功能使用区别(Function Use Differences)
功能 | MYISAM引擎 | INNODB引擎 |
---|---|---|
事物处理 | 不支持 | 支持 |
数据行锁定 | 不支持 | 支持 |
外键约束 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
12.1.3、优缺点(Advantages And Disadvantages)
数据库引擎 | 优点 | 缺点 |
---|---|---|
MYISAM | 节约空间(空间较小),速度较快 | 安全性不高,不支持事务处理及多表用户操作 |
INNODB | 安全性高,支持事务处理及多表用户操作 | 空间较大(约为MYISAM空间2倍),速度较慢 |
12.2、MySQL字符集(MySQL Character Set)
-- 默认MySQL字符集编码为“Latin1”,不支持中文,需单独设定,目前有2种方式,如下所示。
-- 方式1(推荐使用,不会随不同环境的改变而有差异):直接在SQL语句中设置数据库表字符集编码(如“CHARSET=utf8”);
-- 方式2(推荐使用,可能会随不同环境的改变而有差异):直接在"my.ini"配置文件中设置MySQL默认字符集编码(如“character-set-server=utf8”);
13、修改删除MySQL数据表(Modify And Delete MySQL Data Table)
13.1、修改数据表(Modify Data Table)
-- 修改数据表名称:ALTER TABLE `旧表名` RENAME AS `新表名`
ALTER TABLE `student` RENAME AS `student1`;
-- 增加数据表字段:ALTER TABLE `表名` ADD `列名` 列属性
ALTER TABLE `student1` ADD `age` INT(3);
-- 修改数据表字段列属性(修改约束):ALTER TABLE `表名` MODIFY `列名` 列属性
ALTER TABLE `student1` MODIFY `age` VARCHAR(11);
-- 修改数据表字段列名称及列属性(重命名+修改约束):ALTER TABLE `表名` CHANGE `旧列名` `新列名` 列属性
ALTER TABLE `student1` CHANGE `age` `age1` INT(5);
-- 删除数据表字段:ALTER TABLE `表名` DROP `列名`
ALTER TABLE `student1` DROP `age1`;
13.2、删除数据表(Delete Data Table)
-- 删除数据表(若存在再删除,否则不删除):ALTER TABLE `表名` DROP `列名`
DROP TABLE IF EXISTS `student1`;
14、MySQL数据管理(MySQL Data Management)
14.1、外键(Foreign Key)
-- 方式1:在创建表的时候,增加外键约束
-- 创建grade表
CREATE TABLE IF NOT EXISTS `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`) COMMENT '主键gradeid'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '创建年级表';
-- 创建student表,增加外键约束
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '12321' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '电子邮箱',
`gradeid` INT(10) NOT NULL COMMENT '学生年级id',
PRIMARY KEY(`id`) COMMENT '主键id',
KEY `FK_gradeid`(`gradeid`) COMMENT '外键gradeid',
CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '创建学生表';
/*
-- 方式2:在创建表完后,增加外键约束
-- 创建grade表
CREATE TABLE IF NOT EXISTS `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`) COMMENT '主键gradeid'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '创建年级表';
-- 创建student表
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '12321' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '电子邮箱',
`gradeid` INT(10) NOT NULL COMMENT '学生年级id',
PRIMARY KEY(`id`) COMMENT '主键id'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '创建学生表';
-- 创建表后增加外键约束:ALTER TABLE `引用表` ADD CONSTRAINT `约束名` FOREIGN KEY(`外键列`) REFERENCES `被引用表`(`被引用列`)
ALTER TABLE `student` ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`);
*/
/*
注意事项:
1、删除有外键关系表时,必须先删除引用表(从表),再删除被引用表(主表)。
2、不建议使用外键关系表,以防连接多张表影响效率,最好由程序内部业务去实现。
3、最好的数据表就是只用来存储数据,只有行(数据)与列(字段),没有其他约束条件。
*/
14.2、添加数据(Add Data)
-- 添加(插入)语句:INSERT INTO `表名`(`列1`,`列2`,...) VALUES(列1值1,'列2值1'),(列1值2,'列2值2'),...;
-- 插入单行数据时,若不写表字段,则自动一一对应插入数值
INSERT INTO `grade` VALUES(1,'1年级');
-- 插入单行数据时,若写表字段,则表字段需一一对应插入数值
INSERT INTO `grade`(`gradename`) VALUES('2年级');
-- 插入多行数据时,若写表字段,则表字段需一一对应插入数值
INSERT INTO `grade`(`gradeid`,`gradename`) VALUES(3,'3年级'),(4,'4年级');
14.3、修改数据(Modify Data)
-- 修改(更新)语句:UPDATE `表名` SET `列1`=列1值,`列2`='列2值',... WHERE 条件;
-- 修改所有的年级名称(未指定条件)
UPDATE `grade` SET `gradename`='100年级';
-- 修改年级id为1的年级名称
UPDATE `grade` SET `gradename`='11年级' WHERE `gradeid`=1;
-- 修改年级id为1的年级id、年级名称
UPDATE `grade` SET `gradeid`=1,`gradename`='111年级' WHERE `gradeid`=1;
14.4、删除数据(Delete Data)
-- 删除数据语句:
-- 1、DELETE命令:DELETE FROM `表名` WHERE 条件
-- 删除指定数据
DELETE FROM `grade` WHERE `gradeid`=4;
-- 删除表中所有数据(未指定条件)
DELETE FROM `grade`;
-- 2、TRUNCATE命令:TRUNCATE `表名`,其作用为“完全清空一个数据表,表的结构与索引约束不会变”。
TRUNCATE `grade`;
/*
一、DELETE命令与TRUNCATE命令区别:
1、相同点:都能清空数据表数据,且都不会删除表结构。
2、不同点:2.1、TRUNCATE命令会重新设置“自增列”(计数器会归零);2.2、TRUNCATE命令不会影响事务。
二、DELETE清空表数据后,重启数据库的特殊现象:
1、若数据库引擎为INNODB,则自增列会重新从1开始计数(存在内存中,断电即失);
2、若数据库引擎为MYISAM,则自增列会继续从上一个自增量+1开始计数(存在文件中,不会丢失);
*/
14.5、查询数据(Query Data)
查询(选择)数据语句:数据库中最核心的SQL语言,使用频率最高的SQL语句(一般80%的操作都是它)。
14.5.1、查询SQL完整语法(Query SQL Complete Grammar)
-- Select完整语法:
SELECT [ALL | DISTINCT]
{*|table.*|[table.field1[AS alias1][,table.field2[AS alias2][,...]]}
FROM table_name1 [AS table_alias1]
[LEFT|RIGHT|INNER JOIN table_name2 [AS table_alias2]] -- 联合查询
[WHERE ...] -- 指定结果满足的条件
[GROUP BY ...] -- 指定结果按照哪几个字段来分组
[HAVING ...] -- 过滤分组的记录必须满足的次要条件
[ORDER BY ...] -- 指定查询记录按一个或多个条件排序
[LIMIT {[OFFSET,]ROW_COUNT|row_countoffset OFFSET}]; -- 指定查询的记录从哪条到哪条
-- 注意事项:以上语法里面的中括号“[]”代表可选的参数,花括号“{}”代表必选的参数。
14.5.2、查询指定字段(Query Specified Fields)
-- 查询所有字段
SELECT * FROM `student`;
-- 查询指定字段,且给每一个字段取一个别名
SELECT `id`,`name`,`pwd` FROM `student`;
-- 查询指定字段拼接后的新字段,且取一个别名
SELECT CONCAT(`name`,'生日:',`birthday`) AS '学生生日' FROM `student`;
-- 去重:查询唯一的指定字段
SELECT DISTINCT `name` FROM `student`;
-- 查询SQL表达式:字段列、文本值、NULL、函数、计算表达式、系统变量、...
SELECT `address` AS '地址' FROM `student`; -- 查询地址(字段列)
SELECT '12321'; -- 查询指定字符串(文本值)
SELECT NULL; -- 查询指定值NULL(NULL)
SELECT VERSION(); -- 查询系统版本(函数)
SELECT 10*2-1 AS '计算结果'; -- 用来计算(计算表达式)
SELECT @@auto_increment_increment; -- 查询自增的步长(系统变量)
14.5.3、查询where子条件(Query Where Sub Condition)
其作用为“检索数据中符合条件的值”,其条件由一个或多个表达式组成,结果为布尔值。
-
14.5.3.1、逻辑运算符。
运算符 语法 描述 AND && a AND b a && b 逻辑与,两个都为真,结果为真 OR || a OR b a || b 逻辑或,其中一个为真,结果为真 NOT ! NOT a NOT a=b ! a a!=b 逻辑非,真为假,假为真 -- 1、逻辑运算符 -- 查询年级id在1~3之间的学生姓名 SELECT `name`,`gradeid` FROM `student` WHERE `gradeid`>=1 AND `gradeid`<=3; SELECT `name`,`gradeid` FROM `student` WHERE `gradeid`>=1 && `gradeid`<=3; -- 查询年级id为1或id为5的学生姓名 SELECT `name`,`gradeid` FROM `student` WHERE `gradeid`=1 OR `gradeid`=5; SELECT `name`,`gradeid` FROM `student` WHERE `gradeid`=1 || `gradeid`=5; -- 查询年级id不为1的学生姓名 SELECT `name`,`gradeid` FROM `student` WHERE NOT `gradeid`=1; SELECT `name`,`gradeid` FROM `student` WHERE `gradeid`!=1;
-
14.5.3.2、比较运算符。
运算符 语法 描述 IS NULL a IS NULL 若操作符为NULL,则结果为真 IS NOT NULL a IS NOT NULL 若操作符不为NULL,则结果为真 BETWEEN AND a BETWEEN b AND c 若a在b和c之间,则结果为真 LIKE a LIKE b 若a模糊匹配b,则结果为真 IN a IN (a1,a2,…) 若a等于a1或a2或…中的任意一个值,则结果为真 -- 查询没有出生日期的学生姓名 SELECT `birthday`,`name` FROM `student` WHERE `birthday` IS NULL; -- 查询有出生日期的学生姓名 SELECT `birthday`,`name` FROM `student` WHERE `birthday` IS NOT NULL; -- 查询年级id在1~4之间的学生姓名 SELECT `gradeid`,`name` FROM `student` WHERE `gradeid` BETWEEN 1 AND 4; -- 查找姓李的学生姓名:其中%代表可以通配0~任意个字符 SELECT `name` FROM `student` WHERE `name` LIKE '李%'; -- 查找姓李且名字后面只有一个字的学生姓名:其中_代表可以通配1个字符 SELECT `name` FROM `student` WHERE `name` LIKE '李_'; -- 查找姓名中带风字的学生姓名 SELECT `name` FROM `student` WHERE `name` LIKE '%风%'; -- 查询学生id为1、2、3的学生姓名 SELECT `id`,`name` FROM `student` WHERE `id` IN (1,2,3);
14.5.4、联表查询(Join Table Query)
8种联表操作 | 描述 |
---|---|
内联接(INNER JOIN) | 若左右两张表中至少有一个匹配,则返回匹配行 |
左联接(LEFT JOIN) / 左外联接(LEFT OUTER JOIN) | 左联接与左外联接一致,会从左表中返回所有行,即使右表中没有匹配 |
右联接(RIGHT JOIN) / 右外联接(RIGHT OUTER JOIN) | 右联接与右外联接一致,会从右表中返回所有行,即使左表中没有匹配 |
交叉联接(CROSS JOIN) | 交叉联接是没有联接条件的联接。一个表的每一行与另一表的每一行合并。这种类型的结果集称为笛卡尔乘积或叉积。 |
-- 联表查询
-- 1、内联接(INNER JOIN):若左右两张表中至少有一个匹配,则返回匹配行。
-- 使用“内联接”从年级表与学生表中查询所有年级id、年级名称、学生id、学生姓名
SELECT a.`gradeid`,a.`gradename`,b.`id`,b.`name` FROM `grade` AS a
INNER JOIN `student` AS b ON(a.`gradeid`=b.`gradeid`);
-- 2、左联接(LEFT JOIN):会从左表中返回所有行,即使右表中没有匹配
-- 使用“左联接”从年级表与学生表中查询所有年级id、年级名称、学生id、学生姓名
SELECT a.`gradeid`,a.`gradename`,b.`id`,b.`name` FROM `grade` AS a
LEFT JOIN `student` AS b ON(a.`gradeid`=b.`gradeid`);
-- 3、左外联接(LEFT OUTER JOIN):与左联接一致,会从左表中返回所有行,即使右表中没有匹配
-- 使用“左外联接”从年级表与学生表中查询所有年级id、年级名称、学生id、学生姓名
SELECT a.`gradeid`,a.`gradename`,b.`id`,b.`name` FROM `grade` AS a
LEFT OUTER JOIN `student` AS b ON(a.`gradeid`=b.`gradeid`);
-- 4、右联接(RIGHT JOIN):会从右表中返回所有行,即使左表中没有匹配
-- 使用“右联接”从年级表与学生表中查询所有年级id、年级名称、学生id、学生姓名
SELECT a.`gradeid`,a.`gradename`,b.`id`,b.`name` FROM `grade` AS a
RIGHT JOIN `student` AS b ON(a.`gradeid`=b.`gradeid`);
-- 5、右外联接(RIGHT OUTER JOIN):与右联接一致,会从右表中返回所有行,即使左表中没有匹配
-- 使用“右外联接”从年级表与学生表中查询所有年级id、年级名称、学生id、学生姓名
SELECT a.`gradeid`,a.`gradename`,b.`id`,b.`name` FROM `grade` AS a
RIGHT OUTER JOIN `student` AS b ON(a.`gradeid`=b.`gradeid`);
-- 6、完全联接(FULL JOIN):MySQL不支持,返回左表与右表的所有行
-- 7、完全外联接(FULL OUTER JOIN):MySQL不支持,与完全联接一致,返回左表与右表的所有行
-- 8、交叉联接(CROSS JOIN):交叉联接是没有联接条件的联接。一个表的每一行与另一表的每一行合并。这种类型的结果集称为笛卡尔乘积或叉积。
SELECT * FROM `grade` AS a CROSS JOIN `student` AS b;
14.5.5、自连接查询(Self Join Query)
自己的表和自己的表连接,即,将一张表拆分成两张一样的父子类表即可。
-
父类表。
id name 1 软件开发 2 JavaSE 3 HTML5 4 CSS3 5 JavaScript 6 MySQL 7 JavaWeb 8 SSM框架 9 大前端进阶 10 微服务开发 11 Linux运维 12 常用中间件 -
子类表。
sub_id id name 1 1 软件开发 1 2 JavaSE 2 3 HTML5 3 4 CSS3 3 5 JavaScript 4 6 MySQL 5 7 JavaWeb 6 8 SSM框架 7 9 大前端进阶 8 10 微服务开发 9 11 Linux运维 10 12 常用中间件
-- 自连接查询:即,自己的表和自己的表连接,亦即,将一张表拆分成两张一样的父子类表即可
SELECT a.`name` AS '父类列名',b.`name` AS '子类列名'
FROM `selftable` AS a,`selftable` AS b
WHERE a.`id`=b.`sub_id`;
14.5.6、分页和排序查询(Pages And Sorts Query)
/*
分页和排序查询
1、分页语法:LIMIT 查询页起始下标,页面大小(如:LIMIT 0,10)。
1.1、第1页:LIMIT 0,num => (1-1)*num,num,
1.2、第2页:LIMIT 1*num,num => (2-1)*num,num,
1.3、第3页:LIMIT 2*num,num => (3-1)*num,num,
...
1.n、第n页:LIMIT (n-1)*num,num => (n-1)*num,num,
推导出分页公式:(n-1)*num,num;且其中num代表页面大小,n代表总页数(总页数=数据总数量/页面大小),(n-1)*num代表查询页起始下标;
2、排序语法:ORDER BY 字段列1,字段列2,... ASC(升序)/DESC(升序)。
*/
-- 查询1~5年级id中学生分数排名前3且学生分数大于等于80分的学生信息(年级id、学生id、学生姓名、学生性别、学生分数)
SELECT `gradeid` 年级id,`id` 学生id,`name` 学生姓名,`sex` 学生性别,`score` 学生分数 FROM `student`
WHERE `gradeid` BETWEEN 1 AND 5 AND `score`>=80
ORDER BY `score` DESC
LIMIT 0,3;
14.5.7、子查询和嵌套查询(Sub Query And Nested Query)
子查询和嵌套查询的本质:“在查询where语句中嵌套一个子查询语句”。
-- 子查询和嵌套查询
-- 查询1~5年级id中所有学生信息(年级id、学生id、学生姓名、学生性别、学生分数)
select `gradeid` as 年级id,`id` as 学生id,`name` as 学生姓名,`sex` as 学生性别,`score` as 学生分数 from `student`
where `gradeid` in (select `gradeid` from `grade` where `gradeid` in (1,2,3,4,5));
14.5.8、分组和过滤查询(Group And Filter Query)
-- 分组和过滤查询
-- 查询所有学生中不同年级id的最高分、最低分、平均分,且平均数大于等于80分的年级名称
SELECT `gradename` 年级名称,MAX(`score`) 最高分,MIN(`score`) 最低分,AVG(`score`) 平均分
FROM `student` s INNER JOIN `grade` g ON(s.`gradeid`=g.`gradeid`)
GROUP BY s.`gradeid` /*按照字段“gradeid”分组数据*/
HAVING 平均分>=80; /*按照新字段“平均分”过滤数据*/
15、MySQL函数(MySQL Function)
15.1、常规函数(General Function)
-- 常规函数
-- 1、数学函数
SELECT ABS(-1); -- 绝对值
SELECT CEILING(5.4);-- 向上取整
SELECT FLOOR(5.4);-- 向下取整
SELECT RAND();-- 返回一个0~1之间的随机浮点数
SELECT SIGN(0);-- 判断一个数的符号:为0时返回0,为正数时返回1,为负数时返回-1
-- 2、字符串函数
SELECT CHAR_LENGTH('mysql');-- 字符串长度
SELECT CONCAT('喜','欢','你');-- 拼接字符串
SELECT INSERT('喜欢你',1,3,'我爱你');-- 指定字符串替换掉从指定位置指定长度的字符串
SELECT UPPER('MySQL');-- 大写字母
SELECT LOWER('MySQL');-- 小写字母
SELECT INSTR('MySQL MySQL','y');-- 返回字符串中第1次出现子字符串的位置
SELECT REPLACE('MySQL MySQL','MySQL','mysql');-- 替换字符串中出现的所有指定字符串
SELECT SUBSTR('hijklMySQLmnopq',6,5);-- 返回指定位置指定长度的子字符串
SELECT REVERSE('MySQL');-- 反转字符串
-- 3、日期时间函数
SELECT CURRENT_DATE();-- 获取当前日期
SELECT CURDATE();-- 获取当前日期
SELECT NOW();-- 获取当前日期时间
SELECT LOCALTIME();-- 获取本地日期时间
SELECT SYSDATE();-- 获取当前系统日期时间
SELECT YEAR(NOW());-- 获取当前年份
SELECT MONTH(NOW());-- 获取当前月份
SELECT DAY(NOW());-- 获取当前日
SELECT HOUR(NOW());-- 获取当前小时
SELECT MINUTE(NOW());-- 获取当前分钟
SELECT SECOND(NOW());-- 获取当前秒
-- 4、系统参数函数
SELECT SYSTEM_USER();-- 获取系统用户
SELECT USER();-- 获取当前用户
SELECT VERSION();-- 获取系统版本
15.2、聚合函数(Aggregate Function)
-- 聚合函数
SELECT COUNT(`score`) FROM `student`;-- 计数,会忽略所有的null值
SELECT COUNT(*) FROM `student`;-- 计数,不会忽略所有的null值,其本质:计算行数
SELECT COUNT(1) FROM `student`;-- 计数,不会忽略所有的null值,其本质:计算行数
SELECT SUM(`score`) '总和' FROM `student`;-- 求和
SELECT AVG(`score`) '平均分' FROM `student`;-- 求平均值
SELECT MAX(`score`) '最高分' FROM `student`;-- 求最大值
SELECT MIN(`score`) '最低分' FROM `student`;-- 求最小值
15.3、数据库MD5加密函数(DataBase MD5 Encryption Function)
MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
-- MD5加密函数:主要是增强算法的复杂度和不可逆性,其返回值为32位十六进制数字的字符串形式。
-- 创建MD5测试表
CREATE TABLE `md5_table`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '唯一标识',
`name` VARCHAR(10) NOT NULL COMMENT '用户名',
`pwd` VARCHAR(20) NOT NULL COMMENT '密码',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
-- 插入明文密码的数据
INSERT INTO `md5_table`(`name`,`pwd`) VALUES('张三','123'),('李四','456');
-- 插入非明文密码(MD5加密)的数据
INSERT INTO `md5_table`(`name`,`pwd`) VALUES('赵五',MD5('123456')),('钱六',MD5('123321'));
-- 密码校验:将用户传递的密码进行MD5加密,然后比对加密后的值
SELECT * FROM `md5_table` WHERE `name`='赵五' AND `pwd`=MD5('123456');
SELECT * FROM `md5_table` WHERE `name`='钱六' AND `pwd`=MD5('123321');
16、MySQL事务(MySQL Transaction)
事务一般是将一组SQL放到一个批次中去执行(要么都成功,要么都失败),且一个事务对应一个完整的业务(如:银行账户转账业务),事务有四个基本要素,即,ACID原则,如下所示。
16.1、原子性(Atomicity)
或称不可分割性,原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
16.2、一致性(Consistency)
一致性是指事务前后数据的完整性必须保持一致。
16.3、隔离性(Isolation)
或称独立性,隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
-
16.3.1、隔离性可以解决的问题(Isolation Can Solve The Problem)
-
16.3.1.1、脏读。
指一个事务读取了另外一个事务未提交的数据。
-
16.3.1.2、不可重复读。
在一个事务内读取表中的某一行数据,多次读取结果不同(这个不一定是错误,只是某些场合不对)。
-
16.3.1.3、虚度(幻读)。
是指在一个事务内读取到了别的事务插入的数据,导致前后读取数量总量不一致。
-
-
16.3.2、四种隔离级别设置(Four Isolation Level Settings)
-- 设置与查询事务隔离级别 -- 设置事务隔离级别为“串行化”:可避免脏读、不可重复读、虚读情况的发生。 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- 设置事务隔离级别为“可重复读”:可避免脏读、不可重复读情况的发生。 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 设置事务隔离级别为“读已提交”:可避免脏读情况发生。 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 设置事务隔离级别为“读未提交”:最低级别,以上情况均无法保证。 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- 查询当前事务隔离级别 SELECT @@tx_isolation;
16.4、持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
-- MySQL事务
SET autocommit=1;-- 开启事务自动提交(MySQL默认情形)
-- 手动处理业务
SET autocommit=0;-- 关闭事务自动提交
-- 开启事务:标记一个事务的开始,从这个之后的SQL都在同一个事务内
START TRANSACTION 事务名;
/*
执行SQL语句块:
SQL语句1;
SQL语句2;
......
SQL语句n;
*/
-- 若SQL语句执行成功,则提交事务
COMMIT 事务名;
-- 若SQL语句执行失败,则回滚事务
ROLLBACK 事务名;
-- 结束事务
SET autocommit=1;-- 开启事务自动提交
-- 设置事务保存点
SAVEPOINT 事务保存点名;
-- 回滚到事务保存点
ROLLBACK TO SAVEPOINT 事务保存点名;
-- 撤销事务保存点
RELEASE SAVEPOINT 事务保存点名;
17、MySQL索引(MySQL Index)
索引的本质是数据结构,其可以使MySQL高效获取数据的数据结构。
17.1、索引分类(Index Classification)
- 17.1.1、主键索引。
PRIMARY KEY关键字,唯一的标识,主键不可重复,只能有一个列作为主键。
- 17.1.2、唯一索引
UNIQUE KEY关键字,避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引。
- 17.1.3、常规索引
KEY或INDEX关键字。
-
17.1.4、全文索引
FULLTEXT关键字,只能为CHAR、VARCHAR、TEXT列创建,可以快速定位数据。
- 17.1.4.1、MySQL5.6版本之前,只有 MyISAM数据库引擎支持全文索引。
- 17.1.4.2、MySQL5.6版本之后,InnoDB或MyISAM数据库引擎都支持全文索引。
17.2、索引使用(Index Use)
-- MySQL索引
/*
索引的使用:索引在数据量小时,效率不明显,在数据量大时,效率非常明显。
1、在创建表的时候给字段添加索引
2、在创建表完后再给字段添加索引
*/
-- 显示指定表所有的索引信息
SHOW INDEX FROM `selftable`;
-- 增加一个全文索引
ALTER TABLE `selftable` ADD FULLTEXT INDEX `name`(`name`);
-- 分析SQL语句执行状况
EXPLAIN SELECT * FROM `selftable`;-- 非全文索引
EXPLAIN SELECT * FROM `selftable` WHERE MATCH(`name`) AGAINST('Java');-- 全文索引
17.3、索引原则(Index Principle)
- 17.3.1、表中索引并非越多越好。
- 17.3.2、不要对表中易变动数据字段列加索引。
- 17.3.3、数据量较小的表中不需要加索引。
- 17.3.4、表中索引一般加在经常查询的字段上。
18、权限管理和数据备份(Rights Management And Data Backup)
18.1、权限管理(Rights Management)
18.1.1、SQLyog可视化管理操作
MySQL权限管理参考网址。
18.1.2、SQL命令语句操作
-- 用户权限管理
-- 创建用户
CREATE USER `xueshanxuehai` IDENTIFIED BY '123456';
-- 修改当前用户秘密
SET PASSWORD=PASSWORD('123456');
-- 修改指定用户密码
SET PASSWORD FOR `xueshanxuehai`=PASSWORD('123');
-- 重命名用户名称
RENAME USER `xueshanxuehai` TO `xsxh`;
-- 用户授权:其中参数“ALL PRIVILEGES”代表除了给别人授权之外的所有权限
GRANT ALL PRIVILEGES ON *.* TO `xsxh`;
-- 查询指定用户权限
SHOW GRANTS FOR `xsxh`;
SHOW GRANTS FOR root@localhost;
-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM `xsxh`;
-- 删除用户
DROP USER `xsxh`;
18.2、数据备份(Data Backup)
18.2.1、SQLyog可视化管理操作
MySQL数据备份参考网址。
18.2.2、CMD命令语句操作
# 导出备份数据
# 导出单张数据表备份数据:mysqldump -h主机名 -u用户名 -p密码 库名 表名 > 物理磁盘位置路径/文件名.sql
mysqldump -hlocalhost -uroot -p123456 school student > D:/a.sql
# 导出多张数据表备份数据:mysqldump -h主机名 -u用户名 -p密码 库名 表1名 表2名 ... > 物理磁盘位置路径/文件名.sql
mysqldump -hlocalhost -uroot -p123456 school student grade md5_table > D:/b.sql
# 导出数据库备份数据:mysqldump -h主机名 -u用户名 -p密码 库名 > 物理磁盘位置路径/文件名.sql
mysqldump -hlocalhost -uroot -p123456 school > D:/c.sql
# 导入备份数据
# 若导入备份数据对应的数据库不存在,则需先创建指定空数据库
# 登录MySQL
mysql -uroot -p123456
# 创建指定空数据库
create database `school`;
# 导入指定数据库数据表备份数据(方式1)
# 登录MySQL
mysql -uroot -p123456
# 切换到指定数据库
use `school`;
# 导入指定数据表备份数据
source D:/c.sql
# 导入指定数据库数据表备份数据(方式2)
mysql -hlocalhost -uroot -p123456 school < D:/c.sql
# 特别注意:1、为防止数据丢失,需备份数据库数据;2、若需把数据给他人测试,直接给备份sql文件即可。
19、规范数据库设计(Standardize DataBase Design)
19.1、不同数据库设计(Different DataBase Design)
-
19.1.1、不好的数据库设计
- 19.1.1.1、数据冗余、浪费空间。
- 19.1.1.2、数据库插入和删除都不方便(会出现外键约束异常)。
- 19.1.1.3、程序性能差。
-
19.1.2、良好的数据库设计
- 19.1.2.1、节省内存空间。
- 19.1.2.2、保证数据库的完整性。
- 19.1.2.3、便于系统开发。
19.2、三大范式(Three Paradigms)
- 19.2.1、第一范式(First Paradigm)
保证每一列不可再分(即,原子性)。
- 19.2.2、第二范式(Second Paradigm)
在满足第一范式的前提下,保证每张表只描述一件事情。
-
19.2.3、第三范式(Third Paradigm)
在满足第一和第二范式的前提下,保证数据表中每一列数据都和主键直接相关,而不能间接相关。
19.3、规范性与性能的问题(Normative And Performance)
- 19.3.1、关联查询的表不得超过三张表。
- 19.3.2、考虑商业化的需求与目标(成本与用户体验)时,数据库的性能更重要。
- 19.3.3、在考虑性能时,也需适当的考虑一下规范性。
- 19.3.4、有时会给某些表故意增加一些冗余的字段,从而提升性能(如:可以从多表查询变为单表查询)。
- 19.3.5、有时也会给某些表增加一些计算列,从而提升性能(如:增加索引列,可以将大数据量查询变为小数据量的查询,从而提高查询速度)。
20、JDBC(Java DataBase Connectivity)
SUN公司为了简化开发人员对数据库的统一操作,提供了一个Java操作数据库的规范(即,JDBC),且这些规范的实现都由具体的数据库厂商去做,从而开发人员只需掌握JDBC接口的操作即可,如下图所示。
20.1、使用IDEA编写JDBC程序(Use IDEA Write JDBC Program)
其具体实现步骤,如下所示。
-
20.1.1、创建一个IDEA工程项目。
-
20.1.2、导入数据库驱动文件(即,mysql-connector-java-5.1.47.jar),如下图所示。
-
20.1.3、将数据库驱动文件(即,mysql-connector-java-5.1.47.jar)添加为库,如下图所示。
-
20.1.4、编写JDBC程序,如下所示。
其示例代码,如下所示。
import java.sql.*; public class JDBC { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1、加载JDBC驱动(固定写法) Class.forName("com.mysql.jdbc.Driver"); //2、URL:其格式为“jdbc:协议(如mysql)://主机地址:端口号/数据库名?参数1(是否使用Unicode字符集)&参数2(指定字符编码)&参数3(是否使用SSL连接)”。 //特别注意:把url后边的安全连接参数删除(有警告)或改成false[SQL版本大于connect版本,就要设置成false])。 //String url="jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=true"; String url="jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false"; //3、用户信息 String username="root";//用户名 String password="123456";//密码 //4、数据库连接对象 Connection connection= DriverManager.getConnection(url,username,password); //5、SQL语句执行对象 Statement statement=connection.createStatement(); //6、SQL语句 String sql="select * from grade"; //7、执行SQL语句 ResultSet resultSet=statement.executeQuery(sql);//返回查询结果集(其中包含全部查询结果) while(resultSet.next()){ System.out.println("gradeid="+resultSet.getObject("gradeid")); System.out.println("gradename="+resultSet.getObject("gradename")); } //8、释放数据库连接对象资源 resultSet.close(); statement.close(); connection.close(); } }
其运行结果,如下所示。
gradeid=1 gradename=1年级 gradeid=2 gradename=2年级 gradeid=3 gradename=3年级 gradeid=5 gradename=4年级 gradeid=6 gradename=5年级
20.2、JDBC对象(JDBC Objects)
20.2.1、Connection对象(Connection Object)
//数据库连接对象
Connection connection= DriverManager.getConnection(url,username,password);
connection.commit();//数据库事务提交
connection.rollback();//数据库事务回滚
connection.setAutoCommit(true);//设置数据库事务是否自动提交,默认参数为true,代表自动提交;否则参数为false,代表不自动提交
20.2.2、ResultSet对象(ResultSet Object)
ResultSet resultSet=statement.executeQuery(sql);//返回查询结果集(其中包含全部查询结果)
resultSet.getObject("gradeid");//不知道"gradeid"列类型
resultSet.getInt("gradeid");//知道"gradeid"列类型为Int
resultSet.beforeFirst();//移动到第一行数据
resultSet.afterLast();//移动到最后行数据
resultSet.next();//移动到下一行数据
resultSet.previous();//移动到上一行数据
resultSet.absolute(1);//移动到指定行数据
20.2.3、Statement对象(Statement Object)
JDBC中Statement对象用于向数据库发送SQL语句(增查删改操作,即 CRUD操作)。
其中Statement对象的executeUpdate方法,用于向数据库发送增、删、改操作的SQL语句,且执行完后,会返回一个整数(代表对应数据表受影响的行数)。
其中Statement对象的executeQuery方法,用于向数据库发送查操作的SQL语句,且执行完后,会返回一个ResultSet对象(代表对应数据表查询的结果)。
20.2.3.1、提取工具类
配置文件(db.properties)内容,如下所示。
# 数据库驱动名称
driver=com.mysql.jdbc.Driver
# url,其中特别注意的是:当数据库安装版本低于数据库驱动版本时“useSSL参数设定值”必须为"useSSL=true",否则必须为"useSSL=false"。
url=jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false
# 用户名
username=root
# 密码
password=123456
JDBCUtils_STA工具类示例代码,如下所示。
package jdbc.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils_STA {
private static String driver=null;
private static String url=null;
private static String username=null;
private static String password=null;
//静态代码快(只会在第一次加载类时执行)
static{
try {
InputStream inputStream= JDBCUtils_STA.class.getClassLoader().getResourceAsStream("resources/db.properties");
Properties properties=new Properties();
properties.load(inputStream);
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
Class.forName(driver);//固定写法,加载数据库驱动
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放数据库连接对象资源
public static void release(Connection conn, Statement sta, ResultSet res){
if(res!=null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(sta!=null){
try {
sta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
20.2.3.2、实现增查删改操作
-
20.2.3.2.1、增操作(Create操作)
其示例代码,如下所示。
package jdbc.statement; import jdbc.utils.JDBCUtils_STA; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //SQL语句增加操作 public class InsertSql { public static void main(String[] args) { Connection conn=null; Statement sta=null; ResultSet res=null; try { conn= JDBCUtils_STA.getConnection();//获取数据库连接对象 sta=conn.createStatement();//获得SQL语句指定对象 String sql="insert into grade(gradeid,gradename) VALUES(7,'7年级')";//SQL语句字符串 int rn=sta.executeUpdate(sql); if(rn>0){ System.out.println("插入数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_STA.release(conn,sta,res); } } }
其运行结果,如下所示。
插入数据成功
-
20.2.3.2.2、删操作(Delete操作)
其示例代码,如下所示。
package jdbc.statement; import jdbc.utils.JDBCUtils_STA; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //SQL语句删除操作 public class DeleteSql { public static void main(String[] args) { Connection conn=null; Statement sta=null; ResultSet res=null; try { conn= JDBCUtils_STA.getConnection();//获取数据库连接对象 sta=conn.createStatement();//获得SQL语句指定对象 String sql="delete from grade where gradename='8年级'";//SQL语句字符串 int rn=sta.executeUpdate(sql); if(rn>0){ System.out.println("删除数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_STA.release(conn,sta,res); } } }
其运行结果,如下所示。
删除数据成功
-
20.2.3.2.3、改操作(Update操作)
其示例代码,如下所示。
package jdbc.statement; import jdbc.utils.JDBCUtils_STA; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //SQL语句修改操作 public class UpdateSQL { public static void main(String[] args) { Connection conn=null; Statement sta=null; ResultSet res=null; try { conn= JDBCUtils_STA.getConnection();//获取数据库连接对象 sta=conn.createStatement();//获得SQL语句指定对象 String sql="update grade set gradename='8年级' where gradename='7年级'";//SQL语句字符串 int rn=sta.executeUpdate(sql); if(rn>0){ System.out.println("更新数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_STA.release(conn,sta,res); } } }
其运行结果,如下所示。
更新数据成功
-
20.2.3.2.4、查操作(Retrieve操作)
其示例代码,如下所示。
package jdbc.statement; import jdbc.utils.JDBCUtils_STA; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //SQL语句查询操作 public class SelectSql { public static void main(String[] args) { Connection conn=null; Statement sta=null; ResultSet res=null; try { conn= JDBCUtils_STA.getConnection();//获取数据库连接对象 sta=conn.createStatement();//获得SQL语句指定对象 String sql="select * from grade";//SQL语句字符串 res=sta.executeQuery(sql); while(res.next()){ System.out.println("gradeid="+res.getInt("gradeid")); System.out.println("gradename="+res.getString("gradename")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_STA.release(conn,sta,res); } } }
其运行结果,如下所示。
gradeid=1 gradename=1年级 gradeid=2 gradename=2年级 gradeid=3 gradename=3年级 gradeid=4 gradename=4年级 gradeid=5 gradename=5年级 gradeid=6 gradename=6年级
-
20.2.3.2.5、会发生SQL注入问题
其示例代码,如下所示。
package jdbc.statement; import jdbc.utils.JDBCUtils_STA; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * SQL注入问题:由于SQL会被拼接,从而存在漏洞,会容易被攻击导致数据泄露。 */ public class SqlInjectionProblem { public static void main(String[] args) { //login("张三","12321");//正常获取用户信息 login(" 'or '1=1"," 'or '1=1");//异常获取所有用户信息(即,SQL注入问题) } //登录业务 public static void login(String username,String password){ Connection conn=null; Statement sta=null; ResultSet res=null; try { conn= JDBCUtils_STA.getConnection();//获取数据库连接对象 sta=conn.createStatement();//获得SQL语句指定对象 String sql="select * from student where name='"+username+"' and pwd='"+password+"'";//SQL语句字符串 res=sta.executeQuery(sql); while(res.next()){ System.out.println("name="+res.getString("name")); System.out.println("pwd="+res.getString("pwd")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_STA.release(conn,sta,res); } } }
其运行结果,如下所示。
name=刘大 pwd=12321 name=王二 pwd=12321 name=张三 pwd=12321 name=李四 pwd=12321 name=赵五 pwd=12321 name=张风雷 pwd=12321 name=李风雨 pwd=12321
20.2.4、PreparedStatement对象(PreparedStatement Object)
PreparedStatement可以防止Statement导致的SQL注入问题发生,且执行效率更好。
20.2.4.1、提取工具类
配置文件(db.properties)内容,如下所示。
# 数据库驱动名称
driver=com.mysql.jdbc.Driver
# url,其中特别注意的是:当数据库安装版本低于数据库驱动版本时“useSSL参数设定值”必须为"useSSL=true",否则必须为"useSSL=false"。
url=jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false
# 用户名
username=root
# 密码
password=123456
JDBCUtils_PSTA工具类示例代码,如下所示。
package jdbc.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils_PSTA {
private static String driver=null;
private static String url=null;
private static String username=null;
private static String password=null;
//静态代码快(只会在第一次加载类时执行)
static{
try {
InputStream inputStream= JDBCUtils_PSTA.class.getClassLoader().getResourceAsStream("resources/db.properties");
Properties properties=new Properties();
properties.load(inputStream);
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
Class.forName(driver);//固定写法,加载数据库驱动
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放数据库连接对象资源
public static void release(Connection conn, PreparedStatement psta, ResultSet res){
if(res!=null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(psta!=null){
try {
psta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
20.2.4.2、实现增查删改操作
-
20.2.4.2.1、增操作(Create操作)
其示例代码,如下所示。
package jdbc.preparedstatement; import jdbc.utils.JDBCUtils_PSTA; import java.sql.*; //SQL语句增加操作 public class InsertSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_PSTA.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="insert into student(name,pwd,sex,birthday,gradeid) values(?,?,?,?,?)"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学山"); psta.setString(2,"123456789"); psta.setString(3,"男"); /** * 特别注意: * 1、Java日期时间:java.util.Date(),Java时间戳:java.util.Date().getTime(); * 2、数据库日期时间:java.sql.Date();数据库时间戳:java.sql.Date().getTime(); */ psta.setDate(4,new java.sql.Date(new java.util.Date().getTime())); psta.setInt(5,1); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("插入数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_PSTA.release(conn,psta,res); } } }
其运行结果,如下所示。
插入数据成功
-
20.2.4.2.2、删操作(Delete操作)
其示例代码,如下所示。
package jdbc.preparedstatement; import jdbc.utils.JDBCUtils_PSTA; import java.sql.*; //SQL语句删除操作 public class DeleteSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_PSTA.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="delete from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("删除数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_PSTA.release(conn,psta,res); } } }
其运行结果,如下所示。
删除数据成功
-
20.2.4.2.3、改操作(Update操作)
其示例代码,如下所示。
package jdbc.preparedstatement; import jdbc.utils.JDBCUtils_PSTA; import java.sql.*; //SQL语句修改操作 public class UpdateSQL { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_PSTA.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="update student set name=? where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); psta.setString(2,"学山"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("更新数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_PSTA.release(conn,psta,res); } } }
其运行结果,如下所示。
更新数据成功
-
20.2.4.2.4、查操作(Retrieve操作)
其示例代码,如下所示。
package jdbc.preparedstatement; import jdbc.utils.JDBCUtils_PSTA; import java.sql.*; //SQL语句查询操作 public class SelectSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_PSTA.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="select name,pwd,sex,birthday,gradeid from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"张三"); res=psta.executeQuery();//执行SQL语句 while(res.next()){ System.out.println("name="+res.getString("name")); System.out.println("pwd="+res.getString("pwd")); System.out.println("sex="+res.getString("sex")); System.out.println("birthday="+res.getDate("birthday")); System.out.println("gradeid="+res.getInt("gradeid")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_PSTA.release(conn,psta,res); } } }
其运行结果,如下所示。
name=张三 pwd=12321 sex=男 birthday=2021-10-03 gradeid=3
-
20.2.4.2.5、不会发生SQL注入问题
其示例代码,如下所示。
package jdbc.preparedstatement; import jdbc.utils.JDBCUtils_PSTA; import java.sql.*; /** * SQL注入问题:由于SQL会被拼接,从而存在漏洞,会容易被攻击导致数据泄露。 */ public class SqlInjectionProblem { public static void main(String[] args) { //login("张三","12321");//正常获取用户信息 login(" 'or '1=1"," 'or '1=1");//不能获取用户信息(即,不会发生SQL注入问题) } //登录业务 public static void login(String username,String password){ Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_PSTA.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="select name,pwd,sex,birthday,gradeid from student where name=? and pwd=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,username); psta.setString(2,password); res=psta.executeQuery();//执行SQL语句 while(res.next()){ System.out.println("name="+res.getString("name")); System.out.println("pwd="+res.getString("pwd")); System.out.println("sex="+res.getString("sex")); System.out.println("birthday="+res.getDate("birthday")); System.out.println("gradeid="+res.getInt("gradeid")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_PSTA.release(conn,psta,res); } } }
20.3、使用IDEA连接数据库(Use IDEA Connection DataBase)
其具体实现步骤,如下所示。
-
20.3.1、选择MySQL连接项目,如下图所示。
-
20.3.2、配置MySQL数据源驱动,如下图所示。
-
20.3.3、测试MySQL连接,如下图所示。
-
20.3.4、选择MySQL数据库"jdbc_test",如下图所示。
-
20.3.5、MySQL数据库配置完成,如下图所示。
20.4、使用IDEA操作数据库连接池(Use IDEA Operation DataBase Connection Pool)
一般操作数据库时,会频繁的连接、处理、释放,十分消耗资源,所以建议操作数据库连接池(即,采取池化技术<如:预先准备好一些缓存资源,数据库连接时优先使用这些缓存资源,从而避免频繁创建于释放资源>)。
数据库连接池的本质就是实现DataSource接口。
20.4.1、DBCP数据库连接池
前提条件:先导入对应jar包(即,commons-dbcp-1.4.jar、commons-pool-1.6.jar),具体操作请参考前面“导入数据库驱动文件(即,mysql-connector-java-5.1.47.jar)”操作。
20.4.1.1、提取工具类
配置文件(db_dbcp.properties)内容,如下所示。
# 连接设置:其中所有的名字都是DBCP数据源(即,DBCP数据库连接池)中定义好的。
# 数据库驱动名称
driverClassName=com.mysql.jdbc.Driver
# url,其中特别注意的是:当数据库安装版本低于数据库驱动版本时“useSSL参数设定值”必须为"useSSL=true",否则必须为"useSSL=false"。
url=jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false
# 用户名
username=root
# 密码
password=123456
# 初始化连接数
initialSize=10
# 最大连接数
maxActive=50
# 最大空闲连接数
maxIdle=20
# 最小空闲连接数
minIdle=5
# 超时等待时间(单位:毫秒)
maxWait=60000
# JDBC驱动建立连接时附带的连接属性:其格式为“属性名=property”
connectionProperties=useUnicode=true;characterEncoding=utf8
# 指定由连接池所创建的连接对象的自动提交(auto-commit)状态
defaultAutoCommit=true
# 指定由连接池所创建的连接对象的只读(read-only)状态:若未设置值,则“setReadOnly”方法不被调用(某些驱动并不支持只读模式,如Informix)
defaultReadOnly=
# 指定由连接池所创建的连接对象的事务隔离级别(TransactionIsolation):NONE、READ_UNCOMMITTED(读未提交)、READ_COMMITTED(读提交)、REPEATABLE_READ(可重复读取)、SERIALIZABLE(可序化)
defaultTransactionIsolation=READ_UNCOMMITTED
JDBCUtils_DBCP工具类示例代码,如下所示。
package jdbc.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtils_DBCP {
private static DataSource dataSource = null;
//静态代码快(只会在第一次加载类时执行)
static {
try {
InputStream inputStream = JDBCUtils_DBCP.class.getClassLoader().getResourceAsStream("resources/db_dbcp.properties");
Properties properties = new Properties();
properties.load(inputStream);
//创建数据源(数据库连接池):固定方式,使用工厂模式创建
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();//从数据源(数据库连接池)中获取连接
}
//释放数据库连接对象资源
public static void release(Connection conn, PreparedStatement psta, ResultSet res) {
if (res != null) {
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (psta != null) {
try {
psta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
20.4.1.2、实现增查删改操作
-
20.4.1.2.1、增操作(Create操作)
其示例代码,如下所示。
package jdbc.dbcp; import jdbc.utils.JDBCUtils_DBCP; import java.sql.*; //SQL语句增加操作 public class InsertSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_DBCP.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="insert into student(name,pwd,sex,birthday,gradeid) values(?,?,?,?,?)"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学山"); psta.setString(2,"123456789"); psta.setString(3,"男"); /** * 特别注意: * 1、Java日期时间:java.util.Date(),Java时间戳:java.util.Date().getTime(); * 2、数据库日期时间:java.sql.Date();数据库时间戳:java.sql.Date().getTime(); */ psta.setDate(4,new Date(new java.util.Date().getTime())); psta.setInt(5,1); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("插入数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_DBCP.release(conn,psta,res); } } }
其运行结果,如下所示。
插入数据成功
-
20.4.1.2.2、删操作(Delete操作)
其示例代码,如下所示。
package jdbc.dbcp; import jdbc.utils.JDBCUtils_DBCP; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句删除操作 public class DeleteSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_DBCP.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="delete from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("删除数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_DBCP.release(conn,psta,res); } } }
其运行结果,如下所示。
删除数据成功
-
20.4.1.2.3、改操作(Update操作)
其示例代码,如下所示。
package jdbc.dbcp; import jdbc.utils.JDBCUtils_DBCP; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句修改操作 public class UpdateSQL { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_DBCP.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="update student set name=? where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); psta.setString(2,"学山"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("更新数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_DBCP.release(conn,psta,res); } } }
其运行结果,如下所示。
更新数据成功
-
20.4.1.2.4、查操作(Retrieve操作)
其示例代码,如下所示。
package jdbc.dbcp; import jdbc.utils.JDBCUtils_DBCP; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句查询操作 public class SelectSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_DBCP.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="select name,pwd,sex,birthday,gradeid from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"张三"); res=psta.executeQuery();//执行SQL语句 while(res.next()){ System.out.println("name="+res.getString("name")); System.out.println("pwd="+res.getString("pwd")); System.out.println("sex="+res.getString("sex")); System.out.println("birthday="+res.getDate("birthday")); System.out.println("gradeid="+res.getInt("gradeid")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_DBCP.release(conn,psta,res); } } }
其运行结果,如下所示。
name=张三 pwd=12321 sex=男 birthday=2021-10-03 gradeid=3
20.4.2、C3P0数据库连接池
前提条件:先导入对应jar包(即,c3p0-0.9.5.5.jar、mchange-commons-java-0.2.19.jar),具体操作请参考前面“导入数据库驱动文件(即,mysql-connector-java-5.1.47.jar)”操作。
20.4.2.1、提取工具类
配置文件(c3p0-config.xml)内容,如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!--此配置文件名必须为“c3p0-config”,且此配置文件放到工程“src”根目录下,否则无法正常加载使用-->
<c3p0-config>
<!--
C3P0的默认(缺省)配置:对应代码为“ComboPooledDataSource dataSource = new ComboPooledDataSource();”。
-->
<default-config>
<!--数据库驱动名称-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!--url,其中特别注意的是:当数据库安装版本低于数据库驱动版本时“useSSL参数设定值”必须为"useSSL=true",否则必须为"useSSL=false"。-->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false</property>
<!--用户名-->
<property name="user">root</property>
<!--密码-->
<property name="password">123456</property>
<!--如果数据库连接池中数据连接不够时一次增长多少个-->
<property name="acquireIncrement">5</property>
<!--初始化数据库连接池数量-->
<property name="initialPoolSize">10</property>
<!--数据库连接池最大连接数量-->
<property name="maxPoolSize">20</property>
<!--数据库连接池最小连接数量-->
<property name="minPoolSize">2</property>
<!--每次最多可以执行多少个批处理语句-->
<property name="maxStatements">30</property>
</default-config>
<!--
C3P0的自定义命名配置:对应代码为“ComboPooledDataSource dataSource = new ComboPooledDataSource("MySQL");”。
-->
<named-config name="MySQL">
<!--数据库驱动名称-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!--url,其中特别注意的是:当数据库安装版本低于数据库驱动版本时“useSSL参数设定值”必须为"useSSL=true",否则必须为"useSSL=false"。-->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false</property>
<!--用户名-->
<property name="user">root</property>
<!--密码-->
<property name="password">123456</property>
<!--如果数据库连接池中数据连接不够时一次增长多少个-->
<property name="acquireIncrement">5</property>
<!--初始化数据库连接池数量-->
<property name="initialPoolSize">10</property>
<!--数据库连接池最大连接数量-->
<property name="maxPoolSize">20</property>
<!--数据库连接池最小连接数量-->
<property name="minPoolSize">2</property>
<!--每次最多可以执行多少个批处理语句-->
<property name="maxStatements">30</property>
</named-config>
</c3p0-config>
JDBCUtils_C3P0工具类示例代码,如下所示。
package jdbc.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCUtils_C3P0 {
private static ComboPooledDataSource dataSource = null;
//静态代码快(只会在第一次加载类时执行)
static {
try {
// //方式一:代码配置版
// dataSource=new ComboPooledDataSource();
// dataSource.setDriverClass("");
// dataSource.setJdbcUrl("");
// dataSource.setUser("");
// dataSource.setPassword("");
// dataSource.setMaxPoolSize(20);
// ......
//方式二:xml文件配置版,创建数据源(数据库连接池):固定方式,使用工厂模式创建
dataSource = new ComboPooledDataSource("MySQL");
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();//从数据源(数据库连接池)中获取连接
}
//释放数据库连接对象资源
public static void release(Connection conn, PreparedStatement psta, ResultSet res) {
if (res != null) {
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (psta != null) {
try {
psta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
20.4.2.2、实现增查删改操作
-
20.4.2.2.1、增操作(Create操作)
其示例代码,如下所示。
package jdbc.c3p0; import jdbc.utils.JDBCUtils_C3P0; import java.sql.*; //SQL语句增加操作 public class InsertSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_C3P0.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="insert into student(name,pwd,sex,birthday,gradeid) values(?,?,?,?,?)"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学山"); psta.setString(2,"123456789"); psta.setString(3,"男"); /** * 特别注意: * 1、Java日期时间:java.util.Date(),Java时间戳:java.util.Date().getTime(); * 2、数据库日期时间:java.sql.Date();数据库时间戳:java.sql.Date().getTime(); */ psta.setDate(4,new Date(new java.util.Date().getTime())); psta.setInt(5,1); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("插入数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_C3P0.release(conn,psta,res); } } }
其运行结果,如下所示。
10月 04, 2021 3:55:09 下午 com.mchange.v2.log.MLog 信息: MLog clients using java 1.4+ standard logging. 10月 04, 2021 3:55:09 下午 com.mchange.v2.c3p0.C3P0Registry 信息: Initializing c3p0-0.9.5.5 [built 11-December-2019 22:07:46 -0800; debug? true; trace: 10] 10月 04, 2021 3:55:09 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2t2kpaakkm5m7ikcfb80|9629756, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 插入数据成功
-
20.4.2.2.2、删操作(Delete操作)
其示例代码,如下所示。
package jdbc.c3p0; import jdbc.utils.JDBCUtils_C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句删除操作 public class DeleteSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_C3P0.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="delete from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("删除数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_C3P0.release(conn,psta,res); } } }
其运行结果,如下所示。
10月 04, 2021 4:00:48 下午 com.mchange.v2.log.MLog 信息: MLog clients using java 1.4+ standard logging. 10月 04, 2021 4:00:48 下午 com.mchange.v2.c3p0.C3P0Registry 信息: Initializing c3p0-0.9.5.5 [built 11-December-2019 22:07:46 -0800; debug? true; trace: 10] 10月 04, 2021 4:00:48 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2t2kpaakkmcvq01omtpg3|9629756, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 删除数据成功
-
20.4.2.2.3、改操作(Update操作)
其示例代码,如下所示。
package jdbc.c3p0; import jdbc.utils.JDBCUtils_C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句修改操作 public class UpdateSQL { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_C3P0.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="update student set name=? where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"学海"); psta.setString(2,"学山"); int rn=psta.executeUpdate();//执行SQL语句 if(rn>0){ System.out.println("更新数据成功"); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_C3P0.release(conn,psta,res); } } }
其运行结果,如下所示。
10月 04, 2021 3:59:38 下午 com.mchange.v2.log.MLog 信息: MLog clients using java 1.4+ standard logging. 10月 04, 2021 3:59:39 下午 com.mchange.v2.c3p0.C3P0Registry 信息: Initializing c3p0-0.9.5.5 [built 11-December-2019 22:07:46 -0800; debug? true; trace: 10] 10月 04, 2021 3:59:39 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2t2kpaakkmbe2l1wto9dk|9629756, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 更新数据成功
-
20.4.2.2.4、查操作(Retrieve操作)
其示例代码,如下所示。
package jdbc.c3p0; import jdbc.utils.JDBCUtils_C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //SQL语句查询操作 public class SelectSql { public static void main(String[] args) { Connection conn=null; PreparedStatement psta=null; ResultSet res=null; try { //获取数据库连接对象 conn= JDBCUtils_C3P0.getConnection(); //SQL语句字符串:使用占位符(?)代替参数 String sql="select name,pwd,sex,birthday,gradeid from student where name=?"; //获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL psta= conn.prepareStatement(sql); //手动给参数赋值,按照字段列的顺序一一对应 psta.setString(1,"张三"); res=psta.executeQuery();//执行SQL语句 while(res.next()){ System.out.println("name="+res.getString("name")); System.out.println("pwd="+res.getString("pwd")); System.out.println("sex="+res.getString("sex")); System.out.println("birthday="+res.getDate("birthday")); System.out.println("gradeid="+res.getInt("gradeid")); } } catch (SQLException throwables) { throwables.printStackTrace(); }finally{ JDBCUtils_C3P0.release(conn,psta,res); } } }
其运行结果,如下所示。
10月 04, 2021 4:02:11 下午 com.mchange.v2.log.MLog 信息: MLog clients using java 1.4+ standard logging. 10月 04, 2021 4:02:11 下午 com.mchange.v2.c3p0.C3P0Registry 信息: Initializing c3p0-0.9.5.5 [built 11-December-2019 22:07:46 -0800; debug? true; trace: 10] 10月 04, 2021 4:02:11 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2t2kpaakkmenid9n5xs1|9629756, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] name=张三 pwd=12321 sex=男 birthday=2021-10-03 gradeid=3
20.5、使用IDEA相关工具类操作数据库事务(Use IDEA Related Tool Classes Operation DataBase Transaction)
20.5.1、使用JDBCUtils_STA工具类操作数据库事务
其示例代码,如下所示。
package jdbc.transaction;
import jdbc.utils.JDBCUtils_STA;
import java.sql.*;
//数据库事务操作
public class Transaction_STA {
public static void main(String[] args) {
Connection conn = null;
Statement sta = null;
ResultSet res = null;
try {
conn = JDBCUtils_STA.getConnection();//获取数据库连接对象
conn.setAutoCommit(false);//关闭数据库事务的自动提交(默认参数为true就是代表自动提交事务)
sta = conn.createStatement();//获得SQL语句指定对象
String sql = "update student set name='学海' where name='学山'";//SQL语句字符串
sta.executeUpdate(sql);//执行SQL语句
sql = "update student set sex='女' where name='学海'";
sta.executeUpdate(sql);
conn.commit();//业务完成,提交事务
System.out.println("事务提交成功");
} catch (SQLException throwables) {
try {
throwables.printStackTrace();
System.out.println("事务提交失败");
conn.rollback();//业务失败,回滚事务
System.out.println("事务回滚成功");
} catch (SQLException e) {
System.out.println("事务回滚失败");
e.printStackTrace();
}
} finally {
JDBCUtils_STA.release(conn, sta, res);
}
}
}
其运行结果,如下所示。
事务提交成功
20.5.2、使用JDBCUtils_PSTA工具类操作数据库事务
其示例代码,如下所示。
package jdbc.transaction;
import jdbc.utils.JDBCUtils_PSTA;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//数据库事务操作
public class Transaction_PSTA {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement psta=null;
ResultSet res=null;
try {
//获取数据库连接对象
conn= JDBCUtils_PSTA.getConnection();
//关闭数据库事务的自动提交(默认参数为true就是代表自动提交事务)
conn.setAutoCommit(false);
//SQL语句字符串:使用占位符(?)代替参数
String sql="update student set name=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"学海");
psta.setString(2,"学山");
psta.executeUpdate();//执行SQL语句
//SQL语句字符串:使用占位符(?)代替参数
sql="update student set sex=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"女");
psta.setString(2,"学海");
psta.executeUpdate();//执行SQL语句
conn.commit();//业务完成,提交事务
System.out.println("事务提交成功");
} catch (SQLException throwables) {
try {
throwables.printStackTrace();
System.out.println("事务提交失败");
conn.rollback();//业务失败,回滚事务
System.out.println("事务回滚成功");
} catch (SQLException e) {
System.out.println("事务回滚失败");
e.printStackTrace();
}
}finally{
JDBCUtils_PSTA.release(conn,psta,res);
}
}
}
其运行结果,如下所示。
事务提交成功
20.5.3、使用JDBCUtils_DBCP工具类操作数据库事务
其示例代码,如下所示。
package jdbc.transaction;
import jdbc.utils.JDBCUtils_DBCP;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//数据库事务操作
public class Transaction_DBCP {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement psta=null;
ResultSet res=null;
try {
//获取数据库连接对象
conn= JDBCUtils_DBCP.getConnection();
//关闭数据库事务的自动提交(默认参数为true就是代表自动提交事务)
conn.setAutoCommit(false);
//SQL语句字符串:使用占位符(?)代替参数
String sql="update student set name=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"学海");
psta.setString(2,"学山");
psta.executeUpdate();//执行SQL语句
//SQL语句字符串:使用占位符(?)代替参数
sql="update student set sex=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"女");
psta.setString(2,"学海");
psta.executeUpdate();//执行SQL语句
conn.commit();//业务完成,提交事务
System.out.println("事务提交成功");
} catch (SQLException throwables) {
try {
throwables.printStackTrace();
System.out.println("事务提交失败");
conn.rollback();//业务失败,回滚事务
System.out.println("事务回滚成功");
} catch (SQLException e) {
System.out.println("事务回滚失败");
e.printStackTrace();
}
}finally{
JDBCUtils_DBCP.release(conn,psta,res);
}
}
}
其运行结果,如下所示。
事务提交成功
20.5.4、使用JDBCUtils_C3P0工具类操作数据库事务
其示例代码,如下所示。
package jdbc.transaction;
import jdbc.utils.JDBCUtils_C3P0;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//数据库事务操作
public class Transaction_C3P0 {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement psta=null;
ResultSet res=null;
try {
//获取数据库连接对象
conn= JDBCUtils_C3P0.getConnection();
//关闭数据库事务的自动提交(默认参数为true就是代表自动提交事务)
conn.setAutoCommit(false);
//SQL语句字符串:使用占位符(?)代替参数
String sql="update student set name=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"学海");
psta.setString(2,"学山");
psta.executeUpdate();//执行SQL语句
//SQL语句字符串:使用占位符(?)代替参数
sql="update student set sex=? where name=?";
//获得SQL语句指定对象:预编译SQL,先写SQL,不执行SQL
psta= conn.prepareStatement(sql);
//手动给参数赋值,按照字段列的顺序一一对应
psta.setString(1,"女");
psta.setString(2,"学海");
psta.executeUpdate();//执行SQL语句
conn.commit();//业务完成,提交事务
System.out.println("事务提交成功");
} catch (SQLException throwables) {
try {
throwables.printStackTrace();
System.out.println("事务提交失败");
conn.rollback();//业务失败,回滚事务
System.out.println("事务回滚成功");
} catch (SQLException e) {
System.out.println("事务回滚失败");
e.printStackTrace();
}
}finally{
JDBCUtils_C3P0.release(conn,psta,res);
}
}
}
其运行结果,如下所示。
10月 04, 2021 4:42:08 下午 com.mchange.v2.log.MLog
信息: MLog clients using java 1.4+ standard logging.
10月 04, 2021 4:42:08 下午 com.mchange.v2.c3p0.C3P0Registry
信息: Initializing c3p0-0.9.5.5 [built 11-December-2019 22:07:46 -0800; debug? true; trace: 10]
10月 04, 2021 4:42:09 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> MySQL, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2t2kpaakknu1itbsr0ym|9629756, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/jdbc_test?useUnicode=true&characterEncoding=utf8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
事务提交成功