环境准备
前期,搭建项目环境,比较费时
前端的环境比较简单就一个node,后端需要提前安装:MySQL(参见3月5日的文章)、Navicat(参见3月5日的笔记)、JDK(需要旗舰版解锁Spring)、IDEA、Maven(以上参见3月6日的文章点击跳转)。
Spring相关的基础概念
- Servlet ∈ Java Servlet API,用于处理HTTP请求和响应, 它需要Java Web容器,如Tomcat...添加外部Jar不方便,需要关注xml,路由配置不方便,一个地址对应一个servlet。
- Spring: 一个分层的轻量级开源框架,核心是IOC(Inverse of Control)& AOP(Aspect Oriented Programming)。
- SpringBoot: 不用过多关注XML的配置,提供一堆依赖,简化了Spring应用的创建、运行、调试、部署。内置了Web容器。
- Spring MVC:MVC:Model(模型)、View(视图)、Controller(控制器)。Spring框架最初没有打算构建自己的Web MVC框架,开发过程中开发人员觉得当时的StrutsWeb框架的呈现层&请求处理层,请求处理层&模型直接分离不够,才创建的Spring MVC。Spring MVC = Strusts + Spring。
- 调用逻辑:前端请求到controller层→services处理业务逻辑,整合好数据以后→mapper→操作数据库(xml)
新建项目,pom.xml报错
- 依赖相关的报错: 找不到插件
- could not acquire lock(s)
- 无法解析符号'repackage'
解决:安装插件
控制台(Terminal)执行
mvn idea:idea
手动刷新:
结果:pom.xml从无数多的飘红转黄色波浪线
main 文件报错:JDK1.8缺失
在提示处选择:添加JDK,选择jdk的安装路径。报错解决。
启动项目报错
没有配置数据库
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
解决:修改resources/application.properties文件,连接MySQL数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xxx(你的数据库名称)?serverTimezone=GMT%2B8
spring.datasource.username=root/(你的数据库用户名)
spring.datasource.password=你的数据库密码
重新启动项目,成功。
access denied for user 'root'@'localhost' (using password: yes)
或
create connection SQLException, errorCode 0, state 08001
检查数据库密码 是否输入错误
端口被占用问题
启动以后默认使用8080端口,如果前端vue项目在之前就启动,8080端口会因被占用。
在上面的文件里添加
server.port=8081
访问地址:
快捷键(跟vscode不一样的地方)
- 复制行是 Ctrl + D
- Alt + Ins 选择生成get & set; Shift 全选
- 查找替换Ctrl + F, Ctrl + R
- 补全Ctrl + Ent
- 删除多余包Ctrl + Alt + O
- 整行移动 Shift + Alt + 上下方向键
- Ctrl + Alt + B 在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口
- Ctrl + Alt + 左方向键 退回到上一个操作的地方
- Ctrl + Alt + 右方向键 前进到上一个操作的地方
- Ctrl + Shift + B 跳转到类型声明处
- Ctrl + Shift + I 快速查看光标所在的方法 或 类的定义
打印
System.out.println("------------------------------------------------------>"+xx);
驼峰映射数据库下划线
数据库字段有下划线,手动全选生成和使用lombok.Data自动生成get/set就不是驼峰。
解决:在修改resources/application.properties文件添加配置
mybatis.configuration.map-underscore-to-camel-case=true
或者
mybatis.configuration.mapUnderscoreToCamelCase=true
Mybatis-plus依赖引入显示红色
Maven 的配置(以上参见3月6日的文章点击跳转)
在IDEA中设置Maven
命名规范
Swagger:Whitelabel Error Page
https://blog.csdn.net/Aige_hml/article/details/124017391
queryWrapper查询不区分大小写
queryWrapper.eq("user_name", userDTO.getUserName());
queryWrapper.eq("password", userDTO.getPassword());
// 改为使用:
lambdaQueryWrapper.eq(User::getUserName, userDTO.getUserName());
lambdaQueryWrapper.eq(User::getPassword, userDTO.getPassword());
项目报错/问题
create_time展示问题
解决:实体类添加注解
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
mybatis部分字段更新不成功【结果是前端精度丢失】
数据库bigint java:long 前端js截断了
解决:实体类添加注解
@JsonFormat(shape = JsonFormat.Shape.STRING)
访问不到本地图片
@Component
public class SysWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**").addResourceLocations("file:D:/work/backend/files/");
}
}
mapper.xml的的比较符号
> > 大于号
< < 小于号
& & 和
' ' 单引号
" '' 双引号
获取resources资源包下的静态资源
getClass().getClassLoader().getResourceAsStream("export-template.xlsx");
数据库相关
报错相关
- 使用了关键字(order改为sys_order)
- 数据类型不一致(id先开始定义为int自增;后面使用UUID生成string类型)
在没有添加@Transactional注解前,主表插入失败,子表插入成功。主表的@TableId不能删掉,type改为INPUT
@ApiModelProperty("主表id,业务里用不带-的UUID创建") @TableId(value = "id", type = IdType.INPUT)
基础知识相关
关系型数据库三大点:锁、事务、索引
索引
- B+树最顶部的节点叫根节点,最底部的节点叫叶子节点,叶子节点存储了完整的记录。
- MySQL给B+树起名为索引。索引即数据,数据即索引。每一颗B+树的数据节点都是一个数据页,每个数据页默认占用16KB的磁盘空间。
- 主键的索引是由InnoDB存储引擎自动生成,即主键索引(聚簇索引)。
- 主键索引的作用:1.按照主键大小对用户记录(单向链表)和数据页(双向链表)进行排序。 2. 叶子节点保存了用户的完整记录。
- 如果用户没有设置主键,InnoDB会优先选Unique作为主键,如果连Unique也没有就自动为每一条记录添加一个看不见的DB_ROW_ID。
- 自增ID作为主键的好处:自增ID只需要添加next_record指针就能简单地实现后来插入的记录一定会排列在上一条记录的后面。而用UUID不同,大小随机,后插入的记录极大几率会插到上一条记录前面。
- 大小排列规则:Infimum(伪记录)<用户数据<Supremum(伪记录)
分组规则:
- Infimum(伪记录)单独1个组
- Supremum(伪记录)所在的分组记录条数1-8之间
- 其余分组4-8条
- 普通索引(二级索引)对单个列添加
如果数据以“name”为搜索条件。如果模拟主键索引,将用户记录按照name字段排序生成B+树,name的B+树的叶子节点的完整记录 和 主键叶子节点的完整记录就重复了。
所以思路应该是根据name字段查找主键,再根据主键查找用户记录【回表】。这里的B+树叶子节点应该只记录name列和主键列。数据页中存放的用户记录和目录项记录不再以主键排序,而是以name排序。
目录项记录除了储存索引列,页号还储存了主键值(它的排列没有规律),这是因为普通不是唯一,插入数据没法决定插入位置,有了主键值在有重复的情况下可以通过主键决定插入正确的数据页。 - 联合索引,先按column1排序在按照column2排序....联合索引需要遵守【最左匹配】原则
- 增删改记录的时候,可能会触发数据页的回收和分裂
- 在执行select语句前,MySQL查询优化器会基于Cost(成本)对一条查询记录进行优化,生成执行计划
- MySQL会尽量避免随机IO(同一个索引的叶子节点的数据页在磁盘空间中相邻的)
回表已经是比较高效的搜索方式了,但是,能不回表就不会表,必须回表就减少回表次数。
- 非主键索引的叶子节点上有所需要的是所有数据没不需要回表。索引中已经包含了所有需要读取的列数据的查询方式叫索引覆盖。
正常情况:step1: 查二级索引,step2:回表,step3: 找到的数据返回MySQL的server层。【注意:索引的使用是在存储引擎中进行的,数据记录的比较在server层】 - 索引条件下推 Index Condition Pushdown
过滤由下层存储引擎通过索引完成,而不需要上推到server层,只需要回表一次。 发挥索引的作用-避免索引失效
MySQL自动将字符串转换为数字- 索引字段类型是字符串,使用数字类型搜索不会用到索引
- 索引字段类型是数字类型,使用字符串类型搜索会用到索引
Or查询 - or之前的条件列是索引列,or之后的条件列不是索引列,不会用到索引
为合适的列创建合适的索引-索引创建原则
- 不会离散度低的列创建索引
- 只为搜索、排序或分组的列创建索引
(只为where/order by/group by字句中的列创建索引) 用好联合索引
- 不要为联合索引的第一个索引列单独创建索引
- 建立联合索引时,一定要把最常用的列放在最左边
- 对长字段创建前缀索引
- 频繁更新的列,不要作为主键或索引
- 非主键索引的叶子节点上有所需要的是所有数据没不需要回表。索引中已经包含了所有需要读取的列数据的查询方式叫索引覆盖。
SQL语句
- ISNULL 空的情况排前排后问题
- CASE WHEN ...then...WHEN...then...else替换多个if/else, end xx(将then出来的放到xx字段下)
- ORDER BY FIELD 自定义排序
- GROUP_CONCAT分组连接 SEPRARTOR分隔符 GROUP BY...
- WITH ROLLUP 相当于筛选出来的总体的sum
- WITH xx AS, xx AS 提取子查询
插入/更新,唯一键重复问题
- INSERT IGNORE INTO
- REPLACE INTO
- INSERT INTO....on duplicate key update
数据库备份
逻辑备份
mysqldump命令是把数据的执行SQL进行导出,导出的数据以sql文件的形式存储。# 查看表的创建语句(不相关) SHOW CREATE TABLE xx; # -B = --database 指定备份某一个、某几个库 # > 重定向到某个位置 mysqldump -u用户名 -p密码 -B xx yy zz > /xx/yy/zz/mm.sql ls /xx/yy/zz/mm.sql -lh vim /xx/yy/zz/mm.sql grep -Ev '#|\*|--|^$' /xx/yy/zz/mm.sql
观察导出的sql文件
# 新的数据库环境必须得有mm库。否则第一句USE就报错了
USE 'mm';
# 先删除再创建,锁表再插入
DROP TABLE IF EXISTS 'xx';
CREATE TABLE 'xx';
LOCK TABLES 'xx' WRITE;
INSERT INTO 'xx' VALUES(......
UNLOCK TABLES;
海量数据的备份,mysqldump逻辑备份就不适用
Mysqldump备份方案
- 指定db,table备份,对存储的sql数据进行压缩,节省磁盘空间
mysqldump -u用户名 -p密码 -S 连接信息 -B 指定的库 |gzip > /xx/yy/zz/库_库.sql.gz
- 分库、分表备份(shell脚本开发,已经做好了分库分表的备份)
- 备份单个table、备份多个table
- 只要table结构,不要数据(新机器)
- 只有table数据,不要接口
其实,这些都是通过mysqldump的各种选项提供好的功能,进行备份
部署服务器相关
单独放在了另一篇文章中:
https://segmentfault.com/a/1190000044771293
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。