谷粒学院开发(一):基础准备
商业模式
常见商业模式
-
B2C模式:
两个角色:
- 管理员:增加,修改,删除
- 普通用户:查询
商家到用户,自己制作大量自有版权的视频,放在自有平台上,让用户付费。
这是这个项目使用的模式
核心模块:课程模块
-
B2B2C模式:
商家到商家到用户,平台连接第三方教育机构,平台一般不直接提供课程内容。
比如京东,很多的电商平台都是这种模式。
项目模块
分成两个系统进行开发
-
系统后台
管理员使用
- 讲师管理模块
- 课程分类管理模块
- 课程管理模块
- 视频
- 统计分析模块
- 订单管理
- banner管理
- 权限管理
-
系统前台
普通用户使用
- 首页数据的显示
- 讲师列表和详情
- 课程列表和详情
- 视频在线播放
- 登录和注册
- 微信扫码登录
- 微信扫码支付
项目技术点
采用前后端分离开发
-
后端技术
SpringBoot
SpringCloud
MybatisPlus
Spring Security
-
前端技术
vue + element ui + axios + node.js …
-
其他技术
阿里云oss
阿里云视频点播服务
阿里云短信服务
微信支付和登录
docker
git
jenkins
Mybatis Plus
-
创建数据库,创建数据库表
添加数据用于MP操作
DROP TABLE IF EXISTS user;CREATE TABLE USER(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id) );DELETE FROM user;INSERT INTO user (id,name,age,email) VALUES (1, 'Jone', 18, 'test1@test.com'), (2, 'Jack', 20, 'test2@test.com'), (3, 'Tom', 28, 'test3@test.com'), (4, 'Sandy', 21, 'test4@test.com'), (5, 'Billie', 24, 'test5@test.com'); -
使用Idea 创建一个Spring Boot工程
-
引入相关依赖
springboot和mp
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</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.0.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies> -
在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=xxxxxxx -
编写代码测试
配置日志
查看sql输出日志
# mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
测试Mybatis的添加操作
@Test
void addUser() {User user = new User();user.setName("lucy");user.setAge(30);user.setEmail("lucy@qq.com");int insert = userMapper.insert(user);System.out.println("insert: "+insert);
}
在这里没有手动设置id,但是MP会自动生成。

主键生成策略
-
自动增长 AUTO INCREMENT
分表时,会像下面这样分配每张表的id,所以创建新的表的时候需要知道上一张表最后一个项目的id

-
UUID 一个生成的随机的值
不好进行排序
-
用Redis实现

-
MP自带策略,19位,使用雪花算法生成的
如何使用这些主键策略

AUTO: 自动增长
ID_WORKER: MP自带的策略,生成19位的值,数字类型使用这种策略
ID_WORKER_STR:也是MP自带的策略,生成19位值,字符串类型使用这种策略
INPUT: 需要我们自己设置id
NONE: 没有策略,也需要自己设置
UUID: 每次生成一个UUID
@TableId(type=IdType.AUTO)
private Long id
增删改查其他操作
mp实现修改操作
@Test
void updateUser() {User user = new User();user.setId(2L);user.setAge(120);int i = userMapper.updateById(user);System.out.println(i);
}
自动填充
- 表中添加两个字段
create_time update_time - 添加实体类属性
注意属性需要驼峰命名法 - 设置自动填充
- 可以在
addUser()的时候手动传值

- 可以使用MP来做到
- 可以在
MP自动填充具体实现过程
-
在实体类里面需要自动填充的属性上添加注解
@TableField(fill = FieldFill.INSERT) private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;FieldFill.INSERT表示在执行插入的时候自动填充这个字段 -
自己创建类,实现
METAObjectHandler接口,实现接口里面的方法@Component // 一定注意交给Spring容器管理 public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) { // 填充操作时会执行this.setFieldValByName("createTime", new Date(), metaObject);this.setFieldValByName("updateTime", new Date(), metaObject);}@Overridepublic void updateFill(MetaObject metaObject) { // 更新操作时会执行this.setFieldValByName("updateTime", new Date(), metaObject);} }
乐观锁
主要解决:丢失更新问题
如果不考虑事务隔离性,会产生读问题?
- 脏读
- 不可重复读
- 幻读/虚读
不考虑隔离性,产生写问题:丢失更新问题。
丢失更新问题
上面的过程中,mary原本是想修改数据500,可最后修改了数据8000,这就导致了lucy的数据更新被覆盖了。
多人同时修改一条记录,最后一个提交的人会把前面提交的更新覆盖。
解决方案:
- 悲观锁
把所有的操作变成串行操作。lucy开启事务之后,mary无法开启事务。有可能影响性能。 - 乐观锁
在表中加上一个字段 version ,开始事务时获取这条记录的 version ,提交修改的时候比较刚开始获取的 version 和当前数据库中这条记录的 version,如果一样的话,提交修改,并将版本号加一;如果不一样的话就取消当前的修改。
在代码中使用乐观锁
-
在数据库表中添加version字段
-
对应的实体类添加版本号属性
-
在实体类的属性上添加注解
@Version private Integer version; // 版本号 -
配置乐观锁插件 (建议写到配置类里面)
@Configuration // 注解表示这是一个配置类 public class MPConfig {/** 乐观锁插件,这个插件是固定的,直接复制就可以了* */@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();} } -
编写代码测试
@Test void testLock() { // 因为乐观锁的存在,所以一定要先查再改// 通过id查询数据User user = userMapper.selectById(1633278798692634625L);// 1633278798692634625user.setAge(200);userMapper.updateById(user); }
MP简单查询
-
根据id查询
// 根据id查询数据 User user = userMapper.selectById(); -
多个id的批量查询
@Test void testSelectBench() {List<Integer> integers = Arrays.asList(1, 2, 3);List<User> users = userMapper.selectBatchIds(integers);users.forEach(System.out::println); } -
简单的条件查询
@Test void testSelectByMap() { // 这种不经常使用HashMap<String, Object> map = new HashMap<>();map.put("name", "mary");map.put("age", 30);List<User> users = userMapper.selectByMap(map);for (User user : users) {System.out.println(user);} } -
分页查询 (和PageHelper差不多)
-
配置分页插件
@Bean // 也是在配置类里面进行的 public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor(); } -
编写分页代码
直接new page对象,传入两个参数,当前页和每页显示的记录数@Test void testPage() {// 创建page对象,传入参数: 当前页 和 每页小时的记录数Page<User> userPage = new Page<>(1, 3);// 调用MP中分页查询的方法// 调用MP分页查询过程中,会把查出来的数据封装到page对象里面userMapper.selectPage(userPage, null);System.out.println(userPage.getCurrent()); // 获取当前页System.out.println(userPage.getRecords()); // 每页数据list集合System.out.println(userPage.getSize()); // 每页的记录数System.out.println(userPage.getTotal()); // 表中总记录数System.out.println(userPage.getPages()); // 得到总页数System.out.println(userPage.hasNext()); // 是否有下一页System.out.println(userPage.hasPrevious()); // 是否有上一页 }
-
删除
- 逻辑删除:假删除,在表中还存在,但是查询查不出来了,设置是否被删除字段来实现。
- 物理删除:真删除,将对应数据从数据库中删除。
物理删除
-
通过id删除
@Test void testDeleteByID() {int row = userMapper.deleteById(1L);System.out.println(row); } -
批量删除
@Test void testDeleteBatchIds() {int row = userMapper.deleteBatchIds(Arrays.asList(2, 3));System.out.println(row); } -
简单条件删除
@Test void testDeleteByMap() {HashMap<String, Object> map = new HashMap<>();map.put("age", 18);int i = userMapper.deleteByMap(map);System.out.println(i); }
逻辑删除
-
在数据库中添加 deleted 字段
-
实体类添加 deleted 字段
加上注解@TableLogic和TableField(fill = FieldFill.INSERT)@TableLogic @TableField(fill = FieldFill.INSERT) private Integer deleted; -
配置类中配置逻辑删除插件
@Bean public ISqlInjector sqlInjector() {return new LogicSqlInjector(); }mybatis-plus.global-config.db-config.logic-delete-value=1 # 也可以在这里配置删除后是什么1,不删除是什么值 mybatis-plus.global-config.db-config.logic-not-delete-value=0 -
要删除的时候还是执行之前的删除方法,但是效果就变成了把 deleted 字段变成1,使用MP查询的时候我们也不需要加额外的条件,MP会自动加上 deleted 不为1这个条件。
-
如果想要查询被删除的记录的话,MP没有办法做到,只能通过新建 xml 文件,手写slq来实现。
性能分析
-
在配置类中配置性能分析插件
/* * SQL执行性能分析插件 * 开发环境使用,线上不推荐。MaxTime是指sql最大运行时长 * * 环境一般有三种: * dev: 开发环境 * test: 测试环境 * prod: 生产环境, 用户真正去使用的 * */ @Bean @Profile({"dev", "test"}) public PerformanceInterceptor performanceInterceptor() {PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();performanceInterceptor.setMaxTime(100); // ms, 超过这个时间的sql不执行performanceInterceptor.setFormat(true);return performanceInterceptor; } -
在配置文件中设置 SpringBoot当前环境
测试
运行代码的时候会在输出窗口看到sql的运行时长。

如果sql运行时间超过MaxTime的话,就会抛出一个异常。

复杂条件查询
条件查询器

一般使用 QueryWrapper 来构件条件
- 创建QueryWrapper对象
- 添加条件
@Test
void testSelectQuery() {// 创建QueryWrapper对象QueryWrapper<User> wrapper = new QueryWrapper<>();// 通过QueryWrapper设置条件// ge, gt, le, lt// 查询age >= 30 的记录// 第一个参数是列名, 第二个参数是值
// wrapper.ge("age", 30);// eq, ne
// wrapper.eq("name", "东方不败");
// wrapper.ne("name", "东方不败");// between
// wrapper.between("age", 20, 30);// like 模糊查询
// wrapper.like("name", "东");// orderByDesc, 排序
// wrapper.orderByDesc("id");// last, 拼接sql语句
// wrapper.last("limit 1");// 指定要查询的列wrapper.select("id", "name");List<User> users = userMapper.selectList(wrapper);System.out.println(users);}
相关文章:
谷粒学院开发(一):基础准备
商业模式 常见商业模式 B2C模式: 两个角色: 管理员:增加,修改,删除普通用户:查询 商家到用户,自己制作大量自有版权的视频,放在自有平台上,让用户付费。 这是这个项目使…...
Photoshop如何安装ZXP扩展插件?
Photoshop如何安装ZXP扩展插件呢?有一些小伙伴不会安装,今天介绍两种安装ZXP扩展的方法,希望对能帮助到大家。方法一:手动安装方式1)把下载好的.zxp扩展名改为.zip,然后解压。Windows系统:C:\Us…...
c++面试技巧-基础篇4
1.面试官:在使用继承时需要注意哪些问题? 应聘者:在使用继承时需要注意以下内容。 (1)父类的构造函数和析构函数是不会被继承的,需要重写派生类的构造函数和析构函数。 (2)派生类…...
openEuler用户软件仓(EUR)介绍
什么是 EUR EUR(openEuler User Repo)是openEuler社区针对开发者推出的个人软件包托管平台,目的在于为开发者提供一个易用的软件包分发平台。 链接:https://eur.openeuler.openatom.cn/ 为什么我们需要 EUR 在操作系统的世界,软件包是一等…...
MySQL的图形化界面开发工具DataGrip的下载安装
在日常的开发中,会借助于MySQL的图形化界面,来简化开发,提高开发效率。目前mysql主流的图形化界面工具,有Navicat、SQLyog、DataGrip等,最后一种DataGrip,这种图形化界面工具,功能更加强大&…...
Azure Portal 访问安全性增强
Azure Portal 访问安全性增强客户需求如何设置账号(包括Admin)定期修改密码,例如强制每90天必须修改密码如何设定账号密码的复杂性要求如何设定限制访问Azure Portal的源IP Address客户需求 为了增强访问Azure Portal的安全性,希…...
mysql安全值守数据库常用语句
目录1.用户权限设置mysql中用户如何定义2.元数据查询3.union查询详解4.分组查询展示5.字符串函数6.mysql数据库导入导出1.用户权限设置 mysql中用户如何定义 用户名主机域有以下几种表示方式: 1. 10.0.0.51 2. 10.0.0.% 3. % 4. 10.0.0.0/255.255.255.0 5. Db01 6…...
CSS快速入门
文章目录一、CSS是什么?语法规范引入方式二、CSS选择器标签选择器类选择器ID选择器通配符选择器后代选择器子选择器并集选择器伪类选择器三、常见元素属性字体属性文本属性背景属性圆角矩形元素的显示默认块级与行级元素盒子模式去除浏览器默认样式弹性布局一、CSS是…...
emq-docker安装配置
目录 1 docker配置 2 mysql 认证 2.1 添加认证表 2.2 认证文件配置 3 系统topic docker安装;mysql客户端认证;配置系统topic 获取客户端上下线消息。文件提到配置文件见附件。 1 docker配置 docker镜像地址:emqx/emqx emqx_auth_mysql.…...
Bean三种实例化方式的底层原理
Bean实例化的三种方式 1,使用类构造器实例化(无参构造函数)2,使用静态工厂方法实例化(简单工厂模式)3,使用实例工厂方法实例化(工厂方法模式) 基于以上的三种方式&…...
java25种设计模式之适配器模式
1、定义 适配器模式在java中是一中结构型设计模式。 在实际的java来发中,有时候我们会遇到一些不能直接调用,或者不是客户需要的接口,但是却需要使用时,我们就可以使用适配器设计模式。 适配器设计模式就是将一个原本不兼容的接口…...
【微服务】—— 初识微服务
文章目录1. 什么是微服务1.1 微服务的特性自主专用性1.2 微服务的优势敏捷性灵活扩展轻松部署技术自由可重复使用的代码弹性2. 微服务技术栈3. 微服务架构演进3.1 单体架构3.2 分布式架构服务治理3.3 微服务微服务结构微服务技术对比企业需求1. 什么是微服务 微服务是一种开发软…...
Unity使用webSocket与服务器通信(二)——C#服务器端使用Fleck时的简单服用方法
C#服务端用到Fleck包,它包含哪些可用的回调函数,有哪些常用的api方法? 演示:服务端收到Unity用户发来的信息 1、Fleck服务器提供哪些回调函数 Fleck提供的回调函数有下面几种: //用户连入服务器时... Action OnOp…...
【Linux】线程概念 | 线程控制
🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉知识补充&…...
pocsuite3安装及使用
pocsuite3安装及使用简介项目地址环境配置及安装环境要求安装(详情可以参考[https://pocsuite.org/](https://pocsuite.org/))使用方法运行模块加载目标参数:Console模式查看有哪些模块使用Telnet 弱密码模块这里以flask模板注入漏洞为例pocs…...
docker从安装到部署一个项目
一.centos安装docker 参考博客:https://blog.csdn.net/m0_47010003/article/details/127775185 1.设置一下下载Docker的镜像源 设置下载的镜像源为国内的阿里云,如果不设置,会默认去Docker的官方下载 yum-config-manager --add-repo http…...
QT编程从入门到精通之十二:“第四章:Qt程序创建基础”之“4.1 创建基础程序”
目录 第四章:Qt程序创建基础 4.1 创建基础程序 4.1.1 新建一个项目...
黑客入门教程【非常详细】从零基础入门到精通,看这一篇就够了!
首先要明白啊,我们现在说的黑客不是那种窃取别人信息、攻击别人系统的黑客,说的是调试和分析计算机安全系统的网络安全工程师。 黑客技术的核心就是渗透攻防技术,是为了证明网络防御按照预期计划正常运行而提供的一种机制。就是通过模拟恶意…...
手机怎么远程控制腾讯云云服务器?
手机怎么远程控制腾讯云云服务器?腾讯云提供的连接:Windows系统。可以用远程桌面连接,你本地电脑点击,开始-运行-输入mstsc,弹出的框里,填IP和账号密码信息。 管理服务器上还会运行一个数据采集程序&#…...
dorcker与vlu靶场搭建
dorcker与vlu靶场搭建 dorcker安装 以kali linux 为例 安装必要的一些系统工具 apt update apt -y install apt-transport-https ca-certificates curl software-properties-common 添加Docker PGP key curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg …...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
CTF show 数学不及格
拿到题目先查一下壳,看一下信息 发现是一个ELF文件,64位的 用IDA Pro 64 打开这个文件 然后点击F5进行伪代码转换 可以看到有五个if判断,第一个argc ! 5这个判断并没有起太大作用,主要是下面四个if判断 根据题目…...
【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...
深入理解 C++ 左值右值、std::move 与函数重载中的参数传递
在 C 编程中,左值和右值的概念以及std::move的使用,常常让开发者感到困惑。特别是在函数重载场景下,如何合理利用这些特性来优化代码性能、确保语义正确,更是一个值得深入探讨的话题。 在开始之前,先提出几个问题&…...
