0、视频地址

视频地址

1、 项目下载

谷粒项目
链接:https://pan.baidu.com/s/1iA_wK_4alIugw8yFUKDjHA
提取码:db3m

2、他人写的项目总结和笔记(有一定的改进,简历改进在本地项目文件夹)

2.1、项目笔记

项目笔记
码云

2.2、项目总结1

他人博客总结

他人博客总结

2.3、项目总结2

整完了,顺带整合了 SpringSecurity。使用 Redis 缓存 jwt 实现了 jwt 的自动续约
可以参考: https://github.com/antigenMHC/ErCiYuan

2.4项目总结3

总结

2.5、项目总结4

https://github.com/liusCoding/guli-online-college-project

3、问题与解决

他人总结

问题day04 03

如果你在day04 03中vue-admin-template首次登录,并没有像老师那样进入的是login页面,而是直接跳过登录页面,不要慌,把浏览器cookie清除试试。(推测你第一次登录vue- admin-master这个时候记住密码了)

问题day 05

你好,我现在看到day5前端设计的表单设计,在实现点击编辑按钮反显到添加讲师页面时,报network error 但是我在teachercontroller中已经加了跨域注解,前段teacher. js中getbyID的URL也正确,请问这种问题怎么解决呢?

无双M请问你解决了吗?我也遇到了,我是认为是id字段过长,才不行,我在数据库手动把teacher表id改小就没事了,但是这个很low,请教啊!

解决了

:把控制器接收参数的类型改为long,或string就OK了[大笑][大笑]

你好,请问怎么解决的?

请问本来getById()传的不就是String id吗,数据库也是char类型的

无双M回复 @不要熬夜了哦 :就是控制器参数类型用string或者long

问题 day 05

位置描述:day05,讲师管理前端。

问题描述:分页查询,删除讲师,添加讲师,编辑讲师功能都没有问题。

但是,新添加的讲师,在讲师列表中修改和删除时,

前端却提示:未知错误

后端控制台打印是:Caused by: java.lang.NumberFormatException: For input string: 1335353508001587201

个人尝试解决:手动在数据库中将teacher表的id字段改小,如:“1335”,却能正常删除和编辑!!

求赐教!!!

解决了,我在teachercontroller中,使用string代替integer接受参数就OK了

数字太长,超过了js中number类型的安全范围(2^53 = 9007199254740992),所以替换成String就好了

问题day11~day12

踩个坑,在day11~day12那,视频点播,如果JDK是1.8以上的,那么点播的相关POM依赖, 要严格按照官方文档给的版本配置,否则会显示上传失败,然后控制台那一直显示视频上传中。。

补充:文档地址在这里https://help.aliyun.com/document_detail/53406.html?spm=a2c4g.11186623.6.980.5f027853fqcnnZ#section-lru-alb-d7o

自己要注册域名吗?然后自己备案这些吗?

要,去万网买个你喜欢的域名,icu的最便宜5块一年;然后去阿里云服务器注册,备案。然而实际上这些不做,貌似不是很影响接下来的流程。所以可以先搁置

那请问您是买个哪一个,有备案吗?

有尝试备案过,然后因为自拍照片不合格被驳回了,哈哈。其实整个流程下来很容易的,你下个阿里云App,里面有完整的备案流程,我记得流程是这样:1.先买个域名;2.然后去阿里云控制台买个云服务器,我买了个一年90元的centOS7;这两个是必须有才能备案的,有了这两个后,先实名认证域名,很简单的,一般隔天就能认证好,认证好三天后,才可以备案,备案用阿里云App去备案就行了,里面有流程指导

day11的时候,不做域名加速可以吗?嫌麻烦,如果不是很影响后面的学习

实际上并不影响后面的课程,照着做下去事没问题的

问题day 19

在第19天订单那里,跳转不到订单页面,是因为token没传给后端
在api方法那加上代码
// 通过请求头发送token
headers: { token: cookie.get(guli_jwt_token) }

这真的是个坑 headers: { token: cookie.get(hzau_jwt_token) }

问题p41

对P41有很大的疑问,为什么要把BasicEntity放在其他module下面,而不是service_edu?我试过放在service_base下面但是创建的实体类不能引用BasicEntity

其他模块例如service_cms,它的实体类也要继承BaseEntity。不能引用是因为启动类没加@ComponentScan注解扫描吧

附近的决定因为后面还有其他的业务,里边也有实体类,而basicEntity是所有实体类共有属性的类,如果房子啊service_edu,后面 的业务就引用不了,service_base下面可以引用,可能你的service业务没有导入service_base依赖

是的了,service那边没引用

问题p51

如果你在在p51教师的模糊查询,name你填的是汉字,可发现怎么也查不出来。在老师给的application.yaml中数据库连接配置:jdbc:mysql://localhost3306db191125_guli_eduserverTimezone=GMT%2B8,配置characterEncoding=utf8

问题p94

p94,05不用模拟,base api换成https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin就可以了

问题 p352

P325,当使用Swagger测试上传视频时遇到控制台报错“com/aliyun/oss/internal/OSSUdfOperation”的信息,阿里云点播控制台中一直显示“上传中”的情况。请先确定JDK版本是否为JDK1.8,然后可以将版本控制器中“aliyun.oss.version”的版本改为3.1.0

问题p325

p325中视频上传,aliyun-java-vod-upload组件版本使用1.4.11,测试不能通过;改为1.4.14即可

问题P355

P355,如果在执行npm install后,在执行npm run dev 的时候报错,请先找到指定的报错文件然后执行一次ctrl+s的操作

把那个_id.vue保存一下(ctrl+s)就可以了

问题P355

P355运行错误的原因:Tab键打出的空格被ESlint检测到了,把_id.vue文件的153行li class=lh-menu-second ml30语句前面的空格删除就行,在回车一下,记得C+S

问题二

流媒体技术学习笔记之(四)解决问题video.js 播放m3u8格式的文件,根据官方的文档添加videojs-contrib-hls也不行的原因解决了

问题三

再全局安装webpack 和webpack-cli在执行webpack -v,进入死循环一样一直叫你安装webpack-cli。百度也解决不了,不要慌。那你就不要全局安装,解压老师给的vue-admin-master或者那个简单的,现在vs控制台,npm install webpack npm install webpack-cli 再执行老师的命令npm install npm run dev

问题五

遇到common_util打包失败:
首先在preference-build tool-Maven下,勾选两个override,然后打开local repository,找到common_util,把它给删了;然后其他地方的配置基本和原来的一样,不过我删掉了最大的那个父Pom里的springboot-maven-plugin;然后点击IDEA右边工具栏的Maven,点击install,就好了。

对了,还要在project structurn里面选中爆红的common_util,修改它的class和source,分别修改为,install之后,在common_util包里面生成target里面对应的文件夹和jar包

问题六

3.1以下的 mp有BUG ,删除时,如果用service调用remove方法,无论删除与否都会返回true,用mapper调用delete方法则可以通过int返回更新数据库条目判断是否删除成功
两个方法功能相同,返回值类型不同
如果一定要调用service中的remove方法,请把MP版本更新为3.2.0

问题十二

微信登录老师的现在还能用吗

将guli.shop换为localhost:8160就可以了,亲测可用

微信扫码失效的,使用新的,首先将模块启动端口改成8160(一定得是这个,其他的没用),其次将redirect_url 改为:http://localhost:8160/api/ucenter/wx/callback

问题十六

为什么老是出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.qy.mybatis_plus.mapper.UserMapper.selectList 问题呐 有大佬知道的么?

GuJeonPamapper xml文件打包时忽略了, 在依赖里加东西,还得再配置文件里加上mapper文件的路径地址

问题十八

打包始终不成功 弄了好久了 除了打common util能成功 但是service base打包找不到common util的依赖包

https://blog.csdn.net/caoweifeng12/article/details/107335517 已解决可以参考一下

可能需要 clean + install一下,jar包就出来了,我的是这样,然后在project structure的module里面找到缺失的那个包,修改他的classpath和source

4、我的笔记

mybatisplus

让天下没有难学的技术
官网:http://mp.baomidou.com
参考教程:http://mp.baomidou.com/guide/

一、简介

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

润物无声  
    只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。

效率至上
    只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。

丰富功能
    热加载、代码生成、分页、性能分析等功能一应俱全。

二、创建并初始化数据库
1、创建数据库
mybatis_plus
在这里插入图片描述

2、创建 User 表
其对应的数据库 Schema 脚本如下:

	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)


);

其对应的数据库 Data 脚本如下:

	INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),

(2, 'Jack', 20, 'test2@baomidou.com'),

(3, 'Tom', 28, 'test3@baomidou.com'),

(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

三、确认idea配置
1、打开配置
2、Java编译器
3、项目和文件的编码
4、Maven配置

四、创建项目
1、初始化工程

使用 Spring Initializr 快速初始化一个 Spring Boot 工程
Group:com.atguigu
Artifact:mybatis_plus
版本:2.2.1.RELEASE
2、引入依赖
注意:引入 MyBatis-Plus 之后请不要再次引入 MyBatis,以避免因版本差异导致的问题。

		<!--mybatis-plus-->

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.3.1</version>
		</dependency>



		<!--mysql运行时依赖-->

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>


		<!--lombok用来简化实体类-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

3、idea中安装lombok插件
(1)idea2019版本

(2)idea2018版本
五、编写代码
1、配置
在 application.properties 配置文件中添加 MySQL 数据库的相关配置:

#mysql数据库连接

spring boot 2.1及以上(内置jdbc8驱动)
注意:driver和url的变化

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db1911256_mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=990325

注意:

1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:

java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more

2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息
2、主类
在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹

package com.atguigu.mybatis_plus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.atguigu.mybatis_plus.mapper")
public class MybatisPlusApplication {

	public static void main(String[] args) {
		SpringApplication.run(MybatisPlusApplication.class, args);
	}

}

3、实体
创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)

package com.atguigu.mybatis_plus.entity;

import lombok.Data;

/**
 * @Author ljm
 * @Date 2021/9/25 21:32
 * @Version 1.0
 */
@Data
public class User {
    private Long id;


    private String name;


    private Integer age;


    private String email;
}

查看编译结果

4、mapper
创建包 mapper 编写Mapper 接口: UserMapper.java

package com.atguigu.mybatis_plus.mapper;

import com.atguigu.mybatis_plus.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

/**
 * @Author ljm
 * @Date 2021/9/25 21:34
 * @Version 1.0
 */
// https://www.jianshu.com/p/3942f6b4fa75   用法
@Repository
public interface UserMapper extends BaseMapper<User> {

}

5、测试

添加测试类,进行功能测试:

package com.atguigu.mybatis_plus;

import com.atguigu.mybatis_plus.entity.User;
import com.atguigu.mybatis_plus.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class MybatisPlusApplicationTests {

	@Autowired
	private UserMapper userMapper;


	@Test
	void testSelectList() {
		List<User> users = userMapper.selectList(null);
		users.forEach(System.out::println);

	}

}

注意:

IDEA在 userMapper 处报错,因为找不到注入的对象,因为类是动态创建的,但是程序可以正确的执行。

为了避免报错,可以在 dao 层 的接口上添加 @Repository 注

通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

查看控制台输出:

6、查看sql输出日志


#mybatis日志

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

三、MP的主键策略
1、ASSIGN_ID
MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)

@TableId(type = IdType.ASSIGN_ID)



private String id;
2、AUTO 自增策略
需要在创建数据表的时候设置主键自增
实体字段中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO)



private Long id;

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略



mybatis-plus.global-config.db-config.id-type=auto

一、更新操作
注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

@Test


public void testUpdateById(){  



    User user = new User();


    user.setId(1L);


    user.setAge(28);



    int result = userMapper.updateById(user);

    System.out.println("影响的行数:" + result);



}
二、自动填充

需求描述:
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作
1、数据库修改
在User表中添加datetime类型的新的字段 create_time、update_time
2、实体类修改
实体上增加字段并添加自动填充注解

@Data


public class User {




    

    @TableField(fill = FieldFill.INSERT)


    private Date createTime;



    //@TableField(fill = FieldFill.UPDATE)

    @TableField(fill = FieldFill.INSERT_UPDATE)


    private Date updateTime;


}

3、实现元对象处理器接口
注意:不要忘记添加 @Component 注解

package com.atguigu.mybatis_plus.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author ljm
 * @Date 2021/9/26 19:49
 * @Version 1.0
 */
// spring初始化对象,Component表示注解类的对象就会自动被spring初始化出来
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        System.out.println("insertfill=====");
        //对象赋值
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }

    @Override
    public void updateFill(MetaObject metaObject) {
        System.out.println("updatefill=====");
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }
}

4、测试

三、乐观锁

1、场景
一件商品,成本价是80元,售价是100元。老板先是通知小李,说你去把商品价格增加50元。小李正在玩游戏,耽搁了一个小时。正好一个小时后,老板觉得商品价格增加到150元,价格太高,可能会影响销量。又通知小王,你把商品价格降低30元。
此时,小李和小王同时操作商品后台系统。小李操作的时候,系统先取出商品价格100元;小王也在操作,取出的商品价格也是100元。小李将价格加了50元,并将100+50=150元存入了数据库;小王将商品减了30元,并将100-30=70元存入了数据库。是的,如果没有锁,小李的操作就完全被小王的覆盖了。
现在商品价格是70元,比成本价低10元。几分钟后,这个商品很快出售了1千多件商品,老板亏1多万。
2、乐观锁与悲观锁

上面的故事,如果是乐观锁,小王保存价格前,会检查下价格是否被人修改过了。如果被修改过了,则重新取出的被修改后的价格,150元,这样他会将120元存入数据库。
如果是悲观锁,小李取出数据后,小王只能等小李操作完之后,才能对价格进行操作,也会保证最终的价格是120元。

接下来将我们演示这一过程:
3、模拟修改冲突
(1)数据库中增加商品表(2)添加数据

	CREATE TABLE product

(



    id BIGINT(20) NOT NULL COMMENT '主键ID',



    name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',


    price INT(11) DEFAULT 0 COMMENT '价格',



    version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',



    PRIMARY KEY (id)


);


INSERT INTO product (id, NAME, price) VALUES (1, '外星人笔记本', 100);

(3)实体类

package com.atguigu.mybatis_plus.entity;

import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;

/**
 * @Author ljm
 * @Date 2021/9/26 20:21
 * @Version 1.0
 */
@Data
public class Product {


        private Long id;

        private String name;

        private Integer price;

        @Version
        private Integer version;

}

(4)Mapper

package com.atguigu.mybatis_plus.mapper;

import com.atguigu.mybatis_plus.entity.Product;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;

/**
 * @Author ljm
 * @Date 2021/9/26 20:22
 * @Version 1.0
 */
@Repository
public interface ProductMapper extends BaseMapper<Product> {
}

(5)测试

	  @Autowired
    private ProductMapper productMapper;

    @Test
    public void testConcurrentUpdate() {
        //1、 小李获取数据
        Product p1 = productMapper.selectById(1L);
        System.out.println("小李取出的价格"+p1.getPrice());

        // 2、 小王获取数据
        Product p2 = productMapper.selectById(1L);
        System.out.println("小王取出的价格"+p2.getPrice());

        // 3、小李加了50元存入数据库
        p1.setPrice(p1.getPrice()+50);
        productMapper.updateById(p1);


        // 4、小王减了30元存入数据库
        p2.setPrice(p2.getPrice()-30);
        int i = productMapper.updateById(p2);
        if (i==0) {
            System.out.println("小王更新失败");
            //发起重试
            p2 = productMapper.selectById(1L);
            p2.setPrice(p2.getPrice() -30);
            productMapper.updateById(p2);

        }

        //5、其他人看到的结果.最后的结果
        Product p3 = productMapper.selectById(1L);
        System.out.println("" +
                "最后的结果"+p3.getPrice());

    }

4、解决方案

数据库中添加version字段
取出记录时,获取当前version
SELECT id,`name`,price,`version` FROM product WHERE id=1
更新时,version + 1,如果where语句中的version版本不对,则更新失败
UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND `version`=1

5、乐观锁实现

(1)修改实体类
添加 @Version 注解

 @Version
        private Integer version;

(2)创建配置文件

创建包config,创建文件MybatisPlusConfig.java
此时可以删除主类中的 @MapperScan 扫描注解

(3)注册乐观锁插件 在 MybatisPlusConfig 中注册 Bean

package com.atguigu.mybatis_plus.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @Author ljm
 * @Date 2021/9/26 20:57
 * @Version 1.0
 */
//做事务处理
@EnableTransactionManagement
//配置类
@Configuration
public class MybatisPlusConfig {
    //spring当中可以被初始化出来的对象
    @Bean
    //乐观锁插件
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {

        return new OptimisticLockerInterceptor();
    }

}

(4)测试
在这里插入图片描述

一、查询

1、通过多个id批量查询
完成了动态sql的foreach的功能

    @Test
    public void testSelectBatchIds(){
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
    }

2、简单的条件查询
通过map封装查询条件
注意:map中的key对应数据库中的列名。如:数据库user_id,实体类是userId,这时map的key需要填写user_id

    @Test
    public void testSelectByMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","helen");
        map.put("age",18);

        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);



    }
二、分页

1、分页插件
MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
(1)添加分页插件
配置类中添加@Bean配置

/**
 * 分页插件

 */


@Bean
public PaginationInterceptor paginationInterceptor() {

    return new PaginationInterceptor();

}

(2)测试selectPage分页
测试:最终通过page对象获取相关数据

@Test
public void testSelectPage(){

    Page<User> page = new Page<>(1, 5);

    Page<User> pageParam = userMapper.selectPage(page, null);

    List<User> records = pageParam.getRecords();

    records.forEach(System.out::println);

    System.out.println(pageParam.getPages());//总页数
    System.out.println(pageParam.getTotal());//总记录数
    System.out.println(pageParam.getCurrent());//当前页码号
    System.out.println(pageParam.getSize());//每页记录数
    System.out.println(pageParam.hasNext());//是否有下一页
    System.out.println(pageParam.hasPrevious());//是否有上一页

}

在这里插入图片描述
2、返回指定的列
当指定了特定的查询列时,希望分页结果列表只返回被查询的列,而不是很多null值
测试selectMapsPage分页:结果集是Map

    @Test
    public void testSelectPage(){


        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();

        queryWrapper.select("id","name");


        Page<Map<String,Object>> page = new Page<>(1, 5);

        Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, queryWrapper);

        List<Map<String, Object>> records = pageParam.getRecords();

        records.forEach(System.out::println);

        System.out.println(pageParam.getPages());//总页数
        System.out.println(pageParam.getTotal());//总记录数
        System.out.println(pageParam.getCurrent());//当前页码号
        System.out.println(pageParam.getSize());//每页记录数
        System.out.println(pageParam.hasNext());//是否有下一页
        System.out.println(pageParam.hasPrevious());//是否有上一页

    }

在这里插入图片描述

一、删除

1、根据id删除记录

    @Test
    public void testDeleteById() {
        int i = userMapper.deleteById(5L);
        System.out.println("删除了"+i+"行");

    }

2、批量删除

    @Test
    public void testDeleteBatchIds() {
        int i = userMapper.deleteBatchIds(Arrays.asList(10,11,12));
        System.out.println("删除了"+i+"行");

    }

3、简单条件删除

 @Test
    public void testDeleteByMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","helen");
        map.put("age","18");

        int i = userMapper.deleteByMap(map);
        System.out.println("删除了"+i+"行");


    }
二、逻辑删除

1、物理删除和逻辑删除

物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

逻辑删除的使用场景:

可以进行数据恢复
有关联数据,不便删除

2、逻辑删除实现流程
(1)数据库修改
添加 deleted字段

ALTER TABLE `user` ADD COLUMN `deleted` boolean DEFAULT false

(2)实体类修改
添加deleted 字段,并加上 @TableLogic 注解

@TableLogic
private Integer deleted;

3)配置(可选)
application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无

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

(4)测试

测试后发现,数据并没有被删除,deleted字段的值由0变成了1
测试后分析打印的sql语句,是一条update
注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作
    @Test
public void testLogicDelete() {

    int result = userMapper.deleteById(1L);

    System.out.println(result);

}

(5)测试逻辑删除后的查询
MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断

@Test
public void testLogicDeleteSelect() {
    List<User> users = userMapper.selectList(null);
    users.forEach(System.out::println);
}
一、wapper介绍

在这里插入图片描述
Wrapper : 条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
QueryWrapper : 查询条件封装
UpdateWrapper : Update 条件封装
AbstractLambdaWrapper : 使用Lambda 语法
LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : Lambda 更新封装Wrapper

@SpringBootTest

public class QueryWrapperTests {

    @Autowired

    private UserMapper userMapper;


}
二、测试用例

1、ge、gt、le、lt、isNull、isNotNull

@Test
public void testDelete() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();

    queryWrapper
       .isNull("name")

        .ge("age", 12)

        .isNotNull("email");

    int result = userMapper.delete(queryWrapper);

    System.out.println("delete return count = " + result);

}

2、eq、ne
注意:seletOne()返回的是一条实体记录,当出现多条时会报错

@Test

public void testSelectOne() {

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();


    queryWrapper.eq("name", "Tom");


    User user = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常
    System.out.println(user);


}

3、between、notBetween
包含大小边界

@Test

public void testSelectCount() {

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();


    queryWrapper.between("age", 20, 30);

    Integer count = userMapper.selectCount(queryWrapper); //返回数据数量

    System.out.println(count);


}

4、like、notLike、likeLeft、likeRight
selectMaps()返回Map集合列表,通常配合select()使用

@Test

public void testSelectMaps() {



    QueryWrapper<User> queryWrapper = new QueryWrapper<>();

    queryWrapper

        .select("name", "age")

        .like("name", "e")

        .likeRight("email", "5");

    List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表

    maps.forEach(System.out::println);

}

5、in、notIn、inSql、notinSql、exists、notExists
n、notIn:

notIn("age",{1,2,3})--->age not in (1,2,3)
notIn("age", 1, 2, 3)--->age not in (1,2,3)

inSql、notinSql:可以实现子查询

例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
    @Test
    public void testSelectObjs() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

//        queryWrapper.in("id", 1, 2, 3);


        queryWrapper.inSql("id", "select id from user where id <= 3");

        List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表

        objects.forEach(System.out::println);

    }

6、or、and
注意:这里使用的是 UpdateWrapper
不调用or则默认为使用 and 连

@Test
public void testUpdate1() {

    //修改值


    User user = new User();


    user.setAge(99);
    user.setName("Andy");



    //修改条件


    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();



    userUpdateWrapper
        .like("name", "h")
        .or()
        .between("age", 20, 30);


    int result = userMapper.update(user, userUpdateWrapper);


    System.out.println(result);

}

7、lambda表达式
lambda表达式内的逻辑优先运算

@Test

public void testUpdate2() {


    //修改值

    User user = new User();



    user.setAge(99);


    user.setName("Andy");



    //修改条件


    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();


    userUpdateWrapper

        .like("name", "n")
        .or(i -> i.like("name", "a").eq("age", 20));



    int result = userMapper.update(user, userUpdateWrapper);



    System.out.println(result);


}

8、orderBy、orderByDesc、orderByAsc

@Test
public void testSelectListOrderBy() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.orderByDesc("age", "id");
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);

}

9、set、setSql
最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段

@Test
public void testUpdateSet() {


    //修改值


    User user = new User();


    user.setAge(60);

    //修改条件

    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();


    userUpdateWrapper

        .like("name", "h")

        .set("name", "Peter")//除了可以查询还可以使用set设置修改的字段


        .setSql(" email = '123@qq.com'");//可以有子查询


    int result = userMapper.update(user, userUpdateWrapper);


}

三、查询方式
在这里插入图片描述
一、工程结构

guli_parent :根目录(父工程),管理四个子模块:
    canal_client : canal 数据库表同步模块(统计同步数据)
    common :公共模块父节点
        common_util :工具类模块,所有模块都可以依赖于它
        service_base : service 服务的 base 包,包含 service 服务的公共配置类,所有 service 模块依赖于它
        spring_security :认证与授权模块,需要认证授权的 service 服务依赖于它 
    infrastructure :基础服务模块父节点
        api_gateway : api 网关服务 
    service : api 接口服务父节点
        service_edu :教学相关 api 接口服务
        service_oss :阿里云 oss api 接口服务
        service_acl :用户权限管理 api 接口服务(用户管理、角色管理和权限管理等)
        service_cms : cms api 接口服务
        service_sms :短信 api 接口服务
        service_trade :订单和支付相关 api 接口服务
        service_statistics :统计报表 api 接口服务
        service_ucenter :会员 api 接口服务
        service_vod :视频点播 api 接口服务 

ctrl+n搜索文件中的类

ctrl+shift+n搜索配置的类

vscode快捷键

!然后回车出现html主题
ul>li*3变为
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐