在线教育-谷粒学院学习笔记(一)

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算法
@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 配置逻辑删除插件
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
    (如果失效可以私信我)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值