MySQL 案例实战教程


案例1:MySQL的安装和基本使用


下载mariadb

Windows下安装见此贴

Windows下安装MySQL详细教程 - m1racle - 博客园 (cnblogs.com)

安装需要设置编码为 UTF-8 , 管理用户root,密码设置 root 或 123456

注意:MySQL在Windows不区分大小写,在Linux区分大小写

案例2:MySQL的数据类型


imgMySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

img备注: char 和varchar 一定要指定长度,float 会自动提升为double,timestamp 是时间的混合类型,理论上可以存储 时间格式和时间戳。

imgdate只能存日期(2022-05-09),time只能存时间(11:38:20),datetime就两个都能存(2022-05-09 11:38:20)

imgchar(10) ‘ABC ‘(自动补齐十个空) varchar(10) ‘ABC’

类型 用途
int 整型,相当于java 的int
bigint 整型,相当于java 的 long
float 浮点型
double 浮点型
datetime 日期类型
timestamp 日期类型(可存储时间戳)
char 定长字符
varchar 不定长字符
text 大文本,用于存储很长的字符内容(几万个字符)
blob 字节数据类型,存储图片、音频等文件

案例3:建表操作


img语法

1
2
3
4
5
6
-- 删除表  PS: 两个横线一个空格代表单行注释符,多行就是/* 多行注释 */和c语言一样
DROP TABLE IF EXISTS 表名;
-- 新建表
create table 表名(
字段名 类型 约束(主键,非空,唯一,默认值), 字段名 类型 约束(主键,非空,唯一,默认值),
)编码,存储引擎;

在 SQL 中,我们有如下约束:

image-20220507211326528NOT NULL - 指示某列不能存储 NULL 值。

imgUNIQUE - 保证某列的每行必须有唯一的值。

imgPRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。

imgFOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。

imgCHECK - 保证列中的值符合指定的条件。

imgDEFAULT - 规定没有给列赋值时的默认值。

img实例

1
2
3
4
5
6
7
8
9
10

DROP TABLE IF EXISTS `websites`; CREATE TABLE `websites` (
id int(11) NOT NULL AUTO_INCREMENT,
name char(20) NOT NULL DEFAULT '' COMMENT '站点名称',
url varchar(255) NOT NULL DEFAULT '',
alexa int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名', sal double COMMENT '广告收入',
country char(10) NOT NULL DEFAULT '' COMMENT '国家',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

案例4:插入、删除、更新


img插入语句

1
INSERT INTO websites(name,url,alexa,sal,country ) VALUES ('腾讯', 'https://www.qq.com', 18, 1000,'CN' ) ;

img删除语句

1
delete from websites where id = 5;

img更新语句

1
update websites set sal = null where id = 3

案例5:基本 select 查询语句


img初始化数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
DROP TABLE IF EXISTS `websites`; CREATE TABLE `websites` (
id int(11) NOT NULL AUTO_INCREMENT,
name char(20) NOT NULL DEFAULT '' COMMENT '站点名称',
url varchar(255) NOT NULL DEFAULT '',
alexa int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名', sal double COMMENT '广告收入',
country char(10) NOT NULL DEFAULT '' COMMENT '国家',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `websites` VALUES
(1, 'Google', 'https://www.google.cm/', '1', 2000,'USA'),
(2, '淘宝', 'https://www.taobao.com/', '13',2050, 'CN'),
(3, '菜鸟教程', 'http://www.runoob.com/', '4689',0.0001, 'CN'),
(4, '微博', 'http://weibo.com/', '20',50, 'CN'),
(5, 'Facebook', 'https://www.facebook.com/', '3', 500,'USA');
CREATE TABLE IF NOT EXISTS `access_log` (
`aid` int(11) NOT NULL AUTO_INCREMENT,
`site_id` int(11) NOT NULL DEFAULT '0' COMMENT '网站id',
`count` int(11) NOT NULL DEFAULT '0' COMMENT '访问次数',
`date` date NOT NULL, PRIMARY KEY (`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `access_log` (`aid`, `site_id`, `count`, `date`) VALUES
(1, 1, 45, '2016-05-10'),
(2, 3, 100, '2016-05-13'),
(3, 1, 230, '2016-05-14'),
(4, 2, 10, '2016-05-14'),
(5, 5, 205, '2016-05-14'),
(6, 4, 13, '2016-05-15'),
(7, 3, 220, '2016-05-15'),
(8, 5, 545, '2016-05-16'),
(9, 3, 201, '2016-05-17'),
(10, 88, 9999, '2016-09-09');

img查询语句

1
2
3
4
-- 实际开发中尽量不要使用* 作为查询
select * from websites

select id, name, url, alexa, sal, country from websites (推荐使用的方式)

我们选中右面的字段,进行鼠标左键拖动,可以一键将其拖入代码段中image-20220509193353237

案例6. 分页查询


mysql 的分页是最优雅

1
2
select * from websites limit 2,3 ; --从第2条(下标从0开始)开始查,查3条数据
select * from websites limit 3 ; --从第0条(下标从0开始)开始查,查3条数据

案例7. distinct 关键字


DISTINCT 关键词用于返回唯一的不同的值。

1
select distinct country from websites

案例8. where 语句


作为条件筛选, 运算符: > < >= <= <> != = (!= 和 <>意义相同)

is null is not null (因为在sql 语句中null 和任何东西比较都是假,包括它本身)

like in

1
select * from websites where sal > 500
1
2
3
UPDATE websites set sal = NULL WHERE id = 2;
UPDATE websites set sal = null WHERE id = 3;
SELECT * FROM websites WHERE sal IS not null

image-20220509194340520

案例9. 逻辑条件: and 、or


1
2
3
select * from websites where sal >= 0 and sal <= 2000;   -- 收入在 0 到 2000之间
select * from websites where sal between 0 and 2000; -- 和上面一样的
select * from websites where sal < 5 or sal is null; -- 收入小于 5 或者没有收入

注意: null 的条件判断用 is null 或 is not null

案例10. order by


排序: 默认情况下是升序,asc 可以省略 。

1
2
select * from websites order by sal asc,alexa desc ;
-- 先根据sal 升序排序,再根据 alexa 降序(升序之后,sal相同的情况考虑alexa)

案例11. like 和 通配符

img

通配符是一种特殊语句,主要用来模糊查询。当不知道真正字符或者懒得输入完整名称时,可以使用通配符来代替一个或多个真正的字符。

  • like 模糊查询

  • 通配符

    • % : 0个或多个字符

    • “%” 是 MySQL 中最常用的通配符,它能代表任何长度的字符串,字符串的长度可以为 0。例如,a%b表示以字母 a 开头,以字母 b 结尾的任意长度的字符串。该字符串可以代表 ab、acb、accb、accrb 等字符串。

      • 该实例代表,找到websites表中name项里有o的一项(前后项任意取都行,没有东西也行)image-20220509200351608
    • _ : 1 个字符

    • “_”只能代表单个字符,字符的长度不能为 0。例如,a_b可以代表 acb、adb、aub 等字符串。如果 _o% 就代表了只有找到o前面只有一个字符的,才会返回

      • 这两张图就很好得反应出来了,_的绝对性image-20220509200418972
      • image-20220509200518952

案例12. in

img

img匹配多个条件

1
select * from websites where country in ('USA','鸟国','CN');

img等价于

1
select * from websites where country = 'USA' or country = '鸟国' or country = 'CN'

image-20220509200659146

案例13. 别名


1
2
select tt.name '网站名字' from websites tt -- 最好这样,比较直观
select tt.name 网站名字 from websites tt -- 效果一样

image-20220509201359799image-20220509201514893

案例14. Group by 分组查询


注意:分组时候的筛选用 having

常见的几个组函数: max() min() avg() count() sum()

上面起别名已经使用了

1
select avg(sal) aa from websites where sal is not null group by country having aa > 1200

image-20220509201705260

案例15. 子查询?


把查询的结果当作一个表来使用

案例16. 连接查询 *


1
2
3
4
5
6
7
8
9
10
11
12
13
14
select name,count,date from websites w , access_log a ; 
-- 著名的笛卡尔积,没什么意义的:挨个查,然后胡乱关联

select name,count,date from websites w , access_log a where w.id = a.site_id;
-- 这是 1992 的语法,意思是websites的id等于access_log的site_id时,挑选出name,count,date
-- 但是这样会有一个问题,如果id和site_id无法配对,本来存在的网站由于没有访问记录,无法显示

select name,count,date from websites w inner join access_log a on w.id = a.site_id;
-- 这是 1999 年的语法,推荐使用,是内连接

select name,count,date from websites w left outer join access_log a on w.id = a.site_id;
-- 把没有访问的网站也显示出来,这个是左外连接
-- 注意: inner 和 outer 是可以默认省略的。

img如图:

1
2
3
4
5
6
7
8
select name,count,date from websites w , access_log a where w.id = a.site_id;
-- 属于内连接,不算错
select name,count,date from websites w , access_log a where w.id = a.site_id and sal > 2000;
-- w.id = a.site_id 属于关联条件 sal > 2000 属于筛选条件,但表多了我们无法分得清楚
-- 实际开发中我们通常使用下面这种写法
select * from websites w join access_log a
on w.id = a.site_id -- on后使用关联条件
where sal > 2000 -- where后用筛选条件,使得我们容易区分开

img

效果展示

右外连接:

可以看到的是,右边是access_log,access里面有一个site_id为888,websites没有与他对应的ID,因此本着主要考虑右边,我们显示出888哪一行,并且左边的值全补nullimage-20220509204054648

左外连接:

左外连接也是一样的道理,jjyaoao’home没有与他对应的东西,但照顾左边,显示出来image-20220509204252233

全连接:

仅仅在左连接代码与右连接代码中间加入一个union,就可以同时显示888和jjyaoao’home两行image-20220509204530129

案例17. Null 处理l 函数


1
2
SELECT NAME, COUNT, DATE  FROM websites w LEFT JOIN access_log a
ON w.id = a.site_id

image-20220509204742962

ifnull函数将count的null值替换为了0 每个数据库都会有的image-20220509204941477

经典练习(Oracle的自带练习)


img员工信息表

empno 员工编号, ename 员工名称, job 员工工作, mgr 员工的上司, hiredate 入职时间, sal 底薪, comm 奖金, deptno 部门编号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 员工信息表
CREATE TABLE emp(
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno INT
) ;

INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30); INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30); INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20); INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30); INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30); INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10); INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20); INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10); INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30); INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20); INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10); INSERT INTO emp values(7981,'MILLER','CLERK',7788,'1992-01-23',2600,500,20);

img部门信息表

deptno 部门编号, dname 部门名称, loc 部门位置

1
2
3
4
5
6
7
8
9
10
CREATE TABLE dept(
deptno INT,
dname varchar(14),
loc varchar(13)
);

INSERT INTO dept values(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept values(20, 'RESEARCH', 'DALLAS');
INSERT INTO dept values(30, 'SALES', 'CHICAGO');
INSERT INTO dept values(40, 'OPERATIONS', 'BOSTON');

img基本查询

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 所有员工的信息
-- 薪资大于等于1000并且小于等于2000的员工信息
-- 从员工表中查询出所有的部门编号
-- 查询出名字以A开头的员工的信息
-- 查询出名字第二个字母是L的员工信息
-- 查询出没有奖金的员工信息
-- 所有员工的平均工资
-- 所有员工的工资总和
-- 所有员工的数量
-- 最高工资
-- 最少工资
-- 最高工资的员工信息
-- 最低工资的员工信息

img分组查询

1
-- 每个部门的平均工资

img子查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 单行子查询(> < >= <= = <>)
-- 查询出高于10号部门的平均工资的员工信息
-- 多行子查询(in not in any all) >any >all
-- 查询出比10号部门任何员工薪资高的员工信息
-- 多列子查询(实际使用较少) in
-- 和10号部门同名同工作的员工信息
-- Select接子查询
-- 获取员工的名字和部门的名字
-- from后面接子查询
-- 查询emp表中经理信息
-- where 接子查询
-- 薪资高于10号部门平均工资的所有员工信息
-- having后面接子查询
-- 有哪些部门的平均工资高于30号部门的平均工资

-- 工资>JONES工资
-- 查询与SCOTT同一个部门的员工
-- 工资高于30号部门所有人的员工信息
-- 查询工作和工资与MARTIN完全相同的员工信息
-- 有两个以上直接下属的员工信息
-- 查询员工编号为7788的员工名称,员工工资,部门名称,部门地址

imgSQL查询的综合案例

  1. 查询出高于本部门平均工资的员工信息

  2. 列出达拉斯加工作的人中,比纽约平均工资高的人

  3. 查询7369员工编号,姓名,经理编号和经理姓名

  4. 查询出各个部门薪水最高的员工所有信息

MySQL更多补充

COMMIT:提交事务

查看事务状态:select @@autocommit; show variables like ‘%autocommit%’;
1或者ON表示自动提交;0或者OFF表示手动提交:需要commit命令提交事务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.06 sec)
123456789101112131415

设置手动提交:set autocommit=0; set autocommit=OFF;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> set autocommit=0;
Query OK, 0 rows affected (0.02 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
mysql> set autocommit=OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.02 sec)
1234567891011121314151617181920

下面实际演示一下:
首先新开session1并建表create table test_a(id1 int,id2 int);

然后设置手动提交set autocommit=0;(这样设置只对当前session有效,是临时的,如果想要永久全局设置,修改my.cnf文件,添加autocommit=0);

再向表中插入数据insert into test_a values(1,1);

此时新开第二个session2,查询该表select * from test_a;可以发现,此时在session2上是查询不到数据的,原因就是因为在session1的事务还未提交。但是此时在session1是可以查到,这是不是和上述有点矛盾呢,其实不然,未提交的数据会临时写到内存或磁盘(内存不足的情况下),且未提交的数据上有个锁(涉及隔离级别,后续讲解),锁是只有当前事务唯一持有的,所以其他事务取不到,但当前事务是可以读取的。 <这段划重点,可以多理解一下>

接着换一种思路,在session2(自动提交)上插入一条新数据insert into test_a values(2,2);然后去session1查询,发现session1上仍然查不到新增的数据,这里有人会问session2不是设置的自动提交吗,为什么session1查不到数据呢?这是因为当session为非自动提交状态时,自事务开始后的DML操作对其都是不可见的,只有事务结束后才可见。在session1执行commit,就可以查询到新增数据了。

再看第三种情况,在session1新增一条数据,此时在session2查询是查不到新增数据的;此时在session1再新建一张表,再去session2查询,结果发现在session1未执行commit命令的情况下,session2竟然也可以查询到新增数据了。这是因为session1执行了DDL操作,触发了隐式提交事务的规则,所以其他session也可以看到DDL的修改了。但是drop命令有点特殊,如果事务还未结束,drop命令会被阻塞。

ROLLBACK:回滚事务

Rollback就是与commit相反,不提交事务,可以理解成撤回的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> insert into test_a values(1,1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test_a;
+------+------+
| id1 | id2 |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test_a;
Empty set (0.00 sec)

约束

image-20220926114432294

添加约束实例

id:int型主键

ename:字符串型非空唯一

joindate:日期型非空(有空值插入即报错)

salary:浮点型非空

bonus:没有数据默认为0

ps:auto_increment:数字类型+唯一约束可以加自增字段

image-20220926114807798

加入自增字段

image-20220926115106136

外键约束

constraint

image-20220926115638159

一般外键名称可以命名为fk_从表_主表,并且在从表中添加该行语句

image-20220926133721402

如果这个时候想要删除主表的话会发生报错

image-20220926134103294

若不在表内添加外键

image-20220926134348256

数据库设计

设计概念

image-20220926135111255

表间关系

image-20220926135324856

1 -> 1 添加外键,但是注意设置为unique,毕竟是1 to 1

image-20220926140049816

M -> 1补充,在M的一方加入外键,关联1的一方主键,主表的东西往往比附表要少

image-20220926135447054

M -> M,使用中间表的方式,将两表构建关系,

image-20220926135651102

子查询

内外查询和子查询,我的评价是pandas

image-20220926141941935

事务

事务是为了避免特殊情况下有一些操作本来该同时执行的,但是中途出现报错,导致最终结果出现问题而提出的技术手段。

简单来说就是用BEGIN – COMMIT\ROLLBACK三个部分来执行原子操作,BEGIN代表操作开始的flag,commit代表持久化更改数据,rollback就是把这次事务执行语句影响的结果复原,也就是从BEGIN到这一句的所有影响消除。通常commit和rollback在语句末尾任选一句放即可。当数据库数据变化不对劲的时候及时使用rollback,解决问题后用commit

image-20220926142717463

image-20220926143500511

JDBC

JDBC的概念

image-20220926144244491

步骤

基本框架

image-20220926143644636

框架

image-20220926144431549

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class demo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1. 注册驱动,实际使用时可以不写这一行,连接包自动帮助了
Class.forName("com.mysql.jdbc.Driver");

// 2. 获取连接,如果连接的是本机mysql,并且端口默认为3306,可以简化书写
String url = "jdbc:mysql://127.0.0.1:3306/mydb";
String username = "root";
String passwd = "123456";
Connection conn = DriverManager.getConnection(url, username, passwd);

// 3. 定义sql
String sql = "update websites set alexa = 777 where id = 6";

// 4. 获取执行sql的对象 statement
Statement stmt = conn.createStatement();

// 5. 执行sql
int count = stmt.executeUpdate(sql); // 返回受影响的行数

// 6. 处理结果
System.out.println(count);

// 7. 释放资源
stmt.close();
conn.close();
}
}

返回值:1

JDBC API

DriverManager

image-20220926153129446

image-20220926152800041

这里可能会有疑问为什么我们用forname注册驱动,却说他是DriverManager注册的呢?其实是因为我们可以点进去字符串中的Driver,可以看到里面有一个静态的方法,调用时自动启用DriverManager。

image-20220926152730783

Connection

image-20220926153201881

image-20220926153301088

image-20220926153404158

事务管理+trycatch

当程序能顺利执行到commit()即运行完毕,不然就在catch中进行回滚,close可以弄到finally里

image-20220926153802272

Statement

DDL:对数据表、库进行增删改查

DML:对数据的增删改

DQL:对数据的查询操作

image-20220926153948018

ResultSet

需要注意的就是参数部分,列的编号从1开始。

image-20220926160414326

image-20220926160955587

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class demo02 {
@Test
public void testResultSet() throws Exception{
String url = "jdbc:mysql:///mydb";
String username = "root";
String passwd = "123456";
Connection conn = DriverManager.getConnection(url, username, passwd);

// 3. 定义sql
String sql = "select * from websites";

// 4. 获取statement对象
Statement stmt = conn.createStatement();

// 5. 执行sql
ResultSet rs = stmt.executeQuery(sql);

//6. 处理结果,遍历rs所有数据
// 6.1 光标向下移动一行,并且判断当前行是否有数据
while(rs.next()) {
// 6.2 光标向下移动一行,并且判断当前行是否有数据
int id = rs.getInt(1);
String name = rs.getString("name");
double alexa = rs.getDouble(4);

System.out.println(id);
System.out.println(name);
System.out.println(alexa);
}
// 7. 释放资源

rs.close();
stmt.close();
conn.close();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
Google
1.0
2
淘宝
13.0
3
菜鸟教程
4689.0
4
微博
20.0
5
Facebook
3.0
6
jjyaoao'home
777.0

Process finished with exit code 0

PreparedStatement

image-20220926162839452

image-20220926163738611

类似于将原来的password的’’给截断,然后使得他的意思发生改变。

image-20220926163752731

image-20220926164045413

其实就干了一件事情

将文本数据中的特殊字符,加一个转译号

image-20220926165621897

原理

注意:默认是没有开启预编译功能的

image-20220926170004780

开启之后去mysql的myini文件加入执行日志的配置(上图黄色部分)后可看出他的原理,预编译需要开启,红色部分为已开启。

image-20220926170340364

数据库连接池

image-20220926170835338

image-20220926170921860

使用框架

image-20220926172825958

增删改查

大部分内容固定,不固定的特殊标识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@Test
public void testSelectAll() throws Exception {
//1. 获取Connection
//3. 加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("../jdbc-demo/src/druid.properties"));
//4. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

//5. 获取数据库连接 Connection
Connection conn = dataSource.getConnection();

// 这里就是修改sql语句
//2. 定义SQL
String sql = "select * from tb_brand;";

//3. 获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement(sql);

// 这里添加时,绑定除ID以外的参数,更新时,包括自己想要更改的属性以及定位id,删除时,只绑定id
// 查找时无需参数
//4. 设置参数
// pstmt.setInt(1,id);

//5. 执行SQL
ResultSet rs = pstmt.executeQuery();

// 仅查找需要这么做,另外几个功能都可以通过pstmt.executeUpdate()的返回值来进行处理(返回改变的行数)
//6. 处理结果 List<Brand> 封装Brand对象,装载List集合
Brand brand = null;
List<Brand> brands = new ArrayList<>();
while (rs.next()){
//获取数据,rs为sql语句返回的结果
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
//封装Brand对象
brand = new Brand();
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setStatus(status);

//装载集合
brands.add(brand);

}
System.out.println(brands);
//7. 释放资源
rs.close();
pstmt.close();
conn.close();


}