day5

计划

  1. HTML入门基础学习

笔记

1.HTML基础结构

  1. 文档声明<!DOCTYPE html>,声明文件类型为HTML5
  2. 根元素<html>,包含整个HTML文档
  3. 头部<head>,存放页面元信息
    • <title>:页面标题,显示在浏览器标签栏
    • <meta>:元数据,如字符集<meta charset="UTF-8">、视口设置<meta name="viewport">
    • <style>:内部样式表
    • <link>:引入外部样式表
  4. 主体<body>,页面可见内容区域

2.常用HTML标签

文本标签
  1. <h1>-<h6>:标题标签,h1最大,h6最小
  2. <p>:段落标签
  3. <span>:行内容器,不换行
  4. <div>:块级容器,独占一行
  5. <b>:加粗文本
媒体标签
  1. <img>:图片标签
    • src:图片路径(相对路径如./img/1.png或绝对路径)
    • alt:图片加载失败时的替代文本
  2. <video>:视频标签
    • src:视频路径
    • controls:显示播放控制条
链接标签
  1. <a>:超链接标签
    • href:目标URL
    • target="_blank":在新窗口打开

3.CSS样式

三种引入方式
  1. 行内样式:通过标签的style属性直接设置,优先级最高
    1
    <span style="color: red;">红色文字</span>
  2. 内部样式:在<style>标签内定义,作用于当前页面
  3. 外部样式:通过<link>标签引入外部CSS文件,可复用
    1
    <link rel="stylesheet" href="css/test01.css">
CSS选择器
  1. 元素选择器:直接使用标签名,选中所有该标签
    1
    span { color: red; }
  2. 类选择器:使用.类名,可选中多个元素(类名可重复)
    1
    .time { color: #b7b7b7; }
  3. ID选择器:使用#ID名,只能选中一个元素(ID唯一)
    1
    #a001 { text-decoration: none; }

4.盒子模型

  1. 核心概念:每个元素都是一个盒子,由内容(content)、内边距(padding)、边框(border)、外边距(margin)组成
  2. box-sizing:控制盒子尺寸计算方式
    • content-box(默认):width/height仅包含内容
    • border-box:width/height包含内容+内边距+边框,便于布局计算
  3. margin:外边距,控制元素间距
    • margin: 0 auto;:上下边距为0,左右自动,实现块级元素居中

5.Flexbox弹性布局

  1. 开启方式:父元素设置display: flex;
  2. 主轴方向flex-direction
    • row(默认):水平方向
    • column:垂直方向
  3. 主轴对齐justify-content
    • space-between:两端对齐,项目之间间距相等
    • center:居中对齐
    • space-around:均匀分布,项目两侧间距相等
  4. 交叉轴对齐align-items
    • center:垂直居中
    • flex-start:顶部对齐
    • flex-end:底部对齐

6.表单与表单项

表单结构
  1. <form>:表单容器
    • action:提交地址
    • method:提交方式(get/post)
表单项类型
  1. 文本输入类

    • text:单行文本
    • password:密码输入(隐藏内容)
    • email:邮箱输入(自动验证格式)
    • tel:电话输入
    • url:网址输入
    • textarea:多行文本
  2. 数字输入类

    • number:数字输入(带上下箭头)
    • range:范围滑块
  3. 日期时间类

    • date:日期选择器
    • time:时间选择器
  4. 选择类

    • select:下拉列表(配合<option>使用)
    • radio:单选按钮(同一组name相同,互斥)
    • checkbox:复选框(可多选)
  5. 文件上传

    • file:文件选择,multiple属性支持多文件
  6. 按钮类

    • submit:提交表单
    • reset:重置表单
    • button:普通按钮

7.表格

  1. <table>:表格容器
  2. <thead>:表头区域
  3. <tbody>:表体区域
  4. <tr>:表格行
  5. <th>:表头单元格(默认加粗居中)
  6. <td>:表格数据单元格
  7. 边框合并border-collapse: collapse;

8.综合页面实践

  1. 页面布局:使用div划分区域(导航栏、内容区、页脚)
  2. 响应式设置<meta name="viewport">适配移动端
  3. 样式优先级:行内样式 > ID选择器 > 类选择器 > 元素选择器
  4. 常用CSS属性
    • text-indent: 2em;:首行缩进2个字符
    • line-height:行高
    • text-decoration: none;:取消下划线
    • border-radius:圆角
    • cursor: pointer;:鼠标悬停显示手型
    • transition:过渡动画效果

day7

计划

  1. Maven项目构建与管理入门

笔记

1.Maven概述

  1. 作用:项目构建、依赖管理、项目信息管理
  2. 核心概念:基于项目对象模型(POM),通过pom.xml管理项目

2.Maven项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
maven-project01/
├── pom.xml # Maven核心配置文件
├── src/
│ ├── main/
│ │ └── java/ # 主代码目录
│ │ └── com/zhang/ # 包结构
│ │ ├── helloworld.java
│ │ └── UserService.java
│ └── test/
│ └── java/ # 测试代码目录
│ └── com/zhang/
│ └── UserServiceTest.java
└── target/ # 编译输出目录(自动生成)

3.POM配置

项目坐标
  1. groupId:组织标识(如org.example
  2. artifactId:项目标识(如maven-project01
  3. version:版本号(如1.0-SNAPSHOT
编译属性
1
2
3
4
5
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
引入依赖
  1. <dependencies>中添加<dependency>标签
  2. 依赖组成:groupId + artifactId + version
  3. 依赖范围(scope):控制依赖的使用范围
    • test:仅在测试时使用,打包时不包含
    • compile(默认):编译、测试、运行都有效
    • provided:编译和测试时有效,运行时由容器提供
    • runtime:运行时有效,编译时不需要
1
2
3
4
5
6
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>

4.单元测试(JUnit 5)

基础注解
  1. @Test:标记一个方法为测试方法
  2. @DisplayName:为测试方法添加中文描述名称,便于阅读
  3. @BeforeAll:在所有测试方法执行前执行一次(静态方法)
  4. @AfterAll:在所有测试方法执行后执行一次(静态方法)
  5. @BeforeEach:每个测试方法执行前都执行一次
  6. @AfterEach:每个测试方法执行后都执行一次
参数化测试
  1. @ParameterizedTest:标记参数化测试方法
  2. @ValueSource(strings = {"数据1", "数据2"}):提供参数列表
  3. 方法参数接收传入的测试数据,自动执行多次测试
常用断言
  1. Assertions.assertEquals(预期值, 实际值, "失败提示信息"):判断两个值是否相等
  2. Assertions.assertThrows(异常类型, 可执行代码):判断是否抛出指定异常

5.测试示例

业务方法(UserService)
  1. getAge(idCard):从身份证号中提取出生日期(第7-14位),计算年龄
    1
    2
    3
    4
    5
    public Integer getAge(String idCard) {
    String birthday = idCard.substring(6, 14);
    LocalDate parse = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyyMMdd"));
    return Period.between(parse, LocalDate.now()).getYears();
    }
  2. getGender(idCard):从身份证号中提取第17位,奇数为男,偶数为女
    1
    2
    3
    public String getGender(String idCard) {
    return Integer.parseInt(idCard.substring(16, 17)) % 2 == 1 ? "男" : "女";
    }
测试方法
  1. 单个测试:使用@Test,调用方法后打印或断言结果
  2. 参数化测试:使用@ParameterizedTest + @ValueSource,批量测试多组数据
  3. 异常测试:使用assertThrows验证非法输入时是否抛出预期异常
  4. 断言验证:使用assertEquals判断方法返回结果是否符合预期

day8

计划

  1. SpringBootWeb入门
  2. HTTP协议学习
  3. SpringBootWeb案例
  4. 分层解耦与IOC/DI

笔记

1.SpringBootWeb入门

Spring家族简介
  • SpringFramework:Spring家族最基础、最核心的框架,提供依赖注入、事务管理、Web开发支持等功能
  • SpringBoot:简化配置、快速开发,是企业开发的主流方式
  • Spring全家桶:Spring家族旗下一系列技术,解决不同领域的问题
起步依赖
  • spring-boot-starter-web:包含Web应用开发所需的常见依赖,内嵌Tomcat服务器
  • spring-boot-starter-test:包含单元测试所需的常见依赖
  • 起步依赖本质:预定义的依赖项集合,提供特定场景下开发所需的所有库和配置
入门程序
1
2
3
4
5
6
7
8
9
@RestController  //标识当前类是一个请求处理类,包含@Controller和@ResponseBody
public class HelloController {

@RequestMapping("/hello") //标识请求路径
public String hello(String name){
System.out.println("HelloController ... hello: " + name);
return "Hello " + name;
}
}
  • @RestController:组合注解,包含@Controller@ResponseBody
  • @RequestMapping:映射请求路径
  • 启动类:带有@SpringBootApplication注解的类,运行main方法启动内嵌Tomcat

2.HTTP协议

HTTP概述
  • HTTP:超文本传输协议,规定浏览器与服务器之间数据传输的规则
  • 特点
    • 基于TCP协议:面向连接,安全
    • 基于请求-响应模型:一次请求对应一次响应
    • 无状态协议:对数据没有记忆能力,每次请求-响应独立
HTTP请求协议
  1. 请求行:请求方式、资源路径、协议/版本
  2. 请求头:key: value形式,包含浏览器信息等
  3. 请求体:存储请求参数(POST请求使用)
请求头 含义
Host 请求的主机名
User-Agent 浏览器版本
Accept 浏览器能接收的资源类型
Content-Type 请求主体的数据类型
GET vs POST请求
区别 GET请求 POST请求
请求参数位置 请求行中 请求体中
请求参数长度 有限制 无限制
安全性 低(暴露在地址栏) 相对高
获取请求数据
1
2
3
4
5
6
7
8
9
@RequestMapping("/request")
public String request(HttpServletRequest request){
String name = request.getParameter("name"); //获取请求参数
String uri = request.getRequestURI(); //获取请求URI
String url = request.getRequestURL().toString(); //获取请求URL
String method = request.getMethod(); //获取请求方式
String header = request.getHeader("User-Agent"); //获取请求头
return "request success";
}
HTTP响应协议
  1. 响应行:协议/版本、响应状态码、状态码描述
  2. 响应头:key: value形式
  3. 响应体:存储响应数据
响应状态码
分类 说明
1xx 临时状态码,表示请求已接受
2xx 成功,表示请求已被成功接收处理
3xx 重定向,让客户端再发起请求
4xx 客户端错误
5xx 服务器端错误

常用状态码

  • 200 OK:请求成功
  • 404 Not Found:请求资源不存在
  • 500 Internal Server Error:服务器发生错误
设置响应数据
1
2
3
4
5
6
7
8
9
10
11
12
13
//方式1:使用HttpServletResponse
@RequestMapping("/response")
public void response(HttpServletResponse response) throws IOException {
response.setStatus(404); //设置响应状态码
response.setHeader("name", "zhang"); //设置响应头
response.getWriter().write("<h1>hello springboot</h1>"); //设置响应体
}

//方式2:使用ResponseEntity
@RequestMapping("/response01")
public ResponseEntity<String> response01() {
return ResponseEntity.status(200).header("name", "li").body("hello springboot");
}

3.SpringBootWeb案例

需求说明

基于SpringBoot开发Web程序,完成用户列表的渲染展示:

  1. 前端页面发送ajax请求(/list)
  2. 服务端加载user.txt文件数据
  3. 返回JSON格式数据给前端
  4. 前端渲染展示在表格中
代码实现

1). 实体类User

1
2
3
4
5
6
7
8
9
10
11
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private String name;
private Integer age;
private LocalDateTime updateTime;
}

2). Controller层

1
2
3
4
5
6
7
8
@RestController
public class UserController {
@RequestMapping("/list")
public List<User> list() {
//读取文件、解析数据、响应JSON
return userList;
}
}

@ResponseBody注解

  • 将方法返回值直接响应给浏览器
  • 如果返回值是实体对象/集合,会自动转换为JSON格式
  • @RestController包含@ResponseBody,无需单独使用

4.三层架构

架构介绍
  • Controller(控制层):接收前端请求,处理请求,响应数据
  • Service(业务逻辑层):处理具体业务逻辑
  • Dao(数据访问层):负责数据访问操作(增删改查)

执行流程:前端请求 → Controller → Service → Dao → 文件/数据库

优势

  1. 复用性强
  2. 便于维护
  3. 利于扩展
代码拆分

1). Controller层

1
2
3
4
5
6
7
8
9
10
@RestController
public class UserController {
private UserService userService = new UserServiceImpl();

@RequestMapping("/list")
public List<User> list() {
List<User> userList = userService.findAll();
return userList;
}
}

2). Service层(接口+实现类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//接口
public interface UserService {
List<User> findAll();
}

//实现类
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();

@Override
public List<User> findAll() {
List<String> lines = userDao.findAll();
//解析数据为User对象
return userList;
}
}

3). Dao层(接口+实现类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//接口
public interface UserDao {
List<String> findAll();
}

//实现类
public class UserDaoImpl implements UserDao {
@Override
public List<String> findAll() {
InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
List<String> lines = IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());
return lines;
}
}

5.IOC&DI(控制反转与依赖注入)

问题分析

直接new对象会导致层与层之间耦合,难以维护和扩展。

软件设计原则:高内聚低耦合

解耦思路
  1. 将对象交给容器管理(IOC容器)
  2. 程序运行时从容器中获取依赖对象(依赖注入)

核心概念

  • IOC(控制反转):对象的创建控制权由程序自身转移到外部容器
  • DI(依赖注入):容器为应用程序提供运行时所依赖的资源
  • Bean对象:IOC容器中创建、管理的对象
Bean的声明

使用@Component及其衍生注解将类交给IOC容器管理:

注解 说明 位置
@Component 声明bean的基础注解 不属于以下三类时使用
@Controller @Component的衍生注解 控制层类
@Service @Component的衍生注解 业务层类
@Repository @Component的衍生注解 数据访问层类
组件扫描
  • @ComponentScan:扫描指定包及其子包下的bean
  • @SpringBootApplication包含@ComponentScan,默认扫描启动类所在包及其子包
依赖注入(@Autowired)

方式1:属性注入

1
2
3
4
5
@RestController
public class UserController {
@Autowired
private UserService userService;
}
  • 优点:代码简洁
  • 缺点:隐藏依赖关系,可能破坏封装性

方式2:构造函数注入(推荐)

1
2
3
4
5
6
7
8
9
@RestController
public class UserController {
private final UserService userService;

@Autowired //只有一个构造函数时可省略
public UserController(UserService userService) {
this.userService = userService;
}
}
  • 优点:依赖关系清晰,安全性高

方式3:setter注入

1
2
3
4
5
6
7
8
9
@RestController
public class UserController {
private UserService userService;

@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
多个相同类型Bean的解决方案

方案1:@Primary

1
2
3
4
@Primary
@Service
public class UserServiceImpl implements UserService {
}

方案2:@Qualifier

1
2
3
4
5
6
@RestController
public class UserController {
@Qualifier("userServiceImpl")
@Autowired
private UserService userService;
}

方案3:@Resource

1
2
3
4
5
@RestController
public class UserController {
@Resource(name = "userServiceImpl")
private UserService userService;
}
@Autowired与@Resource的区别
区别 @Autowired @Resource
所属框架 Spring框架 JDK提供
默认注入方式 按类型注入 按名称注入

6.完整代码示例

最终项目结构
1
2
3
4
5
6
7
8
9
10
11
12
springboot-web-04/
├── src/main/java/com/zhang/
│ ├── controller/UserController.java #控制层
│ ├── service/UserService.java #业务层接口
│ ├── service/impl/UserServiceImpl.java #业务层实现
│ ├── dao/UserDao.java #数据访问层接口
│ ├── dao/impl/UserDaoImpl.java #数据访问层实现
│ ├── pojo/User.java #实体类
│ └── SpringbootWeb04Application.java #启动类
└── src/main/resources/
├── user.txt #数据文件
└── application.properties #配置文件
UserController(最终版本)
1
2
3
4
5
6
7
8
9
10
11
@RestController
public class UserController {
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;

@RequestMapping("/list")
public List<User> list() {
return userService.findAll();
}
}
UserServiceImpl(最终版本)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;

@Override
public List<User> findAll() {
List<String> lines = userDao.findAll();
return lines.stream().map(line -> {
String[] parts = line.split(",");
return new User(
Integer.parseInt(parts[0]),
parts[1], parts[2], parts[3],
Integer.parseInt(parts[4]),
LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
);
}).toList();
}
}
UserDaoImpl(最终版本)
1
2
3
4
5
6
7
8
@Repository
public class UserDaoImpl implements UserDao {
@Override
public List<String> findAll() {
InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
return IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());
}
}

7.核心知识点总结

知识点 说明
@RestController 组合注解,包含@Controller和@ResponseBody
@RequestMapping 映射请求路径
@ResponseBody 将返回值转为JSON响应给浏览器
@Service 声明业务层Bean
@Repository 声明数据访问层Bean
@Autowired 自动装配,按类型注入依赖
@Qualifier 按名称选择注入的Bean
@Primary 指定默认主Bean
@Resource JDK提供,按名称注入
IOC 控制反转,对象由容器管理
DI 依赖注入,容器提供依赖对象
三层架构 Controller→Service→Dao

计划

  1. MySQL概述
  2. SQL语句(DDL、DML、DQL)
  3. 数据类型与约束
  4. 表结构设计案例

笔记

1.MySQL概述

相关概念
  • 数据库(DB):存储和管理数据的仓库
  • 数据库管理系统(DBMS):操作和管理数据库的大型软件
  • SQL(结构化查询语言):操作关系型数据库的编程语言,定义统一标准
MySQL版本
  • 商业版本:收费,提供技术支持
  • 社区版本:免费开源,本课程使用MySQL 8.0.34社区版
连接方式
1
2
3
4
5
-- 本地连接
mysql -u用户名 -p密码

-- 远程连接
mysql -hIP地址 -P端口号 -u用户名 -p密码

2.SQL语句分类

SQL语句根据功能分为四大类:

分类 全称 说明
DDL Data Definition Language 数据定义语言,定义数据库对象(数据库、表、字段)
DML Data Manipulation Language 数据操作语言,对表中数据进行增删改
DQL Data Query Language 数据查询语言,查询表记录
DCL Data Control Language 数据控制语言,创建用户、控制权限

3.DDL语句

数据库操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 查询所有数据库
show databases;

-- 查询当前数据库
select database();

-- 创建数据库
create database [if not exists] 数据库名 [default charset utf8mb4];

-- 使用数据库
use 数据库名;

-- 删除数据库
drop database [if exists] 数据库名;
表结构操作

创建表

1
2
3
4
5
create table 表名(
字段1 字段类型 [约束] [comment 注释],
字段2 字段类型 [约束] [comment 注释],
...
) [comment 表注释];

查询表

1
2
3
4
5
6
7
8
-- 查询当前数据库所有表
show tables;

-- 查看表结构
desc 表名;

-- 查询建表语句
show create table 表名;

修改表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 添加字段
alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];

-- 修改字段类型
alter table 表名 modify 字段名 新类型(长度);

-- 修改字段名和类型
alter table 表名 change 旧字段名 新字段名 类型(长度) [comment 注释];

-- 删除字段
alter table 表名 drop 字段名;

-- 修改表名
rename table 表名 to 新表名;

删除表

1
drop table [if exists] 表名;

4.约束

约束概念

约束是作用在表中字段上的规则,保证数据的正确性、有效性和完整性。

常用约束
约束 描述 关键字
非空约束 限制字段值不能为null not null
唯一约束 保证字段数据唯一不重复 unique
主键约束 唯一标识一行数据,非空且唯一 primary key
默认约束 未指定值时采用默认值 default
外键约束 建立表间连接,保证数据一致性 foreign key
主键自增
1
id int primary key auto_increment comment 'ID,唯一标识'

5.数据类型

数值类型
类型 小写 大小 描述
TINYINT tinyint 1byte 小整数值
SMALLINT smallint 2bytes 大整数值
MEDIUMINT mediumint 3bytes 大整数值
INT/INTEGER int/integer 4bytes 大整数值
BIGINT bigint 8bytes 极大整数值
FLOAT float 4bytes 单精度浮点数值
DOUBLE double 8bytes 双精度浮点数值
DECIMAL decimal - 小数值(精确定点数)

示例

1
2
3
4
5
-- 年龄(无负数,不会太大)
age tinyint unsigned

-- 分数(最多1位小数)
score double(4,1)
字符串类型
类型 小写 大小 描述
CHAR char 0-255 bytes 定长字符串
VARCHAR varchar 0-65535 bytes 变长字符串
TEXT text 0-65535 bytes 长文本数据

示例

1
2
3
4
5
-- 用户名(长度不定,最长50)
username varchar(50)

-- 手机号(固定11位)
phone char(11)
日期时间类型
类型 小写 大小 格式
DATE date 3 YYYY-MM-DD
TIME time 3 HH:MM:SS
DATETIME datetime 8 YYYY-MM-DD HH:MM:SS
TIMESTAMP timestamp 4 YYYY-MM-DD HH:MM:SS

示例

1
2
3
4
5
-- 生日(只需年月日)
birthday date

-- 创建时间(需要精确到秒)
create_time datetime

6.DML语句

添加数据(INSERT)
1
2
3
4
5
6
7
8
-- 指定字段添加
insert into 表名 (字段1, 字段2) values (值1, 值2);

-- 全部字段添加
insert into 表名 values (值1, 值2, ...);

-- 批量添加
insert into 表名 (字段1, 字段2) values (值1, 值2), (值1, 值2);

注意

  • 字段顺序与值顺序要一一对应
  • 字符串和日期用引号包含
  • 数据大小在字段规定范围内
修改数据(UPDATE)
1
update 表名 set 字段1 =1, 字段2 =2 [where 条件];

注意

  • 不加条件会修改整张表所有数据
  • 修改时建议同步更新update_time字段
删除数据(DELETE)
1
delete from 表名 [where 条件];

注意

  • 不加条件会删除整张表数据
  • 不能删除单个字段值(用UPDATE置为NULL)

7.DQL语句

基本查询
1
2
3
4
5
6
7
8
9
10
11
-- 查询指定字段
select 字段1, 字段2 from 表名;

-- 查询所有字段
select * from 表名;

-- 设置别名
select 字段1 as 别名1, 字段2 as 别名2 from 表名;

-- 去除重复记录
select distinct 字段列表 from 表名;
条件查询(WHERE)

比较运算符

运算符 功能
>, >= 大于,大于等于
<, <= 小于,小于等于
= 等于
<> / != 不等于
between … and … 在范围内
in(…) 多选一
like 模糊匹配
is null 是null

逻辑运算符

运算符 功能
and / && 并且
or / | | 或者
not / !

示例

1
2
3
4
5
6
7
8
-- 查询薪资大于5000的员工
select * from emp where salary > 5000;

-- 查询入职日期在2000-01-01到2010-01-01之间的员工
select * from emp where entry_date between '2000-01-01' and '2010-01-01';

-- 查询姓名以'张'开头的员工
select * from emp where name like '张%';
聚合函数
函数 功能
count 统计数量
max 最大值
min 最小值
avg 平均值
sum 求和

示例

1
2
3
4
5
6
7
8
-- 统计员工总数
select count(*) from emp;

-- 统计平均薪资
select avg(salary) from emp;

-- 统计最高薪资
select max(salary) from emp;
分组查询(GROUP BY)
1
select 字段列表 from 表名 [where 条件] group by 分组字段 [having 分组后条件];

示例

1
2
3
4
5
-- 按性别分组统计人数
select gender, count(*) from emp group by gender;

-- 查询入职时间在2015年之前的员工,按职位分组,获取人数>=2的职位
select job, count(*) from emp where entry_date <= '2015-01-01' group by job having count(*) >= 2;

where与having区别

  • where:分组前过滤,不能使用聚合函数
  • having:分组后过滤,可以使用聚合函数
排序查询(ORDER BY)
1
select 字段列表 from 表名 order by 字段1 排序方式1, 字段2 排序方式2;

排序方式

  • ASC:升序(默认)
  • DESC:降序

示例

1
2
3
4
5
-- 按入职时间升序排序
select * from emp order by entry_date;

-- 按入职时间升序,入职时间相同按更新时间降序
select * from emp order by entry_date asc, update_time desc;
分页查询(LIMIT)
1
select 字段列表 from 表名 limit 起始索引, 查询记录数;

公式:起始索引 = (页码 - 1) * 每页条数

示例

1
2
3
4
5
6
7
8
9
10
-- 查询第1页,每页5条
select * from emp limit 0, 5;
-- 简写
select * from emp limit 5;

-- 查询第2页,每页5条
select * from emp limit 5, 5;

-- 查询第3页,每页5条
select * from emp limit 10, 5;

8.表结构设计案例

员工表设计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table emp(
id int unsigned primary key auto_increment comment 'ID,主键',
username varchar(20) not null unique comment '用户名',
password varchar(32) not null comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment '性别, 1:男, 2:女',
phone char(11) not null unique comment '手机号',
job tinyint unsigned comment '职位',
salary int unsigned comment '薪资',
image varchar(255) comment '头像',
entry_date date comment '入职日期',
create_time datetime comment '创建时间',
update_time datetime comment '修改时间'
) comment '员工表';
设计流程
  1. 阅读产品原型及需求文档
  2. 确定字段(类型、长度、约束)
  3. 添加基础字段(id、create_time、update_time)

9.核心知识点总结

知识点 说明
DDL 数据定义语言,操作数据库和表结构
DML 数据操作语言,增删改数据
DQL 数据查询语言,查询数据
primary key 主键约束,唯一标识
auto_increment 主键自增
not null 非空约束
unique 唯一约束
default 默认约束
int / varchar / datetime 常用数据类型
where 条件查询
group by 分组查询
order by 排序查询
limit 分页查询
count / max / min / avg / sum 聚合函数

day6

计划

  1. JS基础语法学习
  2. Vue3框架入门

笔记

1.JS引入方式

  1. 内联式:直接在<script>标签内编写代码,写在body底部避免DOM未加载完成
    1
    2
    3
    <script>
    alert('hello world');
    </script>
  2. 外部式:通过src属性引入外部JS文件,利于代码复用和维护
    1
    <script src="./JS/hello.js"></script>

2.JS基础语法

变量
  1. let:声明可变变量
  2. const:声明常量,声明后不可修改
  3. typeof:获取变量类型
函数
  1. 普通函数:使用function关键字定义
    1
    2
    3
    function add(a, b) {
    return a + b;
    }
  2. 匿名函数:没有函数名,可赋值给变量
    1
    2
    3
    let add = function(a, b) {
    return a + b;
    }
  3. 箭头函数:简化写法,this指向父对象
    1
    2
    3
    let add = (a, b) => {
    return a + b;
    }
对象与JSON
  1. 对象定义:键值对形式,属性访问使用.[]
    1
    2
    let stu = { name: '张三', age: 18, sex: '男' };
    console.log(stu.name);
  2. JSON序列化JSON.stringify()将对象转为JSON字符串
  3. JSON反序列化JSON.parse()将JSON字符串转为对象

3.DOM操作

  1. 获取元素
    • document.querySelector('选择器'):获取第一个匹配元素
    • document.querySelectorAll('选择器'):获取所有匹配元素,返回NodeList
  2. 修改样式:通过style属性修改元素CSS样式
    1
    2
    let p = document.querySelector('p');
    p.style.color = 'red';
  3. 遍历元素:使用for...of循环遍历NodeList
    1
    2
    3
    4
    let ps = document.querySelectorAll('p');
    for(let x of ps) {
    x.style.color = 'red';
    }

4.事件监听

  1. 绑定方式element.addEventListener('事件名', 回调函数)
  2. 常用事件
    • click:鼠标点击
    • mouseenter:鼠标移入
    • mouseleave:鼠标移出
    • focus:获得焦点
    • blur:失去焦点
    • keydown:键盘按下
    • keyup:键盘抬起
    • input:表单输入
    • submit:表单提交
  3. 事件对象:回调函数接收event参数,包含事件相关信息
    • event.target:触发事件的元素
    • event.currentTarget:绑定事件的元素

5.JS模块化

  1. 导出:使用export关键字导出函数或变量
    1
    2
    3
    4
    // util.js
    export function log(data) {
    console.log(data);
    }
  2. 导入:使用import关键字导入模块,需设置type="module"
    1
    <script src="./JS/05js模块化.js" type="module"></script>
    1
    2
    import { log } from "./util.js";
    log("hello world");

6.Vue3基础

引入方式
  1. 通过CDN引入Vue3模块
    1
    import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
创建Vue实例
  1. createApp():创建Vue应用实例
  2. .mount('#容器'):挂载到指定DOM元素
核心概念
  1. data选项:定义组件的数据,返回一个对象

    1
    2
    3
    4
    5
    data() {
    return {
    employees: [...]
    }
    }
  2. methods选项:定义组件的方法

    1
    2
    3
    4
    5
    methods: {
    handleMouseEnter(event) {
    event.currentTarget.style.backgroundColor = 'rgb(196,212,225)';
    }
    }
  3. 模板语法

    • {{表达式}}:插值表达式,用于显示数据
    • v-bind:属性:动态绑定属性,简写为:属性
    • v-on:事件:绑定事件,简写为@事件
    • v-for:列表渲染,v-for="(item, index) in list"
    • v-if/v-else-if/v-else:条件渲染,根据条件决定是否加载元素
事件绑定
  1. 在模板中使用v-on:事件名="方法名"绑定事件
  2. 方法接收event参数,可访问事件对象
条件渲染
  1. v-if:条件为false时,元素不会被渲染到DOM
  2. v-show:条件为false时,元素通过display:none隐藏,仍存在于DOM中
v-model双向绑定
  1. 作用:实现表单元素与Vue数据的双向绑定,数据变化同步到视图,视图变化同步到数据
  2. 使用范围:只能绑定到表单项元素(input、select、textarea等),不能绑定到form表单
    1
    2
    3
    4
    5
    6
    <input v-model="searchForm.name" type="text" placeholder="请输入姓名">
    <select v-model="searchForm.gender">
    <option value="">请选择</option>
    <option value="1"></option>
    <option value="2"></option>
    </select>
  3. 应用场景:搜索表单中绑定查询条件,用户输入时自动更新数据对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    data() {
    return {
    searchForm: {
    name: '',
    gender: '',
    position: ''
    }
    }
    }
methods中的方法交互
  1. 查询方法:读取searchForm中的数据,可用于发送请求
  2. 清空方法:重置searchForm数据,并重新查询
    1
    2
    3
    4
    5
    6
    7
    8
    9
    methods: {
    handleSearch() {
    // 读取searchForm中的查询条件,发送请求
    },
    handleClear() {
    this.searchForm = { name: '', gender: '', position: '' };
    this.handleSearch(); // 清空后重新查询
    }
    }
生命周期钩子
  1. mounted:组件挂载完成后自动调用,常用于初始化数据
    1
    2
    3
    mounted() {
    this.handleSearch(); // 页面加载时自动查询数据
    }

7.Ajax请求(axios)

引入方式
  1. 通过CDN引入axios库,需在Vue之前引入
    1
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
请求方式
  1. GET请求:使用axios.get(url, { params })axios({ method: 'get', url, params })

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 方式1:简洁写法
    let res = await axios.get(`https://api.example.com/emps/list`, {
    params: this.searchForm
    });
    this.employees = res.data.data;

    // 方式2:完整写法
    axios({
    url: `https://api.example.com/emps/list`,
    method: 'get',
    params: this.searchForm
    }).then((res) => {
    this.employees = res.data.data;
    }).catch((err) => {
    console.log(err);
    });
  2. POST请求:使用axios.post(url, data)axios({ method: 'post', url, data })

    1
    2
    3
    4
    5
    6
    7
    axios.post(`https://api.example.com/emps/update`, {
    data: this.searchForm
    }).then((res) => {
    // 处理响应
    }).catch((err) => {
    console.log(err);
    });
Promise与async/await
  1. Promise链式调用.then()处理成功,.catch()处理失败
  2. async/await:将异步代码转换为同步代码
    • 方法前加async关键字
    • await后面跟Promise对象,等待Promise完成
    • 需配合try/catch捕获异常或使用Promise的.catch()
    1
    2
    3
    4
    async handleSearch() {
    let res = await axios.get(`url`, { params: this.searchForm });
    this.employees = res.data.data;
    }
应用流程
  1. 页面加载时(mounted)自动调用查询方法获取数据
  2. 用户点击查询时,根据表单条件发送请求过滤数据
  3. 用户点击清空时,重置表单并重新查询全部数据