谷粒学院(一)


根据 尚硅谷 的谷粒学院项目所做笔记 仅供参考

概述

1.介绍项目的背景

这是一个在线教育系统,项目背景 找度娘

2.介绍项目采用的商业模式

B2C模式(Business To Customer 会员模式)

​ 两个角色: 管理员 和 普通用户

​ 管理员: 添加 修改 删除

​ 普通用户: 查询

​ 在线教育系统使用这种模式,核型模块-> 课程模块

B2B2C

​ 例如 京东: 普通用户 可以买到 自营, 也可以买到 普通商家

3.介绍项目实现的功能模块

B2C模式:

系统后台: 管理员使用

  • 讲师管理模块
  • 课程分类管理模块
  • 课程管理模块
    • 视频
  • 统计分析模块
  • 订单管理
  • banner管理
  • 权限管理

系统前台 : 普通用户使用

  • 首页数据展示
  • 讲师列表和详情
  • 课程列表和课程详情
    • 视频在线播放
  • 登录和注册功能
  • 微信扫描登录
  • 微信扫描支付

4.介绍项目使用的技术

项目使用 前后端分离开发

后端技术

​ springboot springcloud MybatisPlus spring security

​ redis maven easyExcel jwt OAuth2

前端技术

​ vue + element-ui + axios + node.js

其他技术

​ 阿里云oss 阿里云视频点播服务 阿里云短信服务

​ 微信支付 docker git jenkins

5.学习技术-MybatisPlus

Mybatis-Plus 牛刀小试

(1)创建一个springboot项目(这个会的都会)

​ 最重要的一步,配置properties配置文件

# 配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=UTF8
spring.datasource.username=root
spring.datasource.password=034312

# mybatis 输出日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

(2)导包:主要是 mybatis-plus-boot-startervelocity-engine-core

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
<build>
    <!-- 插件管理 -->
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.5</version>
        </plugin>
    </plugins>
    <!-- 资源管理 -->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.conf</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.conf</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

(3)创建domain

@Data
public class Student {
    private Integer sid;
    private String name;
    private String age;
}

(4)创建mapper

@Repository
public interface StudentMapper extends BaseMapper<Student> {

}

记得在启动类上加上 @MapperScan 注解 哦

@SpringBootApplication
@MapperScan("com.zhj.mapper")
public class MpPracticeApplication {
    public static void main(String[] args) {
        SpringApplication.run(MpPracticeApplication.class, args);
    }
}

(5)测试

在生成springboot项目时 会生成一个测试类 做一下简单测试

@SpringBootTest
class MpPracticeApplicationTests {
    @Autowired
    private StudentMapper studentMapper;
    @Test
    void contextLoads() {
        List<Student> students = studentMapper.selectList(null);
        System.out.println(students);
    }
}
Mybatis-Plus 之insert
@Test
void add(){
    Student student = new Student();
    student.setName("mmm");
    student.setAge(13);
    int insert = studentMapper.insert(student);
    System.out.println(insert); // 返回影响的行数
}

默认主键策略 采用的使用 Mybatis-Plus 自带的增长策略

几种常见的主键策略:

  • 自动增长策略(msql中设置auto_increment,但是不利于分库分表)
  • UUID(生成 32 唯一标识,但是无法排序)
  • redis
  • mp自带策略(根据snowflake算法,生成一串 19位数字)

可以在实体类中进行配置,例如

@Data
public class Student {
    @TableId(type = IdType.AUTO)
    private Long sid;
    private String name;
    private Integer age;
}

IdType.AUTO:自动增长

IdType.ID_WORKER: mp自带 ,Long类型

IdType.ID_WORKER_STR: mp自带,String类型

IdType.INPUT:手动输入

IdType.NONE:手动输入

IdType.UUID :随机唯一

Mybatis-Plus insert and update --> 自动填充功能

例如:domain

Data
public class User {
    @TableId(type = IdType.ID_WORKER)
    private Long id;
    private String name;
    private int age;
    private Date createTime; // 这里使用驼峰式 对应表中应该使用 下划线(create_time)的形式
    private Date updateTime;
}

中间细节如上

@Test
void addUser(){
    User user = new User();
    user.setName("lisi");
    user.setAge(14);
    user.setCreateTime(new Date());
    user.setUpdateTime(new Date());
    userMapper.insert(user);
}

每次增加,都需要自己setCreateTime setUpdateTime一个时间

解决方法:使用Mybatis-Plus 自动填充功能

  • 1.在实体类中添加注解

    @Data
    public class User {
        @TableId(type = IdType.ID_WORKER)
        private Long id;
        private String name;
        private int age;
        @TableField(fill= FieldFill.INSERT)
        private Date createTime; // 这里使用驼峰式 对应表中应该使用 下划线(create_time)的形式
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
    }
    
  • 2.创建一个类,实现MetaObjectHandler,重写两个方法,注意 加上@Component 注解

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            // 属性 , 创建时间  , 数据源对象(就是字段名)
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            this.setFieldValByName("updateTime",new Date(),metaObject);
    
        }
    }
    
  • 3.测试

    @Test
    void updateUser(){
        User user = new User();
        user.setId(1449526992241463297L);
        user.setName("李四");
        user.setAge(14);
        userMapper.updateById(user);
    }
    
乐观锁

乐观锁: 解决问题

主要解决 丢失更新问题

如果不考虑事务隔离性,产生读的问题?

​ 脏读 不可重复读 幻读

写问题: 丢失更新问题

​ 多人同时修改同一条数据,最后提交的(一个人)把之前的提交数据覆盖

乐观锁主要使用场景:当要更行一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

乐观锁的实现原理:

  • 取出记录时,获取当前versioin
  • 更新时,带上这个version
  • 执行更新时,set version = newVersion where version = oldVersion
  • 如果version 不对,就更新失败

Mybatis-Plus实现方式

  • 数据库中添加version字段

    alter table user add column version int

  • 实体类添加versioin字段

    并添加@Version注解

    @Version
    @TableField(fill=FieldFill.Insertprivate Integer version;
    
  • 元对象处理器接口添加version的insert默认值

    @Override
    public void insertFill(MetaObject metaObject) {
      	......
        // 创建一个对象默认 version = 1
        this.setFieldValByName("version",1,metaObject);
     
    }
    

    注意:这里支持的数据类型只有 int Integer long Long Date Timestamp LocalDateTime

  • 配置MybatisPlus配置类,配置乐观锁插件

    @Configuration
    @MapperScan("com.zhj.mapper")
    @EnableTransactionManagement
    public class MybatisPlusConfig {
        /*
        乐观锁插件
         */
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor (){
            return new OptimisticLockerInterceptor();
        }
    }
    
  • 测试:先查询 在修改

    /*
    乐观锁测试
     */
    @Test
    void updateUserByOptimistic(){
        // 先查询
        User user = userMapper.selectById(1449526992241463297L);
        // 在修改
        user.setAge(120);
        int i = userMapper.updateById(user);
        System.out.println(i);
        // 才能看到结果 测试 version 是否变化
    }
    
Mybatis-Plus 查询
  • 简单 id 查询

    T selectById(Serializable id);
    
  • 多个id批量查询

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
    
  • 条件查询

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
    
  • 分页查询

    实现:

    1. 配置分页插件

      /*
      分页插件
       */
      @Bean
      public MybatisPlusInterceptor mybatisPlusInterceptor() {
          MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
          interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
          return interceptor;
      }
      
    2. 测试

      /*
      分页插件测试
      */
      @Test
      void pageHelperTest(){
          // 1 创建page 对象
          Page<User> page = new Page<>(0,1);
          // 2 把分页所有数据封装到 page 中
          userMapper.selectPage(page,null);
          // 3 通过page 获取当前数据
          System.out.println("当前页:"+page.getCurrent());
          System.out.println("每页数据的list集合:"+page.getRecords());
          System.out.println("每页显示的记录数:"+page.getSize());
          System.out.println("总记录数:"+page.getTotal());
          System.out.println("总页数:"+page.getPages());
          System.out.println("是否有上一页:"+page.hasPrevious());
          System.out.println("是否有下一页:"+page.hasNext());
      }
      
Mybatis-Plus 之删除操作

物理删除: 真是删除,将对应数据从数据库中删除,之后查询不到此条被删除数据

逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后再数据库中仍旧能看到此条数据记录

  1. 物理 删除一条数据:

    int deleteById(Serializable id);
    
  2. 物理删除 批量数据:

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
    
  3. 物理删除 条件:

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);
    
  4. 逻辑删除

    第一步:添加逻辑删除字段,对应实体添加属性,属性添加@TabledLogic 注解

    @TableLogic
    @TableField(fill= FieldFill.INSERT)
    private Integer deleted;
    

    第二步:配置逻辑删除插件

    mybatis plus高版本不需要配置注入逻辑删除 ,不需要配置逻辑删除插件

    /*
    逻辑删除插件
     */
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
    

    第三步(可以省略):

    ​ 此为默认值,如果你的默认值和 mp 默认的一样 , 该配置可无

    mybatis-plus.global-config.db-config.logic-delete-value=1
    mybatis-plus.global-config.db-config.logic-not-delete-value=0
    

    第四步:使用 同物理删除同样的方法 进行测试

    @Test
    void deleteByLogic(){
        int i = userMapper.deleteById(5L);
        System.out.println(i);
    }
    

    如果是高版本的 ,只需要配置 第一、四步

    Mybatis-Plus默认为物理删除,通过配置 @TableLogic 之后 就会变为逻辑删除

性能分析

性能分析拦截器,用于输出每条SQL语句及其执行时间

SQL性能执行分析,开发环境使用,超过指定时间 ,停止运行,有助于发现问题

插件功能:该功能依赖 p6spy 组件,完美的输出打印 SQL 及执行时长, 3.1.0 以上版本支持

添加依赖:

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.1</version>
</dependency>

配置:

  1. 修改配置:application.properties在MybatisPlusConfig中配置

    #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    #spring.datasource.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=UTF8
    #spring.datasource.username=root
    #spring.datasource.password=034312
    spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
    spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/ssm?characterEncoding=UTF8
    spring.datasource.username=root
    spring.datasource.password=034312
    
  2. 创建properties文件配置:spy.properties

    # 3.2.1以上使用
    modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
    # 自定义日志打印
    logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
    # 日志输出到控制台
    appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
    # 使用日志系统记录 sql
    #appender=com.p6spy.engine.spy.appender.Slf4JLogger
    # 设置 p6spy driver 代理
    deregisterdrivers=true
    # 取消JDBC URL前缀
    useprefix=true
    # 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
    excludecategories=info,debug,result,commit,resultset
    # 日期格式
    dateformat=yyyy-MM-dd HH:mm:ss
    # 实际驱动可多个
    driverlist=com.mysql.jdbc.Driver
    # 是否开启慢SQL记录
    outagedetection=true
    # 慢SQL记录标准 2 秒
    outagedetectioninterval=2
    
    

    注意问题

    • driver-class-name 为 p6spy 提供的驱动类
    • url 前缀为 jdbc:p6spy 跟着冒号为对应数据库连接地址
    • 打印出sql为null,在excludecategories增加commit
    • 批量操作不打印sql,去除excludecategories中的batch
    • 批量操作打印重复的问题请使用MybatisPlusLogFactory (3.2.1新增)
    • 该插件有性能损耗,不建议生产环境使用
  3. 然后就可以 查看到 输出 sql 执行时间里哦

复杂查询操作

通过创建QueryWrapper 对象操作

主要操作有 : ge ,gt,le,lt,eq,ne,between,like,orderByDesc,last,指定查询的列

例如:

@Test
void selectUser(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.select("name").eq("age",15);
    List<User> userList = userMapper.selectList(wrapper);
    userList.forEach(System.out::println);
}

详情: https://caochenlei.blog.csdn.net/article/details/108809902

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值