JavaEE 环境与程序设计 · 交互课程
技术演进接力链(M1 → M9)
  1. 1WEB 基础
    HTTP / Browser / WebServer
    静态页面写死,人人看到一样
  2. 2Servlet
    手写 if-else 分发不可扩展,无生命周期/并发管理
  3. 3JSP:参数散字符串
    参数散成一堆 String,取值靠字段名硬记
  4. 3JSP:scriptlet 塞逻辑
    scriptlet 把逻辑塞进页面,代码与 HTML 糊在一起
  5. 3JavaBean:数据对象化
    对象全靠 new、层层硬依赖
  6. 4Spring IoC
    Web 路由仍手写 web.xml/if-else、手动取参绑定,展示/业务/数据访问没分开
  7. 5MVC · SpringMVC
    数据在库里,访问是重复样板 + 拼串有注入风险
  8. 6MySQL
    Java 连库要手写五步,连接与资源管理全手动
  9. 7JDBC
    SQL 与 Java 混写、结果集逐行手映射、没有动态 SQL
  10. 8MyBatis
    四份配置 + web.xml 装配繁琐,部署要外部 Tomcat
  11. 9SpringBoot
    链尾 · 不考核

MySQL 数据库基础

承接上一章的死结
上一章(SpringMVC)的死结:数据在数据库里,访问是重复样板 + 拼串有注入风险。本章先搞清「数据到底放哪」——MySQL 建库建表。

MySQL 数据库基础

目标:理解「数据到底放哪」——从 M5 章末死结「数据在数据库里」出发,掌握 MySQL 安装与客户端连接、DDL 建库建表、DML 四语句(INSERT/SELECT/UPDATE/DELETE)、主键自增、逻辑外键,以及用户与授权基础。

本模块承接前面所有 Web 层的「展示」:Servlet/JSP/SpringMVC 负责把数据呈现出来,但数据本身要持久化——存到数据库里。MySQL 是最常用的关系型数据库,也是后面 MyBatis/SSM 存取数据的底座。

一、为什么需要数据库:数据到底放哪

前面 M1–M5 讲的 Servlet、JSP、Spring IoC、SpringMVC,解决的都是「怎么把数据展示给浏览器」。但有个根本问题没答:数据本身存在哪?

要「结构化存储 + 可按条件检索 + 持久不丢 + 多用户并发」,就需要关系型数据库。MySQL 是其中最流行的一款:表(table) 由行(row) 和列(column) 组成,用 SQL(Structured Query Language)来建表、增删改查。

一句话:Web 层负责「显示」,数据库负责「保存」,中间靠 JDBC/MyBatis 打通——这正是 M7/M8 要讲的桥。

二、安装与连接:mysql CLI / Navicat

MySQL 装好后有两种常用入口:

连上之后先选一个「数据库」(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_idint(11) + AUTO_INCREMENT编号只需递增整数,让数据库自动发号
emp_namevarchar(22)变长字符串,姓名不长,给 22 够用
emp_emailvarchar(256)邮箱可能较长,留足空间
genderchar(2)定长(M/F/男/女),用 char 比 varchar 省
department_idint(11)与部门表主键同类型,便于关联

约束:NOT NULL(不许空)、DEFAULT ''(默认值)、PRIMARY KEY(主键,唯一 + 非空)。下面交互实验把这两张表搬进内存,点选看结构、执行 DML 实时看数据变化:

MySQL 表结构实验室对照 shrmssm.sql · tbl_dept / tbl_emp
表结构(tbl_dept)
列名类型约束
dept_idPK逻辑外键int(11)AUTO_INCREMENT
dept_namevarchar(255) DEFAULT ''
dept_leadervarchar(255) DEFAULT ''
PK AUTO_INCREMENT NOT NULL · DEFAULT '' · DEFAULT ''
数据(2 行)
dept_iddept_namedept_leader
1组织经
2财务钱
🔗 逻辑外键:tbl_emp.department_id → tbl_dept.dept_id(应用层保证一致,不建物理外键)

四、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() 一样返回。

共 3 行 · id 自动编号

guestbook 表(当前状态)

id自动编号userid用户 IDusername昵称title留言标题contents留言内容
1u001tomfrom tom大家好,这是我的第一条留言。
2u002jerryRe: from tom很高兴认识你,tom!
3u003lucy课程很棒JDBC 时序图讲得很清楚。
方法映射:增 / 改 / 删 → executeUpdate(sql)(返回受影响行数,不返回结果集); 查 → executeQuery(sql)(返回 ResultSet,用 rs.next() 逐行读)。

五、主键自增 + 逻辑外键

所以 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

思考题

  1. 「数据在数据库里」——为什么用内存 List 存数据不行?关系型数据库解决了哪几个痛点?
  2. emp_name 用 varchar(22)、gender 用 char(2),选型依据是什么?
  3. 主键自增(AUTO_INCREMENT)给业务代码省去了什么?为什么 INSERT/UPDATE 都不能动它?
  4. tbl_emp.department_id 是逻辑外键。为什么不建物理外键?把校验放应用层有什么好处?
  5. DDL 与 DML 的区别是什么?GRANT 属于哪一类?

学习小测验

学习小测验

Q1

关于 MySQL 里 emp_name 用 varchar(22)、gender 用 char(2) 的选型,正确的是( )

Q2

empid int(11) NOT NULL AUTOINCREMENT, PRIMARY KEY(emp_id) 的含义是( )

Q3

下面哪条 SQL 是「查」语句(DML-SELECT)?

Q4

关于 UPDATE / DELETE,正确的是( )

Q5

tblemp.departmentid 指向 tbldept.deptid,本课程不建物理外键,称之为( )

Q6

为什么课程表一律加 DEFAULT CHARSET=utf8?

Q7

CREATE USER 'hrm'@'localhost' ...; GRANT SELECT,INSERT,UPDATE,DELETE ON shrmssm.* TO 'hrm'@'localhost'; 体现了( )

本章留下的死结
Java 连库要手写五步、连接与资源管理全手动(下一章 JDBC)。