文章目录
1 项目介绍
- Java基础 -> Mysql JDBC -> JavaWeb -> SSM -> Java高级(Redis Nginx idea maven git spring boot)-> 在线教育项目
2 项目商业模式
- B2C ——两个角色
- 管理员:添加、修改、删除
- 普通用户:查询
- B2B2C
- 京东:普通用户,可以买自营,可以买普通商家
3 项目功能模块——B2C
- 系统后台——管理员使用
- 讲师管理模块
- 课程分类管理模块
- 课程管理模块
- 视频
- 统计分析模块
- 订单管理模块
- banner管理模块
- 权限管理模块
- 系统前台——普通用户使用
- 首页数据显示
- 讲师列表和详情
- 课程列表和详情
- 视频在线播放
- 登录和注册功能
- 微信扫码登录功能
- 微信扫码支付功能
4 项目技术点——前后端分离
- 后端
- Spring Boot
- Spring Cloud
- MybatisPlus
- Spring security
- redis、maven、easyExcel、jwt、OAuth2
- 前端
- vue+element-ui+axios+nodejs
- 其他技术
- 阿里云oss、阿里云视频点播服务、阿里云短信服务
- 微信支付和登录、docker、git、jenkins
5 MybatisPlus
- 对mybatis做增强,简化开发
- 1 创建数据库,创建数据表,添加数据,用于mp操作
- 2 创建spring boot工程
- 3 引入相关依赖 spring boot、mp
- 4 安装loombok插件
- 5 配置application.properties
- 6 编写代码
6 mp添加操作
- 不需要设置id(主键),mp自动设置(19位的id值)
- 主键策略
- 自动增长——auto increment
- 分表
- UUID——每次生成唯一的值
- 缺点:无法排序
- 优点:不需要关注上次的值
- redis——原子操作(用的多)
- mp自带——19位id值
- snowflake算法
- 自动增长——auto increment
@TableId(type = IdType.AUTO)
AUTO 自动增长
ID_WORKER mp自带,生成19位值,数字类型使用,比如long
ID_WORKER_STR mp自带,生成19位值,字符串类型使用 如果不写mp自动识别
INPUT 设置id值
NONE 输入
UUID
7 mp修改操作
-
自动填充
-
1 表添加两个字段 create_time update_time
-
2 添加实体类的属性(驼峰式命名)
-
特点:不需要set到对象里面值,使用mp方式实现数据添加
-
实现过程
-
1 实体类里面进行自动填充属性添加注解
@TableField(fill = FieldFill.INSERT)
-
2 创建类,实现接口MetaObjectHandler中的方法
-
-
-
乐观锁——解决某些问题
-
面试:默认在任何情况的操作影响下,都不会影响该操作,这就是乐观锁
-
主要解决:丢失更新
-
事务
-
如果不考虑事务隔离性,会产生读的问题
- 脏读
- 不可重复读
- 幻读
-
写的问题:丢失更新问题
-
-
丢失更新
- 多个人同时修改同一条记录,最后提交的把之前提交的数据覆盖
- 解决方案:
- 悲观锁:串行
- 乐观锁:version
- 比较当前数据版本和数据库版本是否一样,并把版本号+1;否则不能修改
- 实际场景:12306抢票
-
-
具体实现
-
1 添加字段,作为乐观锁版本号
version
-
2 对应实体类添加版本号属性
-
3 在实体类版本号属性添加注解
@Version
-
4 配置乐观锁插件
@Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }
-
8 mp简单查询
-
根据id查询
User user = userMapper.selectById(1545597328998600706L);
-
多个id批量查询
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
-
map查询
@Test public void testSelectByMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name", "mys1"); map.put("age", "20"); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
9 mp分页查询
PageHelper类似
- 1 配置分页插件
- 2 编写分页代码
- new Page对象,传入两个参数,当前页和每页显示记录数,调用mp方法实现分页查询
@Test
public void testPage() {
// 1. 创建page对象
Page<User> page = new Page<>(1, 3); // 当前页 每页记录总数
// 2.调用mp分页查询的方法
// mp分页查询,底层将所有分页数据封装袋page对象中
userMapper.selectPage(page, null);
// 3. 通过page对象获取分页数据
System.out.println(page.getCurrent()); // 当前页
System.out.println(page.getRecords()); // 每页数据list集合
System.out.println(page.getSize()); // 每页显示记录数
System.out.println(page.getTotal()); // 总记录数
System.out.println(page.getPages()); // 总页数
System.out.println(page.hasNext()); // 是否有下一页
System.out.println(page.hasPrevious()); // 是否有上一页
}
10 mp删除
-
物理删除
// 1 根据id删除 int result = userMapper.deleteById(1544514803538624514L); // 2 批量删除 int result = userMapper.deleteBatchIds(Arrays.asList(1, 2)); // 3 map查询删除 HashMap<String, Object> map = new HashMap<>(); map.put("name", "mys3"); map.put("age", 20); int result = userMapper.deleteByMap(map);
-
逻辑删除
- 1 表添加逻辑删除字段,对应实体类添加属性 deleted
@TableLogic
- 2 配置逻辑删除插件
- 1 表添加逻辑删除字段,对应实体类添加属性 deleted
11 mp性能分析
/**
* SQL执行性能分析插件
* 开发环境使用,线上不推荐,maxTime是sql最大执行时间
* 三种环境:
* dev 开发环境
* test 测试环境
* prod 生产环境
*/
@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100); // ms
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
12 mp复杂条件查询
-
1 创建QueryWrapper对象
-
2 通过QueryWrapper设置条件值
13 代码汇总
entity.User
@Data
public class User {
// @TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
// 版本号
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
// 逻辑删除
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
}
handler.MyMetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 使用mp实现添加操作,方法执行
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("version", 1, metaObject);
this.setFieldValByName("deleted", 0, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
config.MpConfig
@Configuration
@MapperScan("com.mys.mpdemo1010.mapper")
public class MpConfig {
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/**
* 逻辑删除插件
*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
}
application.properties
# mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=xxx
# mybatis-plus.global-config.db-config.logic-delete-value=1
# mybatis-plus.global-config.db-config.logic-not-delete-value=0
# mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 环境设置
spring.profiles.active=dev
test.Mpdemo1010ApplicationTests
@SpringBootTest
public class Mpdemo1010ApplicationTests {
@Autowired
private UserMapper userMapper;
// 查询user表所有
@Test
public void findAll() {
List<User> users = userMapper.selectList(null);
System.out.println(users);
}
// 添加
@Test
public void addUser() {
User user = new User();
user.setName("mys4");
user.setAge(20);
user.setEmail("mys@163.com");
int insert = userMapper.insert(user);
System.out.println("insert" + insert);
}
// 修改
@Test
public void updateUser() {
User user = new User();
user.setId(1544514803538624514L);
user.setAge(30);
int row = userMapper.updateById(user);
System.out.println(row);
}
// 测试乐观锁
@Test
public void testOptimisticLocker() {
// 根据id先查询数据
User user = userMapper.selectById(1545597328998600706L);
// 进行修改
user.setAge(200);
userMapper.updateById(user);
}
// 多个id批量查询
@Test
public void testSelectDemo1() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
System.out.println(users);
}
// map查询
@Test
public void testSelectByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "mys1");
map.put("age", "20");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
// 分页查询
@Test
public void testPage() {
// 1. 创建page对象
Page<User> page = new Page<>(1, 3); // 当前页 每页记录总数
// 2.调用mp分页查询的方法
// mp分页查询,底层将所有分页数据封装袋page对象中
userMapper.selectPage(page, null);
// 3. 通过page对象获取分页数据
System.out.println(page.getCurrent()); // 当前页
System.out.println(page.getRecords()); // 每页数据list集合
System.out.println(page.getSize()); // 每页显示记录数
System.out.println(page.getTotal()); // 总记录数
System.out.println(page.getPages()); // 总页数
System.out.println(page.hasNext()); // 是否有下一页
System.out.println(page.hasPrevious()); // 是否有上一页
}
// 删除:物理删除
@Test
public void testDeleteById() {
int result = userMapper.deleteById(1544514803538624514L);
System.out.println(result); // result:影响行数
}
// 删除:批量删除
@Test
public void testDeleteBatchIds() {
int result = userMapper.deleteBatchIds(Arrays.asList(1, 2));
System.out.println(result);
}
// 删除:条件查询删除
@Test
public void testDeleteByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "mys3");
map.put("age", 20);
int result = userMapper.deleteByMap(map);
System.out.println(result);
}
// 删除:逻辑删除
@Test
public void testLogicDelete() {
int result = userMapper.deleteById(1545615823438094338L);
System.out.println(result);
}
// mp复杂查询
@Test
public void testSelectQuery() {
// 1.创建对象
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 2.通过QueryWrapper设置条件值
// ge gt le lt : >= > <= <
// 查询age>30
wrapper.ge("age", 30);
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
// eq ne : = !=/<>
// between : 范围
// like : 模糊查询
// orderByDesc : 排序
// last : 语句最后拼接sql语句
// select : 指定要查询的列
}
}
14 老师笔记与资料链接
-
笔记
https://wwn.lanzouf.com/iaK4N07l920f 密码:dxxt
-
资料
链接:https://pan.baidu.com/s/1rG4dHX1UMrQso0WpmKrmwQ?pwd=wx4s
提取码:wx4s
(如果失效可以私信我)