- 1WEB 基础HTTP / Browser / WebServer静态页面写死,人人看到一样
- 2Servlet手写 if-else 分发不可扩展,无生命周期/并发管理
- 3JSP:参数散字符串参数散成一堆 String,取值靠字段名硬记
- 3JSP:scriptlet 塞逻辑scriptlet 把逻辑塞进页面,代码与 HTML 糊在一起
- 3JavaBean:数据对象化对象全靠 new、层层硬依赖
- 4Spring IoCWeb 路由仍手写 web.xml/if-else、手动取参绑定,展示/业务/数据访问没分开
- 5MVC · SpringMVC数据在库里,访问是重复样板 + 拼串有注入风险
- 6MySQLJava 连库要手写五步,连接与资源管理全手动
- 7JDBCSQL 与 Java 混写、结果集逐行手映射、没有动态 SQL
- 8MyBatis四份配置 + web.xml 装配繁琐,部署要外部 Tomcat
- 9SpringBoot链尾 · 不考核
MySQL 数据库基础
MySQL 数据库基础
目标:理解「数据到底放哪」——从 M5 章末死结「数据在数据库里」出发,掌握 MySQL 安装与客户端连接、DDL 建库建表、DML 四语句(INSERT/SELECT/UPDATE/DELETE)、主键自增、逻辑外键,以及用户与授权基础。
本模块承接前面所有 Web 层的「展示」:Servlet/JSP/SpringMVC 负责把数据呈现出来,但数据本身要持久化——存到数据库里。MySQL 是最常用的关系型数据库,也是后面 MyBatis/SSM 存取数据的底座。
一、为什么需要数据库:数据到底放哪
前面 M1–M5 讲的 Servlet、JSP、Spring IoC、SpringMVC,解决的都是「怎么把数据展示给浏览器」。但有个根本问题没答:数据本身存在哪?
- 写在
.txt/.csv里?——没有结构、没法按条件查、并发写会乱; - 放在 Java 内存(
List/Map)里?——进程一重启就全没了,多用户共享不了。
要「结构化存储 + 可按条件检索 + 持久不丢 + 多用户并发」,就需要关系型数据库。MySQL 是其中最流行的一款:表(table) 由行(row) 和列(column) 组成,用 SQL(Structured Query Language)来建表、增删改查。
一句话:Web 层负责「显示」,数据库负责「保存」,中间靠 JDBC/MyBatis 打通——这正是 M7/M8 要讲的桥。
二、安装与连接:mysql CLI / Navicat
MySQL 装好后有两种常用入口:
- 命令行
mysql:mysql -u root -p登录后进入交互提示符,直接敲 SQL; - 图形工具 Navicat:建库、看表结构、执行 SQL 都有界面,适合教学演示。
连上之后先选一个「数据库」(database)再操作:
CREATE DATABASE shrmssm DEFAULT CHARACTER SET utf8; -- 建库(字符集用 utf8,避免中文乱码)
USE shrmssm; -- 切换到该库
SHOW TABLES; -- 看库里有哪些表
utf8 字符集:建库建表都要指定
DEFAULT CHARSET=utf8,否则存中文会出现乱码——这是课程里所有表的统一约定。
三、DDL:CREATE DATABASE / CREATE TABLE
DDL(Data Definition Language,数据定义语言) 负责「定义结构」:建库、建表、改表、删表。对照 shrmssm.sql 里的两张表逐列看:
-- 部门表
CREATE TABLE tbl_dept (
dept_id int(11) NOT NULL AUTO_INCREMENT, -- 主键,自增
dept_name varchar(255) DEFAULT '', -- 部门名称
dept_leader varchar(255) DEFAULT '', -- 负责人
PRIMARY KEY (dept_id)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- 员工表
CREATE TABLE tbl_emp (
emp_id int(11) NOT NULL AUTO_INCREMENT, -- 主键,自增
emp_name varchar(22) DEFAULT '', -- 姓名(短,22 够)
emp_email varchar(256) DEFAULT '', -- 邮箱(长一点)
gender char(2) DEFAULT '', -- 性别(定长 1~2 字符)
department_id int(11) DEFAULT '0', -- 所属部门(逻辑外键)
PRIMARY KEY (emp_id)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
几个字段类型选型要点:
| 列 | 类型 | 为什么这么选 |
|---|---|---|
dept_id / emp_id | int(11) + AUTO_INCREMENT | 编号只需递增整数,让数据库自动发号 |
emp_name | varchar(22) | 变长字符串,姓名不长,给 22 够用 |
emp_email | varchar(256) | 邮箱可能较长,留足空间 |
gender | char(2) | 定长(M/F/男/女),用 char 比 varchar 省 |
department_id | int(11) | 与部门表主键同类型,便于关联 |
约束:
NOT NULL(不许空)、DEFAULT ''(默认值)、PRIMARY KEY(主键,唯一 + 非空)。下面交互实验把这两张表搬进内存,点选看结构、执行 DML 实时看数据变化:
| 列名 | 类型 | 约束 |
|---|---|---|
| dept_idPK逻辑外键 | int(11) | AUTO_INCREMENT |
| dept_name | varchar(255) | DEFAULT '' |
| dept_leader | varchar(255) | DEFAULT '' |
| dept_id | dept_name | dept_leader |
|---|---|---|
| 1 | 组织 | 经 |
| 2 | 财务 | 钱 |
四、DML:INSERT / SELECT / UPDATE / DELETE
DML(Data Manipulation Language,数据操作语言) 负责「操作数据」:增删改查。以员工表为例:
-- 增 INSERT:不写 emp_id(自增),其余列给值
INSERT INTO tbl_emp(emp_name, emp_email, gender, department_id) VALUES('李四', 'li@q.com', 'F', 2);
-- 查 SELECT:可加 WHERE / ORDER BY / LIMIT
SELECT * FROM tbl_emp WHERE department_id = 1;
SELECT emp_name, gender FROM tbl_emp ORDER BY emp_id DESC LIMIT 5;
-- 改 UPDATE:必须带 WHERE,否则会改整张表
UPDATE tbl_emp SET gender='F' WHERE emp_id=3;
-- 删 DELETE:必须带 WHERE,否则会删整张表
DELETE FROM tbl_emp WHERE emp_id=11;
复用 CRUDVisualizer:下面这个组件用留言板表演示「增删改查 SQL → 表格实时变化」的范式,和上面员工表是同一套 DML 逻辑,可对照着练:
交互实验:CRUD 增删改查实时演示(CRUDVisualizer)
executeUpdate / executeQuery在内存里的 guestbook(留言板)表上直接试 CRUD:点预设或自己写一条 SQL(INSERT / UPDATE / DELETE / SELECT), 点「执行」——新增行变绿、修改行变黄、删除的行红色划掉,受影响行数像 executeUpdate() 一样返回。
guestbook 表(当前状态)
| id自动编号 | userid用户 ID | username昵称 | title留言标题 | contents留言内容 |
|---|---|---|---|---|
| 1 | u001 | tom | from tom | 大家好,这是我的第一条留言。 |
| 2 | u002 | jerry | Re: from tom | 很高兴认识你,tom! |
| 3 | u003 | lucy | 课程很棒 | JDBC 时序图讲得很清楚。 |
executeUpdate(sql)(返回受影响行数,不返回结果集); 查 → executeQuery(sql)(返回 ResultSet,用 rs.next() 逐行读)。五、主键自增 + 逻辑外键
- 主键自增(AUTO_INCREMENT):
emp_id每插入一行自动 +1,业务代码不用管编号——既保证唯一,又省去手工发号。INSERT 时不能指定它,UPDATE 时不能改它。 - 逻辑外键 vs 物理外键:
tbl_emp.department_id指向tbl_dept.dept_id,表示「员工属于哪个部门」。本课程的表不建物理外键(不写FOREIGN KEY ... REFERENCES),只在应用层(Service/DAO)保证一致性。原因:- 物理外键让数据库强约束,删部门前必须先删光其员工,灵活性差;
- 课程聚焦 SSM 分层,把「关联校验」放在 Java 业务层更直观、更好测。
所以
department_id是个逻辑外键:值域上对应dept_id,但数据库不强制。
六、用户与授权基础
生产环境不会让所有人用 root 连库。MySQL 支持建专用账号并只授予所需权限:
CREATE USER 'hrm'@'localhost' IDENTIFIED BY 'hrm123'; -- 建用户
GRANT SELECT, INSERT, UPDATE, DELETE ON shrmssm.* TO 'hrm'@'localhost'; -- 只给 DML 权限,不给 DROP/CREATE
FLUSH PRIVILEGES; -- 生效
最小权限原则:应用账号一般只给
SELECT/INSERT/UPDATE/DELETE,建表删库(DDL)留给 DBA。
DDL vs DML 分类表
| 类别 | 作用 | 语句 |
|---|---|---|
| DDL | 定义结构 | CREATE / ALTER / DROP(DATABASE、TABLE) |
| DML | 操作数据 | INSERT / SELECT / UPDATE / DELETE |
| DCL | 控制权限 | CREATE USER / GRANT / REVOKE |
思考题
- 「数据在数据库里」——为什么用内存
List存数据不行?关系型数据库解决了哪几个痛点? emp_name用varchar(22)、gender用char(2),选型依据是什么?- 主键自增(AUTO_INCREMENT)给业务代码省去了什么?为什么 INSERT/UPDATE 都不能动它?
tbl_emp.department_id是逻辑外键。为什么不建物理外键?把校验放应用层有什么好处?- DDL 与 DML 的区别是什么?
GRANT属于哪一类?
学习小测验
学习小测验
关于 MySQL 里 emp_name 用 varchar(22)、gender 用 char(2) 的选型,正确的是( )
empid int(11) NOT NULL AUTOINCREMENT, PRIMARY KEY(emp_id) 的含义是( )
下面哪条 SQL 是「查」语句(DML-SELECT)?
关于 UPDATE / DELETE,正确的是( )
tblemp.departmentid 指向 tbldept.deptid,本课程不建物理外键,称之为( )
为什么课程表一律加 DEFAULT CHARSET=utf8?
CREATE USER 'hrm'@'localhost' ...; GRANT SELECT,INSERT,UPDATE,DELETE ON shrmssm.* TO 'hrm'@'localhost'; 体现了( )