1一1

Mysql笔记

1.navicat

右键创建数据库

image-20210927114738060

命令行连接


mysql -u root -pabc123      -- 连接数据库  u是user用户 p是passoword密码
show databases;   -- 查询数据库 分号结尾
use school  -- 切换数据库 use 数据库名
show tables;  -- 看表
describe student; -- 显示数据库中的所有表的信息
cerate database westos; -- 创建一个数据库 

-- 反向找命令
show create databases school -- 查看创建数据库的语句
show create table aaa		--查看aaa数据表的定义语句
desc student    -- 显示表结构

**数据库xxx语言 ** CRUD 增删改查

DDL 定义

DML 操作(管理) 增删改

DQL 查询

DCL 控制

2.操作数据库 crud增删改查

操作数据库>操作数据库中的表> 操作数据库表中的数据

如果表明或字段名得加上tab上面的那个键`

== mysql关键字不区分大小写 ==

1.创建数据库

create database xxx; create database 【if not exists】xxx; z中括号中的为可选

2.删除数据库

drop database xxx; drop database 【if exists】 xxx;

3.使用数据库

use xxx;

4.查看数据库

show databases; -- 查看所有的数据库

2.2 数据库的列类型

数值

tinyint  十分小的数据 		一个字节
smallint   较小的数据  		两个字节
mediumint  中等大小的数据 	 三个字节
int   	  标准的整数  		四个字节     常用
big 		较大的数据		八个字节
float		浮点数			  四个字节
double		浮点数			  八个字节
decimal 	字符串形式的浮点数	金融计算的

字符串

char		字符串      0-255
varchar		可变字符串	0-65535		常用String
tinytext	微型文本	2^8-1
text		文本串 大型  2^16-1		大文本

时间日期

data yyyy-mm-dd 日期
time  hh:mm:ss 时间格式
datetime yyyy-mm-dd hh:mm:ss 	最常用
timestamp  时间戳 1970.1.1到现在的毫秒数		常用
year 	年份

null


2.3 数据库的字段列表

勾选 not null 就是不能有空 如果有空 就会报错

不勾 默认就是null

无符号就是不能为负

image-20210927160704221

image-20210927164227473

CREATE TABLE IF NOT EXISTS `student1`(
	`id` INT(4) NOT NULL AUTO_INCREMENT  COMMENT'学号',
	`name` VARCHAR(10) NOT NULL DEFAULT'未知' COMMENT'名字',
	`pwd` VARCHAR(10) NOT NULL DEFAULT'123456' COMMENT'密码',
	`sex` VARCHAR(1) NOT NULL DEFAULT'男' COMMENT'性别',
	`birthday` DATETIME  DEFAULT NULL COMMENT'生日',
	`address` VARCHAR(50)  DEFAULT NULL COMMENT'家庭住址',
	`email` VARCHAR(20) DEFAULT NULL COMMENT'邮箱',
	PRIMARY KEY(`id`) 
)ENGINE=INNODB charset=utf8; -- charset是设置字段为utf8  engine引擎为innodb

2.4 engine=INNODB and MYISAM

image-20210928152309993

2.5 修改删除表 alter

修改   alter	modify也是修改
alter  table teacher rename as teacher1    修改表名

alter table teacher1  add  age int(11)    添加列属性

修改表的字段(重命名,修改约束)

alter  table teacher1 modify age varchar(11)		修改约束

alter  table teacher  change  age  age1 int(11)    重命名			
删除

alter table teacher1 drop age1 删除字段

drop table if exists aaa 删除表( 如果表存在就删除 )

注意点

  1. `` 字段名,用这个是为了防止重名关键字

  2. 注释 -- /* */

    3.sql关键字大小写不敏感

    1. 符号用英文

3.MySQL数据管理

3.1 外键(了解)

constraint 约束 foreign 外面 reference索引参考

image-20210928161753488

alter table 表明 add constraint 约束名(FK_**) foreign key(作为外键的列名) reference 哪个表 (哪个列)

3.2 DML语言 操作语言 记住

数据操作语言

数据库意义:数据存储 数据管理

insert

updata

delete

3.3 添加 insert

INSERT INTO student2(`grade`,`pwd`,`sex`) VALUES('毕业生','woshinidie','女')
INSERT INTO `student2`(`name`,`pwd`,address)	VALUES('die','abc','四合院'),('er','efg','小四合院')

--  创建表 添加东西
CREATE TABLE `testdmd5`(
	`id` INT(5) not null  auto_increment,
	`name` VARCHAR(20) not null,
	`pwd` INT(20) not null,
	PRIMARY KEY (id)
)ENGINE=INNODB CHARSET=utf8

-- 往表里面查数据
INSERT INTO testdmd5 VALUES(1,'zhangsan','123456'),(2,'lisi','123456'),(3,'wangwu','123456')

语法: insert into 表明(列名,列,) values('对应','对应')

注意事项:

​ 1.`和''要分清楚

​ 2.表明后面的列名可以省略,但是后面的值必须跟表一一对应

​ 3.可以同时插入多条数据,value后面加逗号隔开

3.4 修改 update

update(谁)set 原来值=新值 where 条件=什么

UPDATE `student2` set pwd='hello',email='10750' where `id`=11   /*一定要加where 不然修改的就是所有密码为hello */


条件: where的子句 运算符 除了等于 还有大于,在某个区间

image-20210929165417330

-- --多个条件判断  筛选 无上限
UPDATE `student2` set pwd='six' where `pwd`='woshinidie' AND `grade`='毕业生'   

UPDATE `student2` set pwd='six',`name`='lol' where `pwd`='woshinidie' AND `grade`='毕业生'    -- 可以改多个

注意: 记得加上where,没有指定会修改所有的值

​ set不单单是定量 还可以是函数、变量 current_time 是当前时间 current 普遍的 流行的


UPDATE `student2` set `address`=CURRENT_TIME where `pwd`='woshinidie' AND `grade`='小学生'

3.5 删除 delete drop truncate

DELETE FROM `student2`  -- 避免这样写
DELETE FROM `student2` WHERE id='11'  -- 删除指定数据

语法: delete frome 表明 where 条件

truncate 截平

作用: 完全清空一个数据库表,标的结构和索引约束不会变

TRUNCATE student -- 潇洒离去

delete 和 truncate 的区别

​ 1.相同点: 都能删除数据 不能删除列名

​ 2.不同: truncate 重新设置自增列 计数器会归零

​ truncate不会影响事务

delete删除不会删除自增的属性 再添加会接着之前的继续添加

truncate会清除

-- 测试delete和truncate
CREATE TABLE `test`(

`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT'ID',

`score` VARCHAR(20) NOT NULL,
PRIMARY KEY(`id`)

)ENGINE=INNODB  CHARSET=utf8



TRUNCATE `test`
DELETE FROM `test`
INSERT INTO `test`(`score`) VALUES('99'),('80')

image-20210929175304368

4.DQL查询数据(重点) 格式

image-20211003153431887

4.1 DQL select 选择,挑选

data query language

4.2 指定字段查询

AS 别名 有的时候表名不容易一眼看懂 就可以AS为显而易见的字

select 需要查的东西 来自哪

select 字段 frome	`表`     -- 查询全部学生 

SELECT `studentno`,`sex` FROM `student`  --查询指定字段

-- 别名 就是把列名(表头)改一下   也可以把表改别名 frome `` as *
SELECT `studentno` AS '学号',`sex`AS '性别' FROM `student` 

函数 concat(a,b)   把字符拼接起来
SELECT CONCAT('新名字: ',subjectname) AS '新名字' FROM subject


4.3 where逻辑运算符使用

去除重复的 distinct

SELECT DISTINCT `studentno` FROM `result`  

AND 或 && 返回true或false 都为真
or 或 || 一方为真则为真
!= NOT 取反
-- 与
SELECT `studentresult` FROM `result` WHERE `studentresult`>=90 AND `studentresult`<=100
-- 还有一个between ... and ...  属于是左右都闭合 【90,100】
SELECT `studentresult` FROM `result` WHERE `studentresult` BETWEEN 90 and 100 
 
-- 注意not的用法位置   非
SELECT `studentno` FROM `student` WHERE `studentno`!= 1000
SELECT `studentno` FROM `student` WHERE  NOT `studentno` =1000


-- 或
SELECT studentno from student where studentno=1000 or studentno = 1001

还可以给成绩之后加一 直接加就可以

SELECT `studentresult`+1 AS '提分后'FROM `result` WHERE `studentresult`>=90 AND `studentresult`<=100

-- 可以直接计算结果
select 100-5*8

-- 可以查看sql版本
select version

-- 还可以查看自增的步频    auto自动的 increment 增加
select @@auto_increment_increment

模糊查询: 其实就是比较运算符

image-20210930161745397

like

-- 名字后多个字符的  姓赵的同学
SELECT `studentno`,`studentname` FROM `student` WHERE `studentname` like '赵%'
-- 名字后只有一个字符的同学
SELECT `studentno`,`studentname` FROM `student` WHERE `studentname` like '赵_'
-- 名字中含有某个字的  %申%   前后面任意一个字符
SELECT `studentno`,`studentname` FROM `student` WHERE `studentname` like ' %申% '

in

-- in  在某个区间
SELECT studentno FROM student WHERE studentno IN(1000,1001,1002)
-- 查这种地址得精确
SELECT address FROM student WHERE address in('北京朝阳')

is null is not null

-- 为空
SELECT address FROM student WHERE address='' or address is null
-- 不为空
SELECT address FROM student WHERE address is not null

4.4 联表查询 难点

leftjoin 左表 YI以左表为基准 主要的数据看左表的 左表有右表没有的也会显示 而右表有左表没有的则不会显示

inner join 交集 中间的 共有的 什么等于什么

right join 右表

思路: 假设多张表查询,先两张表相互关联,然后再多个查询

-- join 连接的表 on 关联(判断的条件)   (连接查询)
-- where 等值查询

-- 学号 学生姓名 科目名 分数  打印参加了考试的学生
SELECT r.studentno, studentname,subjectname,studentresult
from result AS r left join student AS s 
ON r.studentno = s.studentno 
INNER JOIN `subject` AS sub 
ON r.subjectno = sub.subjectno

-- 学号 学生姓名 科目名 分数  打印参加了考试的学生  打印参加了数据结构1的学生

SELECT s.studentno,s.studentname,subjectname,studentresult
FROM result AS r
RIGHT JOIN student  AS s
ON r.studentno=s.studentno
INNER JOIN `subject` AS sub
ON r.subjectno=sub.subjectno
WHERE subjectname='C语言-1'

自连接

自己的表和自己的表链接:一张表拆为两张一样的表即可

级别1对应的最左边等级 然后剩下的级别对应的对应级别一对应的东西

SELECT a.categoryname AS '父类',b.categoryname  AS '子类'
FROM category AS a,category AS b
WHERE a.categoryid=b.pid

image-20210930205637979

image-20210930205646599

4.5 分页 limit 和 排序 order by 子查询

排序: 升序 ASC 降序 DESC

-- 降序排
SELECT studentresult,subjectno FROM result 
ORDER BY studentresult DESC -- 通过什么排序 升序降序
limit 0,5  -- 从第0个开始 一页五个  第二页就是  limit 5,5 
--  反正就是 *(n-1)   总页数就是总数除以5

image-20211001190512396

语法位置有限制

image-20211001190629544

子查询

-- 查询数据库结构-1 的所有考试结果 学号 科目编号 成绩 降序排列1
SELECT studentno , subjectno ,studentresult
FROM  result
WHERE subjectno = (SELECT subjectno from `subject` WHERE  subjectname = '数据库结构-1')
-- 分数不小于80的学生学号和姓名 并且科目为高等数学-1   
-- 嵌套查询
SELECT  studentname,r.studentno,studentresult
FROM student AS s
INNER JOIN result AS r
ON s.studentno=r.studentno
WHERE studentresult >=80 AND 	`subjectno`=(
	SELECT subjectno FROM `subject` WHERE subjectname='高等数学-1'
)
-- 连表查询
SELECT  studentname,s.studentno,studentresult
FROM student AS s
INNER JOIN result as r
ON s.studentno=r.studentno
INNER JOIN `subject` as sub
ON sub.subjectno=r.subjectno
WHERE studentresult >=80 AND subjectname='高等数学-1'

-- J简化
-- 分数不小于80的学生学号和姓名 并且科目为高等数学-1   
SELECT studentname,studentno FROM student WHERE studentno IN(
		SELECT studentno FROM result WHERE studentresult>=80 AND subjectno=(
				SELECT `subjectno` from `subject` WHERE subjectname='高等数学-1'
		)
) 


4.6 分组和过滤

-- 查询不同课程的平均分 最高分 最低分 大于80的平均分
SELECT  subjectname,avg(studentresult),max(studentresult),min(studentresult)
FROM result as r
INNER JOIN 	`subject` as sub
ON r.subjectno = sub.subjectno
GROUP BY subjectname			-- 分组比较
HAVING AVG(studentresult)>80   -- 分组之后的条件  不用where是因为where只能在分组之前 而要筛选大于80的平均分 必须要先分组之后 才能筛选 所以用having  having可以有多条 where只能有一条

5.MySQL函数

5.1 常用函数

-- 数值函数
select abs(-2)  -- 绝对值
select ceiling(9.4) -- 向上取整  10
select floor(9.4)  -- 向下取整9 
select rand()   -- 随机数0~1
select sign(-10)  -- 判断一个数的正负  -1是负数 0是0 1是正数
 
-- 字符串函数
select char_length('不好玩')   -- 字符串长度  3
select concat('我','爱','sql')  -- 拼接
select insert('',1,2,'') -- 从第一个字符开始,替换两个长度,
select lower()      -- 全部转换小写
select upper()    -- 全部转换大写 
select replace('我是你爹','你''大家的')   -- 替换字符串
select substring('asdwad',2,6) -- 返回第二个开始,截取六个字符串
select reverse()  -- 反转

-- 日期和时间函数
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())


-- 系统 
select system_user()  -- 获取当前登录用户
select user()   -- 跟上面一样
select version()  

image-20211003140209885

5.2 聚合函数

image-20211003145738160

SELECT count(1) FROM student     -- 不会忽略null    1是把所有值变成1然后去查   本质 计算行数
SELECT count(*) FROM student 		-- 不会忽略null值
# count *  和 count 1 的区别就是   *会把所有的值走一遍  1只走一列

	
SELECT count(studentname) FROM student    -- 会忽略所有的null值

SELECT sum(studentresult) as '总和' FROM result
SELECT avg(studentresult) as '平均分' FROM result
SELECT max(studentresult) as '最高分' FROM result
SELECT min(studentresult) as '最低分' FROM result
-- 查询不同课程的平均分 最高分 最低分 大于80的平均分
SELECT  subjectname,avg(studentresult),max(studentresult),min(studentresult)
FROM result as r
INNER JOIN 	`subject` as sub
ON r.subjectno = sub.subjectno
GROUP BY subjectname			-- 分组比较
HAVING AVG(studentresult)>80   -- 分组之后的条件  不用where是因为where只能在分组之前 而要筛选大于80的平均分 必须要先分组之后 才能筛选 所以用having  having可以有多条 where只能有一条

5.3 MD5加密 扩展

CREATE TABLE `testdmd5`(
	`id` INT(5) not null  auto_increment,
	`name` VARCHAR(20) not null,
	`pwd` INT(20) not null,
	PRIMARY KEY (id)
)ENGINE=INNODB CHARSET=utf8

-- 往表里面查数据
INSERT INTO testdmd5 VALUES(1,'zhangsan','123456'),(2,'lisi','123456'),(3,'wangwu','123456')
-- 上面设置的是int类型 密码不一定为纯数字  所以更细腻下==一下约束
ALTER TABLE testdmd5 MODIFY	 pwd VARCHAR(50)
-- 把密码加密 md5
UPDATE testdmd5 SET pwd = MD5(pwd) WHERE id=1

-- 插入的时候就加密
INSERT INTO testdmd5 VALUES(4,'zhangsan',md5('123456'))
-- 如何校验: 将用户传递进来的md5进行加密 然后比较加密之后的值
SELECT * FROM testdmd5 WHERE name='zhangsan' AND pwd=md5('123456')

6. 事务

6.1什么是事务

**要么都成功 要么都失败 **

将一组SQL放在一个批次中执行

事务原则:ACID原则   原子性,一致性,隔离性,持久性 (脏读,幻读)

原子性: 要么都成功 要么都失败

一致性:事务前后的数据完整性保持一致

隔离性:两个进行转账,为每个提供单独的事务,互不干扰

持久性:事务一旦提交则不可逆,呗持久化到数据库中

隔离所导致的问题:

脏读:一个事务读取了另一个没有提交的事务

不可重复读:在一个事务内读取表中的数据,多次读取结果不同

幻读: 读取之后别人插入了一行

6.2 事务的提交代码


-- mysql 是默认开启事务自动提交的
set autocommit = 0 /*关闭*/
SET autocommit = 1   /* 开启 (默认的)*/
-- 手动处理事务				就关闭自动提交
set autocommit = 0     

-- 事务开启  事务:transaction

START TRANSACTION    -- 标记一个事务开始,从这个之后的sql都在一个事务内

insert xxx
-- 提交   持久化
COMMIT
-- 回滚			回到原来样子(失败)
ROLLBACK
-- 事务结束		开启自动提交
set COMMIT = 1

SAVEPOINT 保存点   -- 设置一个事务的保存点  了解即可
ROLLBACK TO SAVEPOINT  保存点 		-- 回滚到保存点 就是游戏的进度条
RELEASE SAVEPOINT 保存点  -- 删除保存点 release

6.3 转账模拟场景


CREATE DATABASE shop
use shop
CREATE TABLE `account`(
	`id` int(10) not NULL auto_increment,
	`name`  VARCHAR(20) NOT NULL,
	`money` DECIMAL(9,2) not null,
	PRIMARY key (`id`)
)ENGINE = INNODB ,DEFAULT CHARSET=utf8

INSERT INTO account(`name`,`money`) VALUES('a',2000),('b',10000)


-- 开始转账
set autocommit = 0;  -- 关闭自动提交
START TRANSACTION;  -- 开启一个事务

UPDATE account SET money=money-500 WHERE `name`='b';
UPDATE account SET money=money+500 WHERE `name`='a';

COMMIT;   -- 提交  		不提交钱是不会少的 但是提交了之后 不可逆 持久性原则
ROLLBACK;  -- 回滚		

SET autocommit = 1 ;  -- 设置自动提交

7. 索引

索引是帮助更快的获取MySQL的数据结果

7.1 索引分类

在一个表中,主键索引只能有一个,唯一索引可以有多个
就设置主键直接写主键名 primary key(`sa`)
 其他索引需要具体 比如 fulltext index sa(`sa`)

主键索引 primary key

​ 唯一标识 主键内容(1,1)不可重复 只能有一个列作为主键

唯一索引 unique key unique 唯一的,独一无二的 优尼科

​ 内容也不能重复(待定)避免重复的列出现,唯一索引可以重复(多个列都可以表示为唯一索引)

常规索引 key/index

​ 默认的 default 用index或key来设置

全文索引 fulltext

​ 在特定的数据库引擎下才有,myisam

​ 快速定位

-- 显示索引信息
show index from student
-- 增加一个全文索引
ALTER table school.student add FULLTEXT INDEX studentname(studentname)
-- 增加一个全文索引
ALTER table school.student add FULLTEXT INDEX studentname(studentname)
SHOW index FROM school.student

-- 分析SQL执行的状况    这是普通索引 非全文索引  EXPLAIN是分析执行状况
EXPLAIN SELECT  * FROM school.student
-- 全文索引不一样

添加索引
CREATE INDEX id_app_user_name ON app_user(`name`)  -- 这个ID应该是index的简称  id_表明_列名 ON 表明(列名)

索引在大数据时候,区别十分明显

7.2 索引原则

1.索引不是越多越好

2.不要对经常变动的数据加索引

3.小数据量的表不需要加索引

4.索引一般加在常用查询的字段上

8.权限管理和备份

8.1 用户管理

默认的用户在 mysql/user表里面  创建用户就是在这里创建
本质 :  对表进行增删改查
重命名
rename user fine to fine2

identified 识别

grant all privileges 授予权限

image-20211004201411298

8.2 mysql 备份

保证重要的数据不丢失

数据转移

备份方式: 直接拷贝data文件

​ 在sqlyog可视化工具中导出

​ 使用命令行导出 mysqldump 就是cmd里面

命令行导出 mysqldump

image-20211005151736142

命令行导入 登录cmd mysql

导入数据库则不需要切换 要是导入表则需要切换到需要导入的表中

然后 source SQL文件地址

image-20211005152255235

9.规范数据库设计

10.jdbc 重点 java database control

-- 测试数据库
CREATE DATABASE `jdbcStudy` CHARACTER SET utf8 COLLATE utf8_general_ci;

USE `jdbcStudy`;

CREATE TABLE `users`(
 `id` INT PRIMARY KEY,
 `NAME` VARCHAR(40),
 `PASSWORD` VARCHAR(40),
 `email` VARCHAR(60),
 birthday DATE
);

 INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)
VALUES('1','zhangsan','123456','zs@sina.com','1980-12-04'),
('2','lisi','123456','lisi@sina.com','1981-12-04'),
('3','wangwu','123456','wangwu@sina.com','1979-12-04')
// java执行的代码
package com.shen.jdbc;

import java.sql.*;

public class firstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 启动程序
        Class.forName("com.mysql.cj.jdbc.Driver");   //固定写法 加载驱动
        //登录 用户信息和url                                   支持中文编码  设置编码格式utf8             使用安全的链接
        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String pwd = "abc123";
        // 连接成功 数据库对象   driverManager驱动管理去获得链接  connection为数据库
        Connection connection = DriverManager.getConnection(url, username, pwd);
        // 执行SQL对象   statement执行SQL的对象
        Statement statement = connection.createStatement();
        // SQL对象去执行sql  execute执行
        String sql = "select * from users";
        ResultSet resultSet = statement.executeQuery(sql);  //返回的结果集
        while (resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("nane="+resultSet.getObject("NAME"));
            System.out.println("pwd="+resultSet.getObject("PASSWORD"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
            System.out.println("====================");
        }
        //  释放连接 也就是关闭
        resultSet.close();
        statement.close();
        connection.close();
    }
}


3306是mysql默认的端口号 
 http:(协议) //    www.baidu.com/数据库名 ? 参数1  & 参数2  & 参数3
jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true"

10.1 statement对象的解释

statement就是执行SQL的对象

image-20211007154122904

// 1. Class.forName(com.mysql.jc.jdbc.Driver)  加载驱动
// 2. 获取连接 conn= DriverManger.getConnection(url,user,pwd)
//3. 获得statement执行SQL对象  sta=conn.createStatement()
// 4.写SQL语句  String sql = "select update";
// 5.执行SQL resultSet= sta.executeQuery(sql)
// 6.  获取内容的话 就得 resultSet.getObject或者String等

三个关键 Connection 连接(连接成功返回的对象其实就是数据库) Statement 执行SQL对象 resultSet 结果集

10.2 SQL注入问题

可以出现漏洞 非法SQL语句盗取数据库的信息 SQL会被拼接 prepareStatement更安全一些

package com.shen.jdbc;

import com.shen.utils.jdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class StolePWD {
    public static void main(String[] args) {
        //login("me","123456");
        login("' or '1=1"," ' or '1=1");
    }
    public static void login(String username,String pwd){
        Connection conn = null;
        Statement sta = null;
        ResultSet res = null;
        try {
            conn = jdbcUtils.getConnection();
            sta = conn.createStatement();
            // sql SELECT * FROM `users` WHERE id='1' AND `PASSWORD` ='123456'
            String sql = "select * from `users` where `NAME` ='"+username+" ' and   `password` = '"+pwd+" ' ";
            res = sta.executeQuery(sql);
            while (res.next()){
                System.out.println(res.getObject("NAME"));
                System.out.println(res.getObject("PASSWORD"));
                System.out.println("==================");
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            jdbcUtils.release(conn,sta,res);
        }
    }
}

10.3 preparedStatement对象

可以防止SQL注入 并且效率更高

package com.shen.demo;
import com.shen.utils.jdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

public class testInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;
        try {
            conn = jdbcUtils.getConnection();
            String sql = "insert into `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`) values (?,?,?,?,?)";
            // 预编译  传入?为参数
            pst =conn.prepareStatement(sql);
            // 插入数据
            pst.setInt(1,4);
            pst.setString(2,"爹爹");
            pst.setString(3,"1233210");
            pst.setString(4,"1075029431@qq.com");
            pst.setDate(5,new java.sql.Date(new Date().getTime()));
            // SQL对象执行SQL
            int i = pst.executeUpdate();
            if(i>0){
                System.out.println("ook");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            jdbcUtils.release(conn,pst,null);
        }
    }
}

先预编译 不用createStatement

直接 连接好了就 st=conn.prepareStatement(sql)

然后传入参数 st.setint(第一位,值) 以此类推

然后 运行 st.excuteUpdate()

prepareStatement 当用户名或者密码传入 转义字符的时候 会自动转义 不能注入 比如说引号 ’

10.4 idea链接数据库

image-20211008172220520

10.5 事务

image-20211008182332719

package com.shen.demo01;
import com.shen.utils.jdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class transactionTest {
    public static void main(String[] args) {
        Connection conn  = null ;
        PreparedStatement pre = null;
        ResultSet re = null ;
        try {
            conn = jdbcUtils.getConnection();  // 连接数据库
            conn.setAutoCommit(false);  // 关闭自动提交
            String sql = "update `account` set money = money -100 where `NAME`='A'";  // 虽然用的prepareStatement  但是没有注入 不用问好
            pre = conn.prepareStatement(sql);  // 预编译
            pre.executeUpdate();  // 执行   不传参

            String sql1 = "update `account` set money = money +100 where `NAME`= 'B'";
            pre = conn.prepareStatement(sql1);
            pre.executeUpdate();

            conn.commit();
            System.out.println("ook");
            
            
             conn.setAutoCommit(true);  // 关闭自动提交

        } catch (SQLException throwables) {
            try {
                conn.rollback(); //其实不写也行 上面执行失败会自动回滚
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }finally {
            jdbcUtils.release(conn,pre,null);
        }
    }
}

dbcp连接池

image-20211008194527224

唯一的使用区别就是把以前的连接改为人家的方法来进行连接 关闭也要改一下

就是提高效率的 就 连接的话 每次执行一个SQL都要连接一下 很麻烦 就像银行

开门--》 服务 --》 关门 再开门

而这个方法就是 开门---》服务 --》下一位 --- 》 下班

posted on 2021-11-01 23:44  1一1  阅读(66)  评论(0编辑  收藏  举报