部署环境说明:
服务器:
192.168.66.100(服务器A)
nginx:部署前端项目、配置反向代理
Mysql:主从复制结构中的主库
192.168.66.101(服务器B)
jdk:运行Java项目
git:版本控制工具
maven:项目构建工具
jar:SpringBoot项目打包成jar包基于内置Tomcat运行
Mysql:主从复制结构中的从库
192.168.66.100(服务器C)
Redis:缓存中间件
配置完记得nginx -s reload 一下,然后再访问就可以了
Swagger注解:
1、@Api:用在请求的类上,例如Controller,表示对类的说明
2、@ApiModel:用在类上,通常是实体类,表示一个返回响应数据的信息
3、@ApiModelProperty:用在属性上,描述响应类的属性
4、@ApiOperation:用在请求方法上,说明方法的用途、作用
5、@ApilmplicitParams:用在请求的方法上,表示一组参数说明
6、@ApilmplicitParam:用在@ApilmplicitParams注解中,指定一个请求参数的各个方面
MVCC:
全称Multi-Vwesion Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。
当前读:
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select…lock in share mode (共享锁),select…for update、insert、delete(排他锁)都是一种当前读
快照读:
简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
- Read Committed:每次select,都生成一个快照读。
- Repeatable Read:开启事务后第一个select语句才是快照读的地方。
- Serializable:快照读会退化为当前读。
MVCC实现原理:
记录中的隐藏字段:
- DB_TRX_ID:最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。
- DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
- DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。如果有主键,那么将没有这个字段
id | age | name |
---|---|---|
1 | 1 | tom |
3 | 3 | cat |
实际上是:
id | age | name | DB_TRX_ID | DB_ROLL_PTR | DB_ROW_ID |
---|---|---|---|---|---|
undo log:
- 回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
- 当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除
- 而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除
undo log版本链条:
不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链条,链条的头部是最新的旧纪录,链表尾部是最早的旧纪录。
readview:
- Readview(读视图)是快照读SQL执行是MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。
- ReadView中包含了四个核心字段:
- m_ids:当前活跃的事务ID集合
- min_trx_id:最小活跃事务ID
- max_trx_id:预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
- creator_trx_id:ReadView创建者的事务ID
版本链数据访问规则:
trx_id:代表是当前事务ID
- trx_id creator_trx_id ? :可以访问该版本->成立,说明数据是当前这个事务更改的
- trx_id < min_trx_id ? :可以访问该版本->成立,说明数据已经提交了
- trx_id max_trx_id ? :不可以访问该版本->成立,说明该事务是在ReadView生成后才开启
- min_trx_id <= trx_id <= max_trx_id ? :如果trx_id不再m_ids中是可以访问该版本的->成立,说明数据已经提交
不同的隔离级别,生成的ReadView的时机不同:
- READ COMMITTED :在事务中每一次执行快照读时生成ReadView。
- REPEATABLE READ:仅在事务中第一次执行快照读时产生ReadView,后续复用该ReadView。
MybatisPlus:
- 新增:int insert(T t)
- 删除:int deleteById(Serializable id)
- 修改:int updateById(T t)
- 根据id查询:T selectById(Serializable id)
- 查询全部:List
selectList() - 分页查询:IPage
selectPage(IPage page) - 按条件查询:IPage
selectPage(Wrapper queryWrapper)
lombok:
常用注解:
- @Getter/@Setter:为所有属性提供get/set方法
- @ToString:会给类自动生成易阅读的toString方法
- @EqualsAndHashCode:根据类所拥有的非静态字段自动重写equals方法和hashCode方法
- @Data:提供了更综合的生成代码功能(@Getter+@Setter+@ToString+@EqualsAndHashCode)
- @NoArgsConstructor:为实体类生成无参的构造方法
- @AllArgsConstructor:为实体类生成除了static修饰的字段之外有各参数的构造器方法
分页查询:
配置分页查询bean:
--------------------------------------------
MpConfig.java
@Configuration
public class MpConfig{
@Bean
public MybatisPlusInterceptor mpInterceptor(){
//1、定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2、添加具体拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mpInterceptor;
}
}
--------------------------------------------
void testGetByPage(){
Ipage page = new Page(1,2); //Page(current:1,size:2)
userDao.selectPage(page,null);
System.out.pringtln("当前页码值:"+page.getCurrent());
System.out.pringtln("每页显示数:"+page.getSize());
System.out.pringtln("一共多少页:"+page.getPages());
System.out.pringtln("一共多少条数据:"+page.getTotal());
System.out.pringtln("数据:"+page.getRecords());
}
--------------------------------------------
调日志:
application.yml
#开启mp的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
--------------------------------------------