JavaEE知识点总结
一、前端基础
1️⃣ HTML(超文本标记语言)
定义:构建网页结构的标记语言,用来定义网页中的元素(如文字、图片、超链接、表格等)。
常用标签:
-
结构标签:
<html>、<head>、<body> -
标题标签:
<h1>~<h6> -
段落标签:
<p> -
链接标签:
<a href="..."> -
图片标签:
<img src="..."> -
列表标签:
<ul>、<ol>、<li> -
表格标签:
<table>、<tr>、<td> -
表单标签:
<form>、<input>、<select>、<textarea>
语义化标签(HTML5新增):
-
<header>、<footer>、<article>、<section>、<nav> -
有助于SEO优化与结构清晰化
HTML注释:<!-- 注释内容 -->
💡 面试常见考点:
HTML语义化的好处?
-
有助于SEO、可读性、屏幕阅读器识别结构
块级元素与行内元素区别?
-
块级独占一行(div、p),行内元素不换行(span、a)
2️⃣ CSS(层叠样式表)
作用:控制网页样式与布局
基本语法:
css
选择器 {属性: 值;
}
选择器类型:
-
标签选择器:
div -
类选择器:
.class -
ID选择器:
#id -
伪类选择器:
:hover、:first-child
优先级规则:!important > ID > 类 > 标签 > 继承
盒模型(Box Model):
-
组成:
content + padding + border + margin -
可通过
box-sizing控制计算方式
布局方式:
-
浮动布局:
float -
定位布局:
position -
弹性布局:
display: flex -
网格布局:
display: grid
CSS动画:
-
transition:过渡效果 -
@keyframes:定义动画关键帧
💡 面试常见考点:
CSS优先级算法?
-
内联样式 > ID > 类 > 标签 > 通配符
Flex布局常用属性?
-
justify-content、align-items、flex-direction
盒模型中margin合并的原理?
3️⃣ JavaScript(网页逻辑层)
定义:一种运行在浏览器端的脚本语言,用于控制网页交互和逻辑
数据类型:
-
基本类型:number、string、boolean、undefined、null、symbol、bigint
-
引用类型:Object、Array、Function、Date
变量定义:var、let、const
运算符与流程控制:
-
运算符:
+ - * / %、==、===(严格相等) -
条件语句:
if / else / switch -
循环语句:
for / while / for...of / for...in
函数:
-
普通函数、箭头函数
()=>{} -
参数与返回值
DOM操作:
-
获取元素:
document.getElementById()、querySelector() -
修改样式:
element.style.color = "red" -
修改内容:
innerHTML、textContent
事件:
-
添加事件:
onclick或addEventListener() -
常见事件:click、mouseover、keyup、submit
定时器:
-
setTimeout()、setInterval()
ES6特性:
-
模板字符串:
`Hello ${name}` -
解构赋值、展开运算符
-
模块化
import / export
💡 面试常见考点:
== 与 === 的区别?
-
==比较值,===比较值和类型
闭包是什么?
-
函数访问外部作用域变量形成的作用域链
原型链原理?
-
对象通过
__proto__继承上级原型形成链式结构
4️⃣ jQuery(简化JS操作)
定义:一个快速、简洁的JavaScript库,用于简化DOM操作和AJAX请求
选择器:
-
基本:
$("div")、$(".class")、$("#id") -
组合:
$("ul li:first")
DOM操作:
-
内容操作:
text()、html()、val() -
属性操作:
attr()、css() -
元素创建与删除:
append()、remove()
事件绑定:
-
.click()、.on("click", fn)
动画效果:
-
.show()、.hide()、.fadeIn()、.slideDown()
AJAX封装:
-
$.ajax()、$.get()、$.post()
💡 面试常见考点:
jQuery与JS区别?
-
jQuery更简洁、兼容性好、封装DOM
on() 与 click() 区别?
-
on()可绑定动态元素事件,click()不行
5️⃣ AJAX(异步请求)
定义:Asynchronous JavaScript and XML,一种在不刷新页面的情况下与服务器通信的技术
核心对象:XMLHttpRequest
作用:局部刷新页面,提升交互体验
AJAX工作原理:
-
创建
XMLHttpRequest对象 -
调用
open()方法设置请求类型和URL -
调用
send()方法发送请求 -
监听
onreadystatechange状态变化 -
接收并处理服务器响应
参数说明:
-
method:GET / POST
-
url:请求地址
-
async:是否异步
-
data:请求数据
AJAX练习案例:
js
var xhr = new XMLHttpRequest();
xhr.open("GET", "data.json", true);
xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {console.log(xhr.responseText);}
};
xhr.send();
💡 面试常见考点:
AJAX的优点?
-
无刷新更新页面、减轻服务器压力、用户体验好
readyState有几种状态?
-
0未初始化、1已打开、2已发送、3处理中、4完成
6️⃣ JSON(数据交换格式)
定义:JavaScript Object Notation,一种轻量级数据格式,常用于前后端数据交互
格式规则:
-
对象:
{"name":"Tom","age":18} -
数组:
[{"id":1},{"id":2}]
前端操作JSON:
-
字符串转对象:
JSON.parse() -
对象转字符串:
JSON.stringify()
💡 面试常见考点:
JSON与XML区别?
-
JSON更简洁、传输更快、结构更清晰
7️⃣ FastJSON(Java后端常用库)
作用:在Java中快速序列化/反序列化JSON数据
常用方法:
-
JSON.parseObject(String, Class):字符串 → 对象 -
JSON.toJSONString(Object):对象 → 字符串
二、Web基础与服务器
1️⃣ C/S 与 B/S 架构
C/S结构(Client / Server)
-
客户端独立程序(如QQ、微信)
-
响应速度快、安全性高,但维护复杂
B/S结构(Browser / Server)
-
用户通过浏览器访问服务器
-
无需安装客户端,维护方便
💡 面试常见考点:
C/S与B/S区别?
-
C/S性能好但维护难,B/S易扩展但依赖浏览器
2️⃣ 静态网页与动态网页
静态网页:固定内容(HTML/CSS),每次访问内容相同
动态网页:内容可变,由服务器端程序生成(JSP、Servlet、PHP)
区别:
-
静态:无逻辑交互
-
动态:可与数据库交互
💡 面试考点:
动态网页的原理?
-
由服务器运行程序生成HTML再返回客户端
3️⃣ 常见Web服务器
-
Tomcat:轻量级Java Web服务器(Servlet容器)
-
Nginx:高性能反向代理服务器
-
Apache:常用于静态网页服务
-
IIS:Windows系统自带Web服务器
4️⃣ Tomcat服务器
定义:Apache基金会开发的Java Web应用服务器
功能:运行JSP、Servlet程序,提供HTTP服务
Tomcat文件结构:
| 文件夹 | 作用 |
|---|---|
| bin | 启动脚本 |
| conf | 配置文件(server.xml / web.xml) |
| lib | 依赖jar包 |
| logs | 日志文件 |
| webapps | 部署的Web应用 |
| temp / work | 临时目录 |
Tomcat配置文件:
-
server.xml:端口配置、虚拟主机配置 -
web.xml:全局Servlet映射与加载顺序
启动与重启:
-
Windows:
startup.bat、shutdown.bat -
Linux:
./startup.sh、./shutdown.sh
💡 面试考点:
Tomcat默认端口?
-
8080
Web应用部署路径?
-
放在
webapps下的目录即为项目名
5️⃣ IDEA整合Tomcat
-
打开 Run → Edit Configurations
-
新建 Tomcat Server
-
选择 Deployment 绑定 Web 项目
-
运行后访问
http://localhost:8080/项目名
6️⃣ HTTP协议
定义:超文本传输协议(HyperText Transfer Protocol),是浏览器与服务器通信的标准
请求协议
请求行:方法 + URL + 协议版本
例:GET /index.html HTTP/1.1
请求头:携带附加信息(Host、User-Agent、Cookie)
请求体:POST方式时的数据部分
响应协议
响应行:协议 + 状态码 + 状态描述
例:HTTP/1.1 200 OK
响应头:Content-Type、Server、Set-Cookie
响应体:服务器返回的HTML或JSON内容
常见HTTP状态码:
| 状态码 | 含义 |
|---|---|
| 200 | 请求成功 |
| 301 | 永久重定向 |
| 404 | 资源未找到 |
| 500 | 服务器内部错误 |
💡 面试常见考点:
GET与POST区别?
-
GET在URL中传参、POST放在请求体
HTTP状态码:200、404、500代表什么?
HTTP协议是无状态的吗?
-
是,需要使用Session/Cookie保存状态
三、Web项目与HTTP协议
1️⃣ Web项目结构
在 Java Web 开发中,一个标准的 Web 项目通常包含如下结构:
text
webapp/ │ ├── index.html / index.jsp # 前端页面 ├── css/ # 样式文件 ├── js/ # 脚本文件 ├── WEB-INF/ # Web应用的核心目录 │ ├── web.xml # 部署描述文件(Servlet配置) │ ├── classes/ # 编译后的class文件 │ └── lib/ # 项目依赖的jar包
🧩 结构说明:
-
WebContent / webapp:存放项目的可访问资源(HTML、JSP、CSS、JS等)
-
WEB-INF:安全目录,外部无法直接访问
-
web.xml:部署描述文件,用于配置 Servlet、过滤器、监听器等
-
classes:存放 Java 源文件编译后的字节码
-
lib:存放依赖的第三方库(JAR包)
-
💡 面试点:
为什么 WEB-INF 下的文件不能被直接访问?
👉 因为 Tomcat 会阻止对 WEB-INF 目录的直接 HTTP 访问,以保证项目安全
2️⃣ IDEA 整合 Tomcat
(1) 添加 Tomcat 配置
-
打开 Run → Edit Configurations
-
点击
+→ 选择 Tomcat Server → Local -
指定 Tomcat 的安装路径
(2) 部署项目
-
在 Deployment 中添加项目(选择 war exploded)
-
设置应用路径(如
/demo)
(3) 设置访问路径
-
启动后通过浏览器访问:
text
http://localhost:8080/demo/index.jsp
💡 常见端口:8080
💡 默认项目路径:项目名(可修改)
3️⃣ HTTP 协议
(1) HTTP 概述
-
HTTP(HyperText Transfer Protocol):超文本传输协议,是 Web 通信的基础
-
采用 请求-响应模型,由客户端发送请求,服务器返回响应
-
常见端口:80(HTTP),443(HTTPS)
(2) HTTP 请求协议结构
一个 HTTP 请求由三部分组成:
text
请求行 + 请求头 + 请求体
✅ 请求行(Request Line)
text
GET /index.html HTTP/1.1
包含:
-
请求方法(Method):GET、POST、PUT、DELETE、HEAD 等
-
请求路径(URL)
-
协议版本(HTTP/1.1)
✅ 请求头(Request Headers)
提供客户端与请求的元数据,如:
text
Host: www.example.com User-Agent: Chrome/141 Content-Type: application/json Cookie: sessionId=abc123
✅ 请求体(Request Body)
用于携带数据(仅 POST / PUT 等方法有)
例如:
json
{"username": "admin","password": "123456"
}
(3) HTTP 响应协议结构
由服务器返回,格式为:
text
响应行 + 响应头 + 响应体
✅ 响应行(Response Line)
text
HTTP/1.1 200 OK
包含:
-
协议版本
-
状态码
-
状态描述
常见状态码:
| 状态码 | 含义 |
|---|---|
| 200 | 请求成功 |
| 301 | 永久重定向 |
| 302 | 临时重定向 |
| 400 | 客户端错误(Bad Request) |
| 401 | 未授权(Unauthorized) |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
✅ 响应头(Response Headers)
描述服务器信息:
text
Content-Type: text/html; charset=utf-8 Server: Apache-Coyote/1.1 Set-Cookie: token=abc123
✅ 响应体(Response Body)
实际返回的数据,可以是:
-
HTML 页面
-
JSON 数据
-
文件流等
(4) 常见 HTTP 方法
| 方法 | 作用 |
|---|---|
| GET | 获取资源 |
| POST | 提交数据(表单、JSON) |
| PUT | 更新资源 |
| DELETE | 删除资源 |
| HEAD | 获取报文头信息 |
| OPTIONS | 查看服务器支持哪些方法 |
💡 面试常问:GET 和 POST 的区别?
| 对比项 | GET | POST |
|---|---|---|
| 参数位置 | URL(?key=value) | 请求体 |
| 安全性 | 低(参数可见) | 高 |
| 数据长度 | 有限制 | 无限制 |
| 缓存 | 可被缓存 | 不缓存 |
| 幂等性 | 幂等 | 非幂等 |
四、数据库基础
1️⃣ 什么是数据库?
数据库(Database, DB)是一种用于存储和管理数据的软件系统
它以一定的数据模型组织数据,支持高效的增删改查操作
💡 数据库是所有动态网站、应用系统的核心部分
2️⃣ 数据库的作用
-
数据持久化:将数据长期保存在磁盘中
-
数据共享:多个程序可同时访问同一数据库
-
数据安全:通过权限与事务保证数据一致性与安全性
-
数据查询与统计:可通过 SQL 快速查询、聚合、分析数据
3️⃣ 关系型数据库(RDBMS)
-
基于 表(Table)结构 存储数据
-
通过 行(Row)与列(Column) 组织
-
使用 SQL语言 进行数据操作
-
各表之间通过 主键、外键 建立关系
📘 关系模型举例:
text
表名:user +----+----------+--------+ | id | username | age | +----+----------+--------+ | 1 | Alice | 20 | | 2 | Bob | 22 | +----+----------+--------+
4️⃣ 常见的关系型数据库
| 数据库 | 特点 |
|---|---|
| MySQL | 开源、轻量、高性能,Web开发主流数据库 |
| Oracle | 功能强大,企业级应用广泛 |
| SQL Server | 微软出品,与 .NET 平台集成好 |
| PostgreSQL | 高扩展性,支持高级SQL特性 |
| MariaDB | MySQL的分支版本 |
5️⃣ 数据库分类
| 类型 | 特点 | 代表产品 |
|---|---|---|
| 关系型数据库 | 表结构存储,支持SQL | MySQL、Oracle、PostgreSQL |
| 非关系型数据库(NoSQL) | 键值或文档存储,灵活 | Redis、MongoDB、Cassandra |
6️⃣ SQL语言简介
-
SQL(Structured Query Language)是操作关系数据库的标准语言
-
功能:查询、插入、更新、删除、定义表结构、控制权限等
📘 SQL分类:
| 类别 | 全称 | 作用 |
|---|---|---|
| DDL | Data Definition Language | 定义数据库结构(CREATE、DROP、ALTER) |
| DML | Data Manipulation Language | 操作数据(INSERT、UPDATE、DELETE) |
| DQL | Data Query Language | 查询数据(SELECT) |
| DCL | Data Control Language | 权限控制(GRANT、REVOKE) |
7️⃣ 数据库操作示例(MySQL)
sql
-- 创建数据库
CREATE DATABASE testdb;-- 使用数据库
USE testdb;-- 创建表
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),age INT
);-- 插入数据
INSERT INTO user (name, age) VALUES ('Alice', 20);-- 查询数据
SELECT * FROM user;-- 修改数据
UPDATE user SET age = 21 WHERE name = 'Alice';-- 删除数据
DELETE FROM user WHERE id = 1;
8️⃣ 数据库约束(Constraint)
| 约束类型 | 作用 |
|---|---|
| PRIMARY KEY | 主键约束,唯一标识记录 |
| UNIQUE | 唯一约束,不能重复 |
| NOT NULL | 非空约束,禁止为空 |
| FOREIGN KEY | 外键约束,维护表之间的引用关系 |
| DEFAULT | 设置默认值 |
| CHECK | 检查约束,限制值范围 |
💡 约束的好处:
-
保证数据完整性
-
提高数据一致性
-
避免非法数据插入
9️⃣ 常见面试题汇总
| 面试题 | 答案 |
|---|---|
| 什么是数据库? | 存储、管理数据的系统 |
| 什么是关系型数据库? | 用表格结构组织数据,支持SQL操作 |
| MySQL 与 Oracle 区别? | MySQL开源轻量;Oracle商业强大 |
| DDL 与 DML 区别? | DDL定义结构;DML操作数据 |
| 主键与外键的作用? | 主键唯一标识记录;外键建立表间关系 |
| 数据库事务的四大特性? | 原子性、一致性、隔离性、持久性(ACID) |
五、SQL语言
1️⃣ SQL语言介绍
-
SQL(Structured Query Language) 是一种 结构化查询语言,用于操作关系型数据库
-
SQL 是一种 通用语言,不同数据库(MySQL、Oracle、PostgreSQL、SQL Server)语法大体相似
-
SQL 主要用来:
-
创建数据库和表结构
-
插入、修改、删除数据
-
查询数据
-
管理用户权限等
-
📘 SQL 的特点
-
非过程化语言:只需告诉数据库"做什么",不必写"怎么做"
-
统一标准:符合 ANSI SQL 标准
-
简洁高效,易学易用
💡 面试点:
SQL 是编程语言吗?
👉 SQL 是 声明式语言(Declarative Language),不是过程式语言。你只描述操作目标,执行细节由数据库引擎决定
2️⃣ SQL分类(四大类)
| 类型 | 全称 | 功能 | 常见命令 |
|---|---|---|---|
| DDL | Data Definition Language | 定义数据库结构 | CREATE、DROP、ALTER |
| DML | Data Manipulation Language | 操作表中数据 | INSERT、UPDATE、DELETE |
| DQL | Data Query Language | 查询数据 | SELECT |
| DCL | Data Control Language | 控制权限与访问 | GRANT、REVOKE、COMMIT、ROLLBACK |
3️⃣ DDL(数据定义语言)
✅ 创建数据库与表
sql
CREATE DATABASE testdb; USE testdb;CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL,age INT,gender CHAR(1) );
✅ 修改表结构
sql
ALTER TABLE user ADD COLUMN email VARCHAR(100); ALTER TABLE user MODIFY COLUMN age SMALLINT; ALTER TABLE user DROP COLUMN gender;
✅ 删除数据库或表
sql
DROP DATABASE testdb; DROP TABLE user;
💡 注意:DROP 会永久删除数据,无法恢复
4️⃣ DML(数据操作语言)
sql
-- 插入数据
INSERT INTO user (username, age) VALUES ('Alice', 22);-- 修改数据
UPDATE user SET age = 23 WHERE username = 'Alice';-- 删除数据
DELETE FROM user WHERE id = 1;
💡 面试点:
DELETE、TRUNCATE、DROP 区别?
命令 删除对象 可回滚 删除速度 DELETE 表中数据 ✅ 慢 TRUNCATE 表中所有数据 ❌ 快 DROP 整个表 ❌ 最快
5️⃣ DQL(数据查询语言)
✅ 基本查询
sql
SELECT * FROM user; SELECT username, age FROM user;
✅ 条件查询
sql
SELECT * FROM user WHERE age > 18 AND gender = 'F';
✅ 排序查询
sql
SELECT * FROM user ORDER BY age DESC;
✅ 聚合函数
| 函数 | 含义 |
|---|---|
| COUNT() | 统计行数 |
| SUM() | 求和 |
| AVG() | 平均值 |
| MAX() | 最大值 |
| MIN() | 最小值 |
✅ 分组与过滤
sql
SELECT gender, COUNT(*) AS total FROM user GROUP BY gender;
6️⃣ DCL(数据控制语言)
sql
-- 创建用户 CREATE USER 'test'@'localhost' IDENTIFIED BY '123456';-- 授权 GRANT ALL PRIVILEGES ON testdb.* TO 'test'@'localhost';-- 回收权限 REVOKE ALL PRIVILEGES ON testdb.* FROM 'test'@'localhost';
💡 面试点:
COMMIT 与 ROLLBACK 的区别?
-
COMMIT:提交事务,数据永久保存
-
ROLLBACK:回滚事务,撤销未提交的修改
六、MySQL数据库
1️⃣ 概念与安装
-
MySQL 是一种开源的关系型数据库管理系统(RDBMS),以高性能、稳定、跨平台著称
-
MySQL 使用 C/S(客户端/服务器)架构
-
安装后可通过命令行或图形工具(如 Navicat)连接
✅ 常用命令
bash
# 启动 MySQL 服务 net start mysql# 登录数据库 mysql -u root -p# 退出 exit;
💡 测试是否安装成功:
bash
mysql --version
2️⃣ 数据库操作
sql
-- 创建数据库 CREATE DATABASE shop CHARACTER SET utf8mb4;-- 查看数据库 SHOW DATABASES;-- 使用数据库 USE shop;-- 删除数据库 DROP DATABASE shop;
💡 面试点:
utf8 和 utf8mb4 的区别?
👉 utf8 在 MySQL 中只支持最多 3 字节字符,而 utf8mb4 支持 4 字节(如 emoji)
3️⃣ 数据类型详解
| 类型 | 示例 | 说明 |
|---|---|---|
| 整数类型 | INT、TINYINT、BIGINT | 存储整型数值 |
| 小数类型 | FLOAT、DOUBLE、DECIMAL | 存储带小数的数值 |
| 字符串类型 | CHAR、VARCHAR、TEXT | CHAR 定长,VARCHAR 变长 |
| 日期时间类型 | DATE、TIME、DATETIME、TIMESTAMP | 存储时间与日期 |
| 布尔类型 | BOOLEAN(本质是 TINYINT 1) | 0为假,1为真 |
| 二进制类型 | BLOB | 存储图片、文件等大数据 |
💡 小技巧:
-
使用
DECIMAL(10,2)存金额,避免浮点误差
4️⃣ 表的约束(Constraint)
| 约束类型 | 关键字 | 作用 |
|---|---|---|
| 主键约束 | PRIMARY KEY | 唯一标识记录 |
| 唯一约束 | UNIQUE | 字段值唯一 |
| 非空约束 | NOT NULL | 不允许为空 |
| 外键约束 | FOREIGN KEY | 建立表间关联 |
| 默认约束 | DEFAULT | 设置默认值 |
📘 示例:
sql
CREATE TABLE student (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE,class_id INT,FOREIGN KEY (class_id) REFERENCES class(id) );
💡 约束的作用:
-
保证数据合法性
-
保证表之间的引用关系
-
避免冗余与错误数据
5️⃣ 表结构操作(CRUD)
sql
-- 查看表 SHOW TABLES;-- 查看表结构 DESC student;-- 修改表结构 ALTER TABLE student ADD COLUMN phone VARCHAR(20); ALTER TABLE student MODIFY COLUMN name VARCHAR(100); ALTER TABLE student DROP COLUMN phone;-- 删除表 DROP TABLE student;
6️⃣ 数据操作(CURD)
sql
-- 插入数据
INSERT INTO student (name, email, class_id) VALUES ('Alice', 'a@xx.com', 1);-- 修改数据
UPDATE student SET email = 'alice@school.com' WHERE id = 1;-- 删除数据
DELETE FROM student WHERE id = 1;-- 查询数据
SELECT * FROM student WHERE class_id = 2;
💡 注意:
-
使用
WHERE限制条件,防止误删整表数据
7️⃣ 查询增强
✅ 条件查询
sql
SELECT * FROM student WHERE age BETWEEN 18 AND 25; SELECT * FROM student WHERE name LIKE 'A%';
✅ 排序(ORDER BY)
sql
SELECT * FROM student ORDER BY age DESC;
✅ 分组(GROUP BY)
sql
SELECT class_id, COUNT(*) FROM student GROUP BY class_id;
✅ 聚合函数
| 函数 | 说明 |
|---|---|
| COUNT() | 统计数量 |
| SUM() | 求和 |
| AVG() | 平均值 |
| MAX() | 最大值 |
| MIN() | 最小值 |
✅ 分页查询
sql
SELECT * FROM student LIMIT 0, 10;
8️⃣ 多表查询
✅ 内连接(INNER JOIN)
sql
SELECT s.name, c.name FROM student s INNER JOIN class c ON s.class_id = c.id;
✅ 左连接(LEFT JOIN)
sql
SELECT s.name, c.name FROM student s LEFT JOIN class c ON s.class_id = c.id;
(即使没有匹配的 class,学生也会显示)
✅ 右连接(RIGHT JOIN)
sql
SELECT s.name, c.name FROM student s RIGHT JOIN class c ON s.class_id = c.id;
✅ 子查询(Subquery)
sql
SELECT * FROM student WHERE class_id = (SELECT id FROM class WHERE name = 'Java班' );
9️⃣ 表关系与设计原则
| 关系类型 | 举例 | 说明 |
|---|---|---|
| 一对一 | 用户-身份证 | 一个用户对应一张身份证 |
| 一对多 | 班级-学生 | 一个班级对应多个学生 |
| 多对多 | 学生-课程 | 需借助中间表(student_course) |
📘 表设计原则:
-
字段原子化:一个字段只存一类信息
-
主外键明确:保持表间关系清晰
-
字段名有意义:易读易维护
-
冗余可控:必要时为性能冗余字段
-
范式化设计:遵循 1NF、2NF、3NF
七、JDBC 编程
1️⃣ JDBC 概述
-
JDBC(Java Database Connectivity)是 Java 提供的一套标准 数据库访问接口规范,用于操作各种关系型数据库(如 MySQL、Oracle、PostgreSQL 等)
-
JDBC 位于 Java 应用程序与数据库之间,起到"桥梁"作用
-
本质:通过 驱动程序(Driver) 让 Java 程序与数据库通信
📘 核心目标:
屏蔽不同数据库差异,提供统一操作接口
💡 面试点:
JDBC 是接口还是类?
👉 JDBC 是一组接口(API),真正的实现由数据库厂商提供的驱动实现
2️⃣ JDBC 快速入门(五大步骤)
java
public class JDBCDemo {public static void main(String[] args) throws Exception {// 1. 加载驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 建立连接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "123456");// 3. 创建Statement对象Statement stmt = conn.createStatement();// 4. 执行SQL语句ResultSet rs = stmt.executeQuery("SELECT * FROM user");// 5. 处理结果集while (rs.next()) {System.out.println(rs.getString("username"));}// 6. 释放资源rs.close();stmt.close();conn.close();}
}
📗 执行流程口诀:
加载驱动 → 建立连接 → 创建对象 → 执行SQL → 处理结果 → 释放资源
3️⃣ JDBC 核心组件
| 组件 | 作用 |
|---|---|
| DriverManager | 管理数据库驱动、建立连接 |
| Connection | 表示数据库连接对象,提供事务控制 |
| Statement | 用于执行静态 SQL 语句 |
| PreparedStatement | 预编译 SQL,提高性能并防止 SQL 注入 |
| ResultSet | 封装 SQL 查询结果集 |
| SQLException | 捕获数据库相关异常 |
💡 面试点:
Connection 提供哪些功能?
👉 提供事务控制:setAutoCommit(false),commit(),rollback()
4️⃣ JDBC 增删改查(CURD)
✅ 增删改(executeUpdate)
java
String sql = "INSERT INTO user(username, age) VALUES('Tom', 22)";
int rows = stmt.executeUpdate(sql);
System.out.println("影响行数:" + rows);
💡 executeUpdate() 返回受影响的行数
✅ 查询(executeQuery)
java
ResultSet rs = stmt.executeQuery("SELECT * FROM user");
while (rs.next()) {System.out.println(rs.getInt("id") + " - " + rs.getString("username"));
}
💡 executeQuery() 返回结果集 ResultSet,使用 rs.next() 遍历
✅ 使用 PreparedStatement 防止 SQL 注入
java
String sql = "SELECT * FROM user WHERE username = ? AND password = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, inputUser); ps.setString(2, inputPass); ResultSet rs = ps.executeQuery();
💡 PreparedStatement 会对参数进行预编译与转义,避免拼接SQL带来的注入风险
5️⃣ JDBC 工具类编写(封装复用)
java
public class JDBCUtils {private static final String URL = "jdbc:mysql://localhost:3306/testdb";private static final String USER = "root";private static final String PASSWORD = "123456";static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {throw new RuntimeException("加载驱动失败");}}public static Connection getConnection() throws SQLException {return DriverManager.getConnection(URL, USER, PASSWORD);}public static void close(Connection conn, Statement stmt, ResultSet rs) {try {if (rs != null) rs.close();if (stmt != null) stmt.close();if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}
}
💡 封装优势:
-
简化 JDBC 操作
-
防止资源泄漏
-
提高代码复用性
6️⃣ SQL 注入漏洞与防护
❌ 漏洞示例
java
String sql = "SELECT * FROM user WHERE name='" + input + "'";
若输入:' OR '1'='1
→ 语句变成:
sql
SELECT * FROM user WHERE name='' OR '1'='1'
👉 所有用户数据都会被查询出,造成严重信息泄露
✅ 防护方案
-
使用 PreparedStatement(预编译机制)
-
对用户输入做合法性验证(正则过滤非法字符)
-
使用 最小权限原则(只授予必要的数据库操作权限)
-
使用 ORM 框架(MyBatis / Hibernate)自带预防机制
💡 面试问法:
PreparedStatement 如何防止 SQL 注入?
👉 SQL 在编译阶段已固定结构,参数不会再被解析为 SQL 语句,从而避免注入攻击
八、反射与注解
1️⃣ 反射的概念
-
反射(Reflection):在运行时动态地加载类、创建对象、访问属性和调用方法的机制
-
Java 中的反射基于
java.lang.reflect包
📘 核心作用:
"编译时不知道类名,运行时还能操作类"
💡 应用场景:
-
框架底层(Spring、MyBatis)
-
动态加载配置类
-
通用工具类(对象拷贝、ORM映射)
2️⃣ Class 类详解
| 方法 | 作用 |
|---|---|
Class.forName("包名.类名") | 通过类名加载 Class 对象 |
对象.getClass() | 获取对象对应的 Class |
类名.class | 获取类的 Class 对象 |
getMethods() | 获取所有公共方法 |
getDeclaredFields() | 获取类中声明的所有字段 |
newInstance() | 创建类实例(无参构造) |
📘 示例:
java
Class<?> cls = Class.forName("com.demo.User");
Object obj = cls.getDeclaredConstructor().newInstance();
3️⃣ Method 类(操作方法)
-
用于获取和调用类的方法
java
Method m = cls.getMethod("showInfo");
m.invoke(obj); // 调用无参方法
💡 调用私有方法:
java
Method m = cls.getDeclaredMethod("calc", int.class);
m.setAccessible(true); // 关闭权限检查
m.invoke(obj, 10);
4️⃣ Field 类(操作属性)
-
用于读取或修改字段值
java
Field f = cls.getDeclaredField("name");
f.setAccessible(true);
f.set(obj, "Tom"); // 修改属性
System.out.println(f.get(obj)); // 获取属性
💡 常用于:ORM(如MyBatis)中字段映射、对象拷贝工具
5️⃣ Constructor 类(操作构造方法)
java
Constructor<?> c = cls.getConstructor(String.class, int.class);
Object user = c.newInstance("Alice", 20);
💡 可以通过反射调用有参构造方法创建对象
6️⃣ 实践:通过反射拷贝对象
java
public static void copy(Object src, Object dest) throws Exception {Class<?> clazz = src.getClass();for (Field field : clazz.getDeclaredFields()) {field.setAccessible(true);Object value = field.get(src);field.set(dest, value);}
}
💡 实现对象属性的浅拷贝,类似于 BeanUtils.copyProperties()
7️⃣ 代理模式(Proxy Pattern)
✅ 静态代理(伪代码)
java
interface Service { void doWork(); }class ServiceImpl implements Service {public void doWork() { System.out.println("业务逻辑"); }
}class ServiceProxy implements Service {private Service target;public ServiceProxy(Service target) { this.target = target; }public void doWork() {System.out.println("前置增强");target.doWork();System.out.println("后置增强");}
}
💡 缺点: 每个类都要单独写代理类,代码冗余
✅ 动态代理(JDK Proxy)
java
Service proxy = (Service) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxyObj, method, args) -> {System.out.println("前置增强");Object result = method.invoke(target, args);System.out.println("后置增强");return result;});
💡 常用于 AOP(面向切面编程) 实现,如 Spring 的事务、日志功能
8️⃣ 注解(Annotation)
✅ 系统内置注解
| 注解 | 作用 |
|---|---|
@Override | 重写父类方法 |
@Deprecated | 标记过时方法 |
@SuppressWarnings | 忽略编译警告 |
✅ 自定义注解
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {String value() default "操作日志";
}
💡 使用注解:
java
@LogInfo("添加用户")
public void addUser() {}
✅ 注解与反射结合开发
-
框架中常用做"元数据标记",结合反射动态处理逻辑
java
Method m = cls.getMethod("addUser");
LogInfo info = m.getAnnotation(LogInfo.class);
System.out.println(info.value());
💡 实战应用:
-
Spring:
@Controller、@Autowired -
MyBatis:
@Select、@Mapper -
JUnit:
@Test
📘 面试常考:
| 问题 | 答案 |
|---|---|
| 什么是反射? | 运行时动态操作类的机制 |
| 反射性能如何? | 稍慢于直接调用(因为需要权限检查与类型转换) |
| 动态代理和静态代理区别? | 动态代理在运行时生成代理类,更灵活;静态代理需手写类 |
| 注解如何起作用? | 通过反射读取注解信息,根据逻辑动态处理 |
