前端(页面:展示,数据!)
后台(连接点:连接数据库JDBC,链接前端(控制视图跳转,和给前端传递数据))
数据库(存数据)
命令行连接
mysql -uroot -p --连接数据库
update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; --修改密码
flush privileges; --刷新权限
-------------------
--所有的语句都使用分号(;)结尾
show databases; --查看所有的数据库
mysql> use school; --切换数据库
Database changed
show tables;--查看数据库中所有的表
describe **(表名);--显示数据库中所有表的信息
create database **(要创建的数据库名);--创建一个数据库
exit;--退出连接
--单行注释
/*
多行注释
*/
CREATE DATABASE [IF NOT EXISTS] school;(数据库名) --中括号[]代表可选
DROP DATABASE [IF EXISTS] school;
--如果你的表名或者字段名是一个特殊字符,就需要在两边带上``
USE `school`;
SHOW DATABASES;--查看所有的数据库
Java.util.Date(Java下的日期类)
-- 目标:创建一个student数据库
-- 创建学生表(列,字段) 使用SQL创建
-- 学号int 姓名varchar(30) 登录密码varchar(20) 性别varchar(2) 出生日期datetime 家庭住址,email
-- 注意点,使用英文(),表的名称和字段尽量用``括起来
-- AUTO_INCREMENT自增
-- 字符串使用 单引号括起来
-- 所有的语句后面加英文的(,) 最后一句不用加英文的逗号
-- PRIMARY KEY 主键,一般一个表只有一个唯一的主键
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' 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 ;
格式:[]中括号代表不是必需的,是可以设置
CREATE TABLE [IF NOT EXISTS] `表名`(
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
......
`字段名` 列类型 [属性] [索引] [注释]
)[表类型][字符集设置][注释]
SHOW CREATE DATABASE 库名 -- 查看创建数据库的语句
SHOW CREATE TABLE 表名 -- 查看创建数据表的定义语句
DESC 表名 --显示表的结构
NULL | INNODB | MyISAM |
---|---|---|
事务支持 | 支持 | 不支持 |
数据行锁定 | 支持 | 不支持 |
外键约束 | 支持 | 不支持 |
全文索引 | 不支持 | 支持 |
表空间的大小 | 较大,约为后者的2倍 | 较小 |
在物理空间存在的位置
所有数据库的文件都存在data目录下,本质还是文件的存储
设置数据库表的字符集编码
CHARSET=utf8
不设置的话,会用mysql默认的字符集编码(Latin1,不支持中文)
也可在my.ini配置文件中设置默认代码
character_set_server=utf8
-- 修改表名: ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE `student` RENAME AS `student1`
-- 增加表的字段: ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE `student1` ADD age INT(11)
-- 修改表的字段: (重命名,修改约束)
-- ALTER TABLE 表名 MODIFY 字段名 列属性[]
ALTER TABLE student1 MODIFY age VARCHAR(12) -- 修改约束
-- ALTER TABLE 表名 CHANGE 旧名字 新名字 列属性[]
ALTER TABLE student1 CHANGE age age1 INT(1) -- 字段重命名
-- 删除表的字段:ALTER TABLE 表名 DROP 字段名
ALTER TABLE student1 DROP age
-- 删除表(如果表存在再删除)
DROP TABLE IF EXISTS student1
所有的创建和删除操作尽量加上判断,以免报错
-- 如果创建表的时候没有外键关系
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`);
-- ALTER TABLE 表
-- ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES 哪个表(哪个字段)
删除有外键关系的表时候,必须要先删除引用自己的那张表(从表),再删除自己这张表(主表)
(这里了解即可,避免因数据库过多造成困扰)
DML语言:数据库操作语言
-- student这个表 有 id,name,sex.其中id是主键,且是自增的
-- 插入数据
-- insert into 表名([字段名1,字段名2,字段名3]) values('值1','值2','值3`student`')
INSERT INTO `student`(`name`,`sex`) VALUES('你好','女')
-- 由于主键自增我们可以省略,不用插入主键的内容
-- 数据和字段一一对应
-- 插入多个字段
INSERT INTO `student`(`name`,`sex`) VALUES('小王','男'),('小李','女')
-- 字段可以省略
INSERT INTO `student` VALUES(15,'小王','男'),(16,'小李','女')
-- 修改student的名字
UPDATE `student` SET `name`='章茂淳' WHERE id=1;
-- 不指定条件的情况下,会改动所有的表!
UPDATE `student` SET `name`='长江七号' ;
-- 修改多个属性,逗号隔开
UPDATE `student` SET `name`='章茂淳',`sex`='男' WHERE id=1;
-- 语法
-- UPDATE 表名 SET colnum_name = value WHERE [条件]
-- 通过多个条件定位数据
UPDATE `student` SET `name`='章茂淳' WHERE id=1 AND sex='男';
条件:where子句 运算符+id(例如:id<2;id=2;id>2) 等于某个值,大于某个值,在某个区间内修改
操作符 | 含义 | 范围 | 结果 |
---|---|---|---|
= | 等于 | 5=6 | false |
<> 或 != | 不等于 | 5<>6 | true |
BETWEEN…and… | 在某个范围内 | [2,5]都是闭区间 | / |
AND | && | 5>1 and 1>2 | false |
OR | | | | 5>1 or 1>2 | true |
-- 删除数据
DELETE FROM `student`
-- 删除指定数据
DELETE FROM `student` WHERE id=1;
-- 清空表
TRUNCATE `student`;
作用:完全清空一个数据库表,表的结构和索引约束不会变
-- 清空表
TRUNCATE `student`;
-- 测试DELETE 和 TRUNCATE 的区别
CREATE TABLE `test`(
`id` INT(4) NOT NULL AUTO_INCREMENT,
`coll` VARCHAR(20) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `test`(`coll`) VALUES('1'),('2'),('3')
DELETE FROM `test` -- 不会影响自增
TRUNCATE TABLE `test` -- 自增会归零
重启数据库后:
(Data Query LANGUAGE:数据查询语言)
这是一个示例表,在创建这些表并插入数据之后,将使用SELECT来查询表
CREATE DATABASE IF NOT EXISTS `school`;
-- 创建一个school数据库
USE `school`;-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`loginpwd` VARCHAR(20) DEFAULT NULL,
`studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
`sex` TINYINT(1) DEFAULT NULL COMMENT '性别,0或1',
`gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
`phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
`address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
`borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
`email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
`identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
PRIMARY KEY (`studentno`),
UNIQUE KEY `identitycard`(`identitycard`),
KEY `email` (`email`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
-- 插入学生数据
INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','张伟',0,2,'13800001234','北京朝阳','1980-1-1','[email protected]','123456198001011234'),
(1001,'123456','赵强',1,3,'13800002222','广东深圳','1990-1-1','[email protected]','123456199001011233');
-- 创建年级表
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade`(
`gradeid` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
) ENGINE=INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8;
-- 插入年级数据
INSERT INTO `grade` (`gradeid`,`gradename`) VALUES(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');
-- 创建科目表
DROP TABLE IF EXISTS `subject`;
CREATE TABLE `subject`(
`subjectno`INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
`subjectname` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',
`classhour` INT(4) DEFAULT NULL COMMENT '学时',
`gradeid` INT(4) DEFAULT NULL COMMENT '年级编号',
PRIMARY KEY (`subjectno`)
)ENGINE = INNODB AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8;
-- 插入科目数据
INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);
-- 创建成绩表
DROP TABLE IF EXISTS `result`;
CREATE TABLE `result`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`subjectno` INT(4) NOT NULL COMMENT '课程编号',
`examdate` DATETIME NOT NULL COMMENT '考试日期',
`studentresult` INT (4) NOT NULL COMMENT '考试成绩',
KEY `subjectno` (`subjectno`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;
-- 插入成绩数据
INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
VALUES
(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1000,3,'2013-11-11 09:00:00',68),
(1000,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);
-- SELECT 字段 FROM 表
SELECT * FROM `student`
-- 查询指定字段
SELECT `studentno`,`studentname` FROM `student`
-- 别名,给属性名起一起名字 AS 可以给字段起别名,也可以给表起别名
SELECT `studentno` AS 学号,`studentname` AS 学生姓名 FROM `student` AS s
-- 函数
-- Concat(a,b) 拼接字符串
SELECT CONCAT('姓名:',`studentname`) AS 新名字 FROM `student`
-- 查询有哪些同学参加了考试
SELECT `studentno` FROM `result`
-- 发现重复数据,去重
SELECT DISTINCT `studentno` FROM `result`
-- 查询MySQL系统版本 (函数)
SELECT VERSION()
-- 用来计算 (表达式)
SELECT 100*3-1 AS 计算结果
-- 查询自增的步长 (变量)
SELECT @@auto_increment_increment
-- 学生考试成绩 +1分查看
SELECT `studentno`,`studentresult`+1 AS '提分后' FROM `result`
作用:检索数据中符合条件的值
搜索的条件由一个或者多个表达式组成,结果返回的是 布尔值
运算符 | 语法 | 描述 |
---|---|---|
and && | a and b / a&&b | 逻辑与 |
or | | | a or b / a | | b | 逻辑或 |
Not ! | not a / ! a | 逻辑非 |
-- 查询考试成绩在95~100分之间
-- and的使用
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>95 AND `studentresult`<=100
-- a&&的使用
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>95 && `studentresult`<=100
-- 模糊查询(between的用法)
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult` BETWEEN 95 AND 100
-- 查询除了1000号学生之外的成绩
-- not的使用
SELECT `studentno`,`studentresu`lt` FROM result
WHERE NOT `studentno`=1000
-- !=的使用
SELECT `studentno`,`studentresult` FROM result
WHERE `studentno`!=1000
模糊查询
运算符 | 语法 | 描述 |
---|---|---|
IS NULL | a is null | 如果操作符为NULL,结果为真 |
IS NOT NULL | a is not null | 如果操作符不为NULL,结果为真 |
BETWEEN | a between b and c | 若a在b和c之间,则结果为真 |
Like | a like b | SQL匹配,如果a匹配b,则结果为真 |
In | a in(a1,a2,a3…) | 假设a在a1或者a2…其中的某一个值,则结果为真 |
-- like结合 %(代表0到任意个字符)查询所有姓“刘”的同学
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE "刘%"
-- like结合_ 查询姓“刘”姓后只有一个字的同学(两个_ ,就是其后有两个字,可以更多叠加)
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE "刘_"
-- 查询名字中间有“强”的同学 即:%强%
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '%强%'
-- 模糊查询 in
-- 查询 1001,1002号的学员
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentno` IN (1001,1002,1003);
-- 查询在北京的学生
SELECT `studentno`,`studentname` FROM `student`
WHERE `address` IN ('安徽合肥','北京朝阳')
思路:
1.分析需求,分析查询的字段来自哪些表(连接查询)
2.确定使用哪种连接查询? 7种"join"理论
3.确定交叉点(这两个表中哪个数据是相同的)
判断的条件:学生表中的studentNo == 成绩表中的studentNo
join+(连接的表) on+(判断的条件) 连接查询
where 等值查询
-- Inner Join
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
INNER JOIN `result` AS r
ON s.`studentno` = r.`studentno`
-- Right Join
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` s
RIGHT JOIN `result` r
ON s.`studentno` = r.`studentno`
-- left Join
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` s
LEFT JOIN `result` r
ON s.`studentno` = r.`studentno`
操作 | 描述 |
---|---|
Inner join | 如果表中至少有一个匹配,就会返回行 |
Left join | 会从左表中返回所有的值,即使右表中没有匹配 |
right join | 会从右表中返回所有的值,即使左表中没有匹配 |
-- 查询缺考的同学
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` s
LEFT JOIN `result` r
ON s.`studentno` = r.`studentno`
WHERE `studentresult` IS NULL
-- 思考题(查询了参加考试的同学信息:学号,学生姓名,科目名,分数)
/*思路
1.分析需求,分析查询的字段来自哪些表,student、result、subject(连接查询)
2.确定使用哪种连接查询?7种
确定交叉点(这两个表中哪个数据是相同的)
判断的条件:学生表中 studentNo = 成绩表中 studentNo
*/
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
RIGHT JOIN `result` r -- 因为查的是参加考试的同学,所以用的是“右连接”
ON r.`studentno`=s.`studentno`
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
自己的表和自己的表连接,核心:一张表拆为两张一样的表
父类
categoryid | categoryName |
---|---|
2 | 信息技术 |
3 | 软件开发 |
5 | 美术设计 |
子类
pid | categoryid | categoryName |
---|---|---|
3 | 4 | 数据库 |
2 | 8 | 办公信息 |
3 | 6 | web开发 |
5 | 7 | ps技术 |
操作:查询父类对应的子类关系
父类 | 子类 |
---|---|
信息技术 | 办公信息 |
软件开发 | 数据库 |
软件开发 | web开发 |
美术设计 | ps技术 |
-- 查询父子信息
SELECT a.`categoryname` AS '父栏目',b.`categoryname` AS '子栏目'
FROM `category` AS a,`category` AS b
WHERE a.`categoryid`=b.`pid`
-- 查询了参加 数据库结构-1 考试的同学信息:学号,学生姓名,科目名,分数
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
INNER JOIN `result` r
ON s.`studentno`=r.`studentno`
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE `subjectname`='C语言-1'
Order By默认是升序排列的
-- 排序:升序ASC,降序DESC
-- ORDER BY 字段 排序方法
-- 查询结果根据 成绩降序 排序
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
INNER JOIN `result` r
ON s.`studentno`=r.`studentno`
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE `subjectname`='C语言-1'
ORDER BY `studentresult` DESC
-- 分页是为了缓解数据库压力,给人的体验更好
-- 分页,每页只显示五条数据
-- limit 起始值,页面的大小(显示的行数)
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
INNER JOIN `result` r
ON s.`studentno`=r.`studentno`
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE `subjectname`='C语言-1'
ORDER BY `studentresult` DESC
LIMIT 0,5
-- 第一页 limit 0,5
-- 第二页 limit 5,5
-- 第三页 limit 10,5
在where语句中嵌套一个子查询语句
where(select*from)
-- 方式一:查询 C语言-1 的所有考试结果(学号,科目编号,成绩),降序排列
SELECT `studentno`,r.`subjectno`,`studentresult`
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE `subjectname`='C语言-1'
ORDER BY `studentresult` DESC
-- 方式二:使用子查询(由里及外)
SELECT `studentno`,`subjectno`,`studentresult`
FROM `result`
WHERE `subjectno`=(
SELECT `subjectno` FROM `subject`
WHERE `subjectname`='C语言-1'
)
-- 查询不同课程的平均分,最高分,最低分,平均分大于80
-- 核心:根据不同的课程分组
SELECT `subjectname`,AVG(`studentresult`) AS 平均分,MAX(`studentresult`),MIN(`studentresult`)
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
GROUP BY r.`subjectno` -- 如果有多种分组标准,可以写成 GROUP BY 属性名,属性名,属性名....
HAVING 平均分>80 -- having用于“过滤分组”,根据已查询的字段分组,后面可以使用聚合函数(这是where做不到的)
-- 数学运算
SELECT ABS(-8) -- 绝对值
SELECT CEILING(9.4) -- 10,向上取整
SELECT FLOOR(9.4) -- 9,向下取整
SELECT RAND() -- 返回一个0~1的随机数
SELECT SIGN() -- 判断一个数的符号 0返回0 负数返回 -1 正数返回 1
-- 字符串函数
SELECT CHAR_LENGTH('你好') -- 字符串长度
SELECT CONCAT('我','和','你') -- 拼接字符串
SELECT INSERT('我爱编程',2,1,'no') -- 查询,从某个位置开始替换某个长度为成要替换的字符串,例子就是从2这个位置开始,将长度为1的字符串“爱”替换成“no”(第一个字符是在1的位置而不是0)
SELECT LOWER('ZMC') -- 小写字母
SELECT UPPER('zmc') -- 大写字母
SELECT INSTR('zmc666','6') -- 返回第一次出现字串的索引
SELECT REPLACE('坚持就能成功','坚持','努力') -- 替换出现的指定的字符串
SELECT SUBSTR('坚持就能成功',4,6) -- 返回指定的字符串
SELECT REVERSE('坚持就能成功') -- 反转
-- 时间和日期函数
SELECT CURRENT_DATE() -- 获取当前日期 年-月-日
SELECT CURDATE() -- 同上
SELECT NOW() -- 年-月-日 时:分:秒
SELECT LOCALTIME() -- 同上 本地时间
SELECT SYSDATE() -- 同上 系统时间
date=2022-04-21
year(date)=2022
month(date)=4
date_format(date, "%Y%m")="202108"
DATE_ADD(date,INTERVAL expr type) --DATE_ADD() 函数向日期添加指定的时间间隔。
-- date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔
SELECT YEAR(NOW())
SELECT MONTH(NOW()) -- 可以此类推
-- 系统
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()
是一种多分支的函数,可以根据条件列表的值返回多个可能的结果表达式中的一个。
可用在任何允许使用表达式的地方,但不能单独作为一个语句执行。
分为:
简单CASE函数
搜索CASE函数
CASE 测试表达式
WHEN 简单表达式1 THEN 结果表达式1
WHEN 简单表达式2 THEN 结果表达式2 …
WHEN 简单表达式n THEN 结果表达式n
[ ELSE 结果表达式n+1 ]
END计算测试表达式,按从上到下的书写顺序将测试表达式的值与每个WHEN子句的简单表达式进行比较。
如果某个简单表达式的值与测试表达式的值相等,则返回第一个与之匹配的WHEN子句所对应的结果表达式的值。
如果所有简单表达式的值与测试表达式的值都不相等,
若指定了ELSE子句,则返回ELSE子句中指定的结果表达式的值;
若没有指定ELSE子句,则返回NULL。
例48. 查询班级表中的学生的班号、班名、系号和班主任号,并对系号作如下处理:
当系号为1时,显示 “计算机系”;
当系号为2时,显示 “软件工程系”;
当系号为3时,显示 “物联网系”。
SELECT 班号 ,班名,
CASE 系号
WHEN 1 THEN '软件工程系'
WHEN 2 THEN '计算机系'
WHEN 3 THEN '物联网系'
END AS 系号,班主任号
FROM 班级表
CASE
WHEN 布尔表达式1 THEN 结果表达式1
WHEN 布尔表达式2 THEN 结果表达式2 …
WHEN 布尔表达式n THEN 结果表达式n
[ ELSE 结果表达式n+1 ]
END
按从上到下的书写顺序计算每个WHEN子句的布尔表达式。
返回第一个取值为TRUE的布尔表达式所对应的结果表达式的值。
如果没有取值为TRUE的布尔表达式,
则当指定了ELSE子句时,返回ELSE子句中指定的结果;
如果没有指定ELSE子句,则返回NULL。
例48用搜索CASE来做:
SELECT 班号 ,班名,
CASE
WHEN 系号=1 THEN '软件工程系'
WHEN 系号=2 THEN '计算机系'
WHEN 系号=3 THEN '物联网系'
END AS 系号,班主任号
FROM 班级表
例49.查询“M01F011”号课程的考试情况,列出学号、课程号和成绩,同时将百分制成绩显示为等级。
SELECT 学号,课程号,
CASE
WHEN 成绩 >= 90 THEN '优'
WHEN 成绩 BETWEEN 80 AND 89 THEN '良'
WHEN 成绩 BETWEEN 70 AND 79 THEN '中'
WHEN 成绩 BETWEEN 60 AND 69 THEN '及格'
WHEN 成绩 <60 THEN '不及格'
END 成绩
FROM 成绩表
WHERE 课程号 = 'M01F011'
例50.统计每个班男生和女生的数量各是多少,统计结果的表头为,班号,男生数量,女生数量。
SELECT 班号,
COUNT(CASE WHEN 性别=‘男’ THEN ‘男’ END) 男生数,
COUNT(CASE WHEN 性别=‘女’ THEN ‘女’ END) 女生数
FROM 学生表 GROUP BY 班号
例51.判断成绩的等级,85-100为“优”,70-84为“良”,60-69为“及格”,60以下为“不及格”,并统计每一等级的人数。
SELECT
CASE
WHEN GRADE BETWEEN 85 AND 100 THEN '优'
WHEN GRADE BETWEEN 70 AND 84 THEN '良'
WHEN GRADE BETWEEN 60 AND 69 THEN '及格'
ELSE '不及格'
END 等级, COUNT(*) 人数
FROM SC
GROUP BY
CASE
WHEN GRADE BETWEEN 85 AND 100 THEN '优'
WHEN GRADE BETWEEN 70 AND 84 THEN '良'
WHEN GRADE BETWEEN 60 AND 69 THEN '及格'
ELSE '不及格'
END
substring_index(str,delim,count)
str:要处理的字符串
delim:分隔符
count:计数
例子: str=www. wikibt.com
substring_ index(str,‘.’,1)
结果是: www
substring_ index(str,‘,2)
结果是: www.wikibt
也就是说,如果count是正数,那么就是从左往右数,第N个分隔符的左边的全部内容
相反,如果是负数,那么就是从右边开始数,第N个分隔符右边的所有内容,如:
substring_ index(str,’.’,-2)
结果为: wikibt.com
有人会问,如果我要中间的的wikibt怎么办?
很简单的,两个方向:
从右边第二个分隔符的右边全部,再从左数的第一个分隔符的左边
substring_index(substring_index(str,‘.’,-2),‘.’,1);
IF(expr,v1,v2)
其中:表达式 expr 得到不同的结果,当 expr 为真是返回 v1 的值,否则返回 v2.
函数名称 | 描述 |
---|---|
COUNT() | 计数 |
SUM() | 求和 |
AVG() | 平均值 |
MAX() | 最大值 |
MIN() | 最小值 |
-- 聚合函数
-- 这三个select都能统计表中的数据,区别:
SELECT COUNT(`studentname`) FROM `student` -- Count(指定列),会忽略所有的null值
SELECT COUNT(*) FROM `student` -- Count(*),不会忽略null值
SELECT COUNT(1) FROM `student` -- Count(1),不会忽略null值(这两个相差无几,可以博客看一下效率问题),本质都是计算行数
SELECT SUM(`studentresult`) AS 总和 FROM `result`
SELECT AVG(`studentresult`) AS 平均分 FROM `result`
SELECT MAX(`studentresult`) AS 最高分 FROM `result`
MD5不可逆
MD5破解网站的原理,背后存在一个字典
-- 加密
UPDATE `test` SET pwd=MD5(pwd) -- 加密全部的密码
-- 插入的时候加密
INSERT INTO `test` VALUES (1,'zhangsan',MD5('123456'))
-- 如何校验:将用户传递进来的密码,进行md5加密,然后比对加密后的值
事务原则:ACID原则 原子性,一致性,隔离性,持久性
要么都成功,要么都失败
事务前后的的数据完整性要保持一致
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干涉,事务之间需要隔离
事务一旦提交则不可逆,被持久化到数据库中
隔离所导致的一些问题
指一个事务读取了另一个事务未提交的数据
在一个事务内读取表中的某一行数据,多次读取结果不同
指在一个事务内读取了别的事务插入的数据,导致前后读取不一致
执行事务
-- mysql 是默认开启事务自动提交的
set autocommit = 0 -- 关闭事务的自动提交
set autocommit = 1 -- 开启事务的自动提交
-- 手动处理事务
SET autocommit = 0
-- 事务开启
start transaction -- 标记一个事务的开始,从这个之后的 sql 都在同一个事务内
-- 提交:持久化
commit -- 一旦提交事务,就被持久化了
-- 回滚:回到原来的样子
rollback
-- 事务结束
SET autocommit = 1
-- 拓展
savepoint 保存点名 -- 设置一个事务的保存点
rollback to savepoint 保存点名 -- 回滚到保存点
release savepoint 保存点名 -- 撤销保存点
-- 索引的使用
-- 1、在创建表的时候给字段增加索引
-- 2、创建完毕后,增加索引
-- 显示所有的索引信息
SHOW INDEX FROM `student`
-- 增加一个索引
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)
-- EXPLAIN 分析sql执行的状况
EXPLAIN SELECT * FROM `student`
CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT'' COMMENT'用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT'用户邮箱',
`phone` VARCHAR(20) DEFAULT'' COMMENT'手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0'COMMENT '性别(0:男;1:女)',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT'0' COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT = 'app用户表'
-- 插入100万条数据
DELIMITER $$ -- 写函数之前必须要写,标记
CREATE FUNCTION mock_data()
RETURNS INT -- 返回一个int类型
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i<num DO
INSERT INTO `app_user`(`name`,`email`,`phone`,`gender`,`password`,`age`)
VALUES(CONCAT('用户',i),'[email protected]'
,CONCAT('18',FLOOR(RAND()*((999999999-100000000)+100000000)))
,FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100)
);
SET i =i +1;
END WHILE;
RETURN i;
END;
SELECT mock_data();
SELECT * FROM `app_user` WHERE `name` = '用户9999'; -- 0.018 sec
SELECT * FROM `app_user` WHERE `name` = '用户9999'; -- 0.048 sec
SELECT * FROM `app_user` WHERE `name` = '用户9999'; -- 0.053 sec
EXPLAIN SELECT * FROM `app_user` WHERE `name` = '用户9999';
-- id_表名_字段名
-- CREATE INDEX 索引名 on 表(字段)
CREATE INDEX id_app_user_name ON `app_user`(`name`); -- INDEX是常规索引
SELECT * FROM `app_user` WHERE `name` = '用户9999'; -- 0.009 sec
SELECT * FROM `app_user` WHERE `name` = '用户9999'; -- 0.002 sec
EXPLAIN SELECT * FROM `app_user` WHERE `name` = '用户9999';
索引在小数据量的时候,用户不大,但是在大数据的时候,区别十分明显
##7.3索引原则
索引的数据结构
Btree:InnoDB的默认数据结构
https://blog.csdn.net/zhizhengguan/article/details/109193886
SQLyog可视化管理
SQL命令操作
系统用户表:mysql.user
-- 创建用户 create user 用户名 identified by 密码
CREATE USER zmc IDENTIFIED BY '123456'
-- 修改密码 (修改当前用户密码)
SET PASSWORD = PASSWORD('111111')
-- 修改密码 (修改指定用户密码)
SET PASSWORD FOR zmc = PASSWORD('111111')
-- 重命名
RENAME USER zmc TO zmc2
-- 用户授权 *.*(所有的表)
-- ALL PROVILEGES 除了给别人授权(GRANT),其他都能干
GRANT ALL PRIVILEGES ON *.* TO zmc2
-- 查询权限
SHOW GRANTS FOR zmc2 -- 查看指定用户的全部权限
SHOW GRANTS FOR root@localhost
-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM zmc2
-- 删除用户
DROP USER zmc
备份的方式:
--musqldummp -h表名 -u用户名 -p密码 数据库 数据库表1 数据库表2.... >导入位置
--导出
mysqldump -hlocalhost -uroot -pehero000921 school sudent >D:/a.sql
--导入
--登录的情况下,切换到指定的数据库
--导入,登录的情况下
source D:/文件.sql
--没有登录的情况
mysql -u用户 -p密码 数据库名字<备份文件
暂时不想听
暂时不想听
Java操作数据库的规范,俗称JDBC
CREATE DATABASE `jdbcstudy`;
CREATE TABLE users
(
`id` INT (4) PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
`birthday` DATE
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `users` (`id`,`name`,`password`,`birthday`)
VALUES ('1','张三','123456','1999-02-02'),('2','李四','1234556','1999-08-02'),('3','王五','1288556','1998-02-15')
,('4','赵六','752156','1999-12-12')
创建一个lib文件夹,将数据库驱动的jar包复制进去,然后右击文件夹,选择 Add as Library
package MySQL_Study.JDBC;
import java.sql.*;
public class JdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver"); // 固定写法,加载驱动
//2.连接用户信息和url
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
String username ="root";
String password="123456";
//3.连接成功,数据库对象 connection代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//4.执行sql的对象 statement
Statement statement = connection.createStatement();
//5.执行sql的对象去执行sql
String sql="select * from users";
ResultSet resultSet = statement.executeQuery(sql);//返回的结果集
while(resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.print("name="+resultSet.getObject("name"));
System.out.print("password="+resultSet.getObject("password"));
System.out.println("birthday="+resultSet.getObject("birthday"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
DriverManager
对数据库的操作都可以在这里写
connection.rollback();
connection.commit();
connection.setAutoCommit();
Statement/PreparedStatement
编写sql
statement.executeQuery();//查询
statement.execute();//执行任何SQL
statement.executeUpdate();//更新,插入,删除
ResultSet 查询的结果集:封装了所有的查询结果
获得指定的数据类型
resultset.getint();
resultset.getobject(); 在不知道列类型的情况下使用
resultset.getDate();
指针
resultset.beforFirst();//移动到第一个
resultset.afterLast();//移动到最后一个
resultset.next();//移动到下一个数据
resultset.previous();//移动到前一个数据
resultset.absolute(row)//移动到指定行
##10.4statement对象
配置类
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
工具类
package MySQL_Study.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
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.class.getClassLoader().getResourceAsStream("MySQL_Study/source/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 st,ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
操作类
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args) {
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
conn= JdbcUtils.getConnection(); //获取数据库连接
st=conn.createStatement();
String sql="INSERT INTO `users`(`id`,`name`,`password`,`birthday`) VALUES (5,'ZMC','123456','2022-01-01') ";
int i = st.executeUpdate(sql);
if(i>0){
System.out.println("插入成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
sql存在漏洞,会导致被拼接
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.*;
public class SQL注入 {
public static void main(String[] args) {
login("'or '1=1","'or '1=1");//SQL被拼接
}
public static void login(String username,String password){
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
conn= JdbcUtils.getConnection(); //获取数据库连接
st=conn.createStatement();
//select * from users where `NAME` =''or '1=1' AND `PASSWORD`='123456'
String sql="select * from users where `NAME` ='"+username+"' AND `PASSWORD`='"+password+"'";
rs = st.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("PASSWORD"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
这样会查出所有的数据
PreparedStatement可以放止SQL注入,效率更高
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
public class PreparedInsert {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
try {
conn = JdbcUtils.getConnection();
//区别
//使用 ? 占位符代替参数
String sql="INSERT INTO `users`(`id`,`name`,`password`,`birthday`) VALUES (?,?,?,?) ";
st=conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行
//手动给参数赋值
st.setInt(1,6);
st.setString(2,"aotuman");
st.setString(3,"123321");
// sql.Date 数据库 java.sql.Date()
// util.Date Java new Date().getTime()
st.setDate(4,new java.sql.Date(new Date().getTime()));
//执行
int i = st.executeUpdate();
if(i>0){
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(conn,st,null);
}
}
}
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedDelete {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
try {
conn = JdbcUtils.getConnection();
//区别
//使用 ? 占位符代替参数
String sql="delete from users where id=?";
st=conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行
//手动给参数赋值
st.setInt(1,1);
//执行
int i = st.executeUpdate();
if(i>0){
System.out.println("删除成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(conn,st,null);
}
}
}
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedUpdate {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
try {
conn = JdbcUtils.getConnection();
//区别
//使用 ? 占位符代替参数
String sql="update users set `name`=? where id=?";
st=conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行
//手动给参数赋值
st.setString(1,"zmc");
st.setInt(2,1);
//执行
int i = st.executeUpdate();
if(i>0){
System.out.println("更新成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(conn,st,null);
}
}
}
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PreparedSelect {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn = JdbcUtils.getConnection();
String sql="select * from users where id=?";
st=conn.prepareStatement(sql);
st.setInt(1,2);
//执行
rs=st.executeQuery();
if(rs.next()){
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
}
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestTransaction {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn= JdbcUtils.getConnection();
//关闭数据库的自动提交,自动会开启事务
conn.setAutoCommit(false);
String sql="update account set money = money-100 where name='A'";
st=conn.prepareStatement(sql);
st.executeUpdate();
// int x=1/0; //故意产生异常
String sql2="update account set money = money+100 where name='B'";
st=conn.prepareStatement(sql2);
st.executeUpdate();
//业务完毕,提交事务
conn.commit();
System.out.println("成功!");
} catch (SQLException e) {
//如果失败,自动回滚
// try {
// conn.rollback();
// } catch (SQLException ex) {
// ex.printStackTrace();
// }
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
}
数据库连接----执行完毕—释放
连接–释放 十分浪费资源
池化技术:准备一些预先的资源,过来就连接预先准备好的
编写连接池,实现一个接口 DataSource
开源数据源实现(拿来即用)
DBCP
C3P0
Druid:阿里巴巴
需要用到的jar包
commons-dbcp2-2.9.0
commons-logging-1.2
commons-pool2-2.11.1
配置类
#连接设置,这里面的名字是DBCP数据源中定义好的
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
#
initialSize=10
#最大连接数量
maxActive=50
#最大空闲连接
maxIdle=20
#最小空闲连接
minIdle=5
#超时等待时间以毫秒为单位/s
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:“user” 与 “password” 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8
#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true
#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
工具类
package MySQL_Study.utils;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils_DBCP {
private static DataSource dataSource = null;
static {
try{
InputStream inputStream = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("MySQL_Study/source/dbcpconfig.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, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
调用类
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils_DBCP;
import java.sql.*;
public class TestDBCP {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
try {
conn = JdbcUtils_DBCP.getConnection();
//区别
//使用 ? 占位符代替参数
String sql="INSERT INTO `users`(`id`,`name`,`password`,`birthday`) VALUES (?,?,?,?) ";
st=conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行
//手动给参数赋值
st.setInt(1,10);
st.setString(2,"aotuman");
st.setString(3,"123321");
// sql.Date 数据库 java.sql.Date()
// util.Date Java new Date().getTime()
st.setDate(4,new java.sql.Date(new java.util.Date().getTime()));
//执行
int i = st.executeUpdate();
if(i>0){
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils_DBCP.release(conn,st,null);
}
}
}
配置类
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=falseproperty>
<property name="user">rootproperty>
<property name="password">123456property>
<property name="acquireIncrement">3property>
<property name="initialPoolSize">10property>
<property name="maxIdleTime">30property>
<property name="maxPoolSize">100property>
<property name="minPoolSize">15property>
default-config>
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jbdcstudy?useUnicode=true&characterEncoding=utf8&useSSL=falseproperty>
<property name="user">rootproperty>
<property name="root">123456property>
<property name="acquireIncrement">3property>
<property name="initialPoolSize">10property>
<property name="maxIdleTime">30property>
<property name="maxPoolSize">100property>
<property name="minPoolSize">10property>
named-config>
c3p0-config>
工具类
package MySQL_Study.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcUtils_C3P0 {
private static ComboPooledDataSource dataSource = null;
static {
try{
// new ComboPooledDataSource();
// dataSource.setDriverClass();
// dataSource.setUser();
// dataSource.setPassword();
// dataSource.setJdbcUrl();
//
// dataSource.setMaxPoolSize();
// dataSource.setMinPoolSize();
//创建数据源
dataSource = new ComboPooledDataSource(); //配置文件写法
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();//从数据源中获取连接
}
//释放连接资源
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
调用类
package MySQL_Study.JDBC;
import MySQL_Study.utils.JdbcUtils_C3P0;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestC3P0 {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
try {
conn = JdbcUtils_C3P0.getConnection();
//区别
//使用 ? 占位符代替参数
String sql="INSERT INTO `users`(`id`,`name`,`password`,`birthday`) VALUES (?,?,?,?) ";
st=conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行
//手动给参数赋值
st.setInt(1,7);
st.setString(2,"aotuman");
st.setString(3,"123321");
// sql.Date 数据库 java.sql.Date()
// util.Date Java new Date().getTime()
st.setDate(4,new java.sql.Date(new java.util.Date().getTime()));
//执行
int i = st.executeUpdate();
if(i>0){
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils_C3P0.release(conn,st,null);
}
}
}
总结
无论使用什么数据源,本质是不变的,DateSource接口不会变,方法就不会变