myBatis plus详细笔记(基于mysql数据库)

官方文档:https://mp.baomidou.com/
MyBatis-Plus 入门 - 视频教程 - 慕课网:https://www.imooc.com/learn/1130
MyBatis-Plus 进阶 - 视频教程 - 慕课网:https://www.imooc.com/learn/1171

一、环境搭建

文件目录结构,一直截图不利于排版,请将后面代码片段对应此图建立
在这里插入图片描述

1、创建测试用的数据库和表(直接复制sql语句执行即可,如果不会,请先学习mysql数据库,这是基础中的基础)

	#创建数据库
	create database `mybatis_plus_test`;
	#指定数据库为
	use `mybatis_plus_test`;
	
	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)
	);
	#添加数据
	insert into user(id,name,age,email) values
	(1,'Jone',18,'testmybatis1@qq.com'),
	(2,'Jack',20,'testmybatis2@qq.com'),
	(3,'Tom',28,'testmybatis3@qq.com'),
	(4,'Sandy',21,'testmybatis4@qq.com'),
	(5,'Billie',24,'testmybatis5@qq.com');

2、使用maven引入依赖(mysql版本请根据自己版本装配)(不会的参考以下两篇文章,分别是maven的使用和spring boot的使用以及lombok的使用)
maven:========https://blog.csdn.net/grd_java/article/details/105089100
spring boot:==https://blog.csdn.net/grd_java/article/details/105140042
lombok:=======https://blog.csdn.net/grd_java/article/details/105923234

	<parent>
        <!--spring boot 父依赖-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>
    <dependencies>
        <!--starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--spring boot web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--整合mybatis-plus和spring boot 的包   这里和以往不同,使用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>
            <version>5.1.2</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>

3、创建spring boot启动类(这里不做介绍,上面给出的spring boot链接中有)

package com.testMybatisPlus;

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

@SpringBootApplication //标志这个类为spring boot 启动类
@MapperScan(value = "com.testMybatisPlus.mapper") //自动扫描指定包下的mapper映射,有了这个就不需要在配置文件中指定mapper映射了.value="需要扫描的包"
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

4、配置application.yml文件

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver #这个已经淘汰了,如果是8.0版本请使用com.mysql.cj.jdbc.Driver 
    url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=GMT%2B8 #?后面参数表示时区,非常重要,8.0以后的版本是一定需要的,spring boot集成了8.0的驱动,所以要加,这里我先前依赖中添加了5.0版本驱动,不写也行
    username: root
    password: 123456

5、编写相应实体类

package com.testMybatisPlus.entity;

import lombok.Data;

@Data //lombok工具,为我们自动生成get,set,有了它,如果生效了,类中的字段名会变色,没有则不变
public class User {
    /**
    * 这里的变量类型和名字应该都和数据库中一一对应
    * */
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

6、编写持久层接口,mapper映射

package com.testMybatisPlus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.testMybatisPlus.entity.User;
import org.springframework.stereotype.Repository;

@Repository //让spring boot通过注解将接口扫描到容器中
public interface UserMapper extends BaseMapper<User> {//mybatis plus 中,通用mapper无需配置了,只需要继承BaseMapper即可完成动态关联实体类,后面跟着的泛型就是结果集封装的实体类
    /**
     * 单表的增删改查,都由通用mapper提供了,
     * 使用通用mapper,在mybatis plus中,无需配置,继承BaseMapper类即可,泛型指定结果集封装的实体类
     * 但是mybatis依然找不到这些mapper映射文件,这时有两种方法可供选择
     *  1、配置mybatis,指定mapper映射的位置
     *  2、在spring boot启动类上添加    @MapperScan(Value="映射文件位置")
     *     注解,即可自动扫描mapper映射
     *     
     *  若有多表操作,才需要编写抽象方法,若只有单表操作,就无需编写此接口了,继承与通用mapper的方法就够用
     */
}

7、编写service处理业务

package com.testMybatisPlus.service;

import com.testMybatisPlus.entity.User;
import com.testMybatisPlus.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper; //此处报错是因为接口不能直接创建对象,但是我们使用的是通用mapper,所以忽略即可

    public User selectById(Long id){
       return userMapper.selectById(id);
    }
}

8、编写前端控制器进行测试

package com.testMybatisPlus.Controller;

import com.testMybatisPlus.entity.User;
import com.testMybatisPlus.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserHandler {
    @Autowired
    private UserService userService;

    @GetMapping("selById")
    @ResponseBody
    public User selById()
    {
        return userService.selectById(4L);//数字后面跟L才能表示为Long类型数据
    }
}

9、测试(若是8.0数据库请向下看)
在这里插入图片描述
10、解决8.0mysql的时区问题

  • 1、重新设置时区,修改后需要重启才能看到效果
    在这里插入图片描述
  • 2、重新配置application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver #使用最新的驱动类
    url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false 
		    #serverTimeZone:设置时区,UTC表示世界通用时区
		    #useUnicode=true:使用字符集Unicode
		    #characterEncoding=utf-8:编码为utf-8
		    #useSSL=false:不使用SSL服务器
    username: root
    password: 123456
  • 3、maven的pom.xml文件中 驱动必须和你的mysql版本对应
  • 11、其它问题在这里插入图片描述

二、单表通用mapper进行CRUD(增删改查)

常用注解

@TableName(value="user") //指定实体类对应的表名,一般用于实体类名字不同于数据库表名的时候,其他时候会自动映射
@TableId //指定此字段为主键,用于当表主键不叫id的时候,这时默认使用id作为主键,当然查询不到,用此注解即可标识此
@TableField(value="name") //指定此属性对应表中哪个字段,用于实体类属性名字与表中字段名不匹配的情况下,
@TableField(exist = false)//推荐,exist默认为true表示数据库中存在的字段,当设置为false时,表示这个属性在数据库中没有对应字段

常用条件构造器(全部拷贝官方文档的

语法
	QueryWrapper<User> queryWrapper=new QueryWrapper<>();//条件构造器需要此对象,泛型传入返回的实体类对象
    queryWrapper.like("name","%o%").lt("age",40);		//对象.条件构造方法1.方法2....的形式判断
    userMapper.selectList(queryWrapper);				//将条件作为参数传入方法即可
1、eq
	等于 =: eq("name", "老王")--->name = '老王'
2、ne
	不等于 <>: ne("name", "老王")--->name <> '老王'
3、gt
	大于 >: gt("age", 18)--->age > 18
4、ge
	大于等于 >=: ge("age", 18)--->age >= 18
5、lt
	小于 <: lt("age", 18)--->age < 18
6、le
	小于等于 <=: le("age", 18)--->age <= 18
7、between
	BETWEEN 值1 AND 值2: between("age", 18, 30)--->age between 18 and 30
8、notBetween
	NOT BETWEEN 值1 AND 值2: notBetween("age", 18, 30)--->age not between 18 and 30
9、like
	LIKE '%值%': like("name", "王")--->name like '%王%'
10、notLike
	NOT LIKE '%值%': notLike("name", "王")--->name not like '%王%'
11、likeLeft
	LIKE '%值': likeLeft("name", "王")--->name like '%王'
12、likeRight
	LIKE '值%': likeRight("name", "王")--->name like '王%'
13、isNull
	字段 IS NULL
	例: isNull("name")--->name is null
14、isNotNull
	字段 IS NOT NULL
	例: isNotNull("name")--->name is not null
15、in
	字段 IN (value.get(0), value.get(1), ...): in("age",{1,2,3})--->age in (1,2,3)
	字段 IN (v0, v1, ...): in("age", 1, 2, 3)--->age in (1,2,3)
16、notIn
	字段 IN (value.get(0), value.get(1), ...): notIn("age",{1,2,3})--->age not in (1,2,3)
	字段 NOT IN (v0, v1, ...): notIn("age", 1, 2, 3)--->age not in (1,2,3)
17、inSql
	字段 IN ( sql语句 ): 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)
18、notInSql
	字段 NOT IN ( sql语句 ): notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6): notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)
19、groupBy
	分组:GROUP BY 字段, ...: groupBy("id", "name")--->group by id,name
20、orderByAsc
	排序:ORDER BY 字段, ... ASC
	例: orderByAsc("id", "name")--->order by id ASC,name ASC
21、orderByDesc
	排序:ORDER BY 字段, ... DESC
	例: orderByDesc("id", "name")--->order by id DESC,name DESC
22、orderBy
	排序:ORDER BY 字段, ...: orderBy(true, true, "id", "name")--->order by id ASC,name ASC
23、having
	HAVING ( sql语句 ): having("sum(age) > 10")--->having sum(age) > 10: having("sum(age) > {0}", 11)--->having sum(age) > 11
24、or
	拼接 OR
	注意事项:
	
	主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接): eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'
	OR 嵌套
	例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')
25、and
	AND 嵌套
	例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')
26、nested
	正常嵌套 不带 AND 或者 OR
	例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')
27、apply
	拼接 sql
	例: apply("id = 1")--->id = 1: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'"): apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
28、last
	无视优化规则直接拼接到 sql 的最后
	例: last("limit 1")
29、exists
	拼接 EXISTS ( sql语句 ): exists("select id from table where age = 1")--->exists (select id from table where age = 1)
30、notExists
	拼接 NOT EXISTS ( sql语句 ): notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)
31、select
	设置查询字段
	例: select("id", "name", "age"): select(i -> i.getProperty().startsWith("test"))
=================================修改======================================

	UpdateWrapper<User> updateWrapper=new UpdateWrapper<>(); //注意这里使用的是UpdateWrapper
    UpdateWrapper.set("name", "老李头");
    userMapper.update(User.Class,UpdateWrapper);
1、set
	SQL SET 字段
	例: set("name", "老李头"): set("name", "")--->数据库字段值变为空字符串
	例: set("name", null)--->数据库字段值变为null
2、setSql
	设置 SET 部分 SQL
	例: setSql("name = '老李头'")

1、为了更好理解,我们配置一下日志打印,这样我们执行mapper接口方法时,就有日志参考了(以下是更新后的application.yml文件)

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false #?后面参数表示时区,非常重要
    username: root
    password: 123456

logging:
  level:
    root: warn
    com.testMybatisPlus.mapper: trace #设置日志输出,帮我监听com.testMybatisPlus.mapper包下的接口日志
  pattern:
    console: '%p%m%n' #日志格式

2、mybatis plus常用注解,给User实体类加注解,一般用于java实体类与数据库的名称不对应的情况

package com.testMybatisPlus.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data //lombok工具,为我们自动生成get,set,有了它,如果生效了,类中的字段名会变色,没有则不变
@TableName(value="user") //指定实体类对应的表名,一般用于实体类名字不同于数据库表名的时候,其他时候会自动映射
public class User {
    /*
    * 这里的变量类型和名字应该都和数据库中一一对应
    * */
    @TableId //指定此字段为主键,用于当表主键不叫id的时候,这时默认使用id作为主键,当然查询不到,用此注解即可标识此字段为主键,从而不使用id作为主键
    private Long id;
    @TableField(value="name") //指定此属性对应表中哪个字段,用于实体类属性名字与表中字段名不匹配的情况下,
    private String name;
    private Integer age;
    private String email;

    /*当我们实体类中需要定义一些属性,而这些属性不存在与数据库时,mybatis plus是依然会自动进行
    * 数据库映射的,这时找不着对应字段就会报错,解决这种问题有3种方法*/
    private transient String 备注1;   //transient关键字可以让这个属性不参与序列化
    private static String 备注2;      //定义为静态,可以参与序列化,但静态变量不会生成get set方法,也就不会进行映射了
    @TableField(exist = false)
    private String 备注3;             //推荐,exist默认为true表示数据库中存在的字段,当设置为false时,表示这个属性在数据库中没有对应字段
}

3、编写针对User表的UserService(我的UserService)

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper; //此处报错是因为接口不能直接创建对象,但是我们使用的是通用mapper,所以忽略即可
    /**
     * 查询
     */
    /*根据id查询数据*/
    public User selectById(Long id){
       return userMapper.selectById(id);
    }

    /*根据多个id查询*/
    public List<User> selectBatchIds(Long ...id){
        /**
        * 查询id为2,3,4的3条数据
        * select * from user where id in (2,3,4)*/
        List<Long> list = Arrays.asList(id);//将数组转化为List集合
        return userMapper.selectBatchIds(list);
    }
    /*根据map查询*/
    public List<User> selectByMap(Map<String,Object> map){
        /**
         * 查询姓名为Jone年龄18岁的数据
         * select * from user where name = 'Jone' and age = 18*/
        return userMapper.selectByMap(map);
    }

    /*模糊查询(条件构造器查询)like 和 lt小于*/
    public List<User> selectList()
    {
        /**
         * 查询名字中包含字母o 年龄小于40的数据
         * where name like '%o%' and age<40*/
        /*queryWrapper是条件构造器,详情观看官方文档的条件构造器,lt表示小于*/
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.like("name","%o%").lt("age",40);
        return userMapper.selectList(queryWrapper);
    }

    /*between isNotNull*/
    public List<User> selectList2()
    {
        /**
         * 名字中包含o,20到25岁之间,邮箱不为null的用户
         * where    name like '%o%' and
         *          age between 20 and 40 and
         *          email is not null
         * */
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.like("name", "%o%").between("age", 20, 40).isNotNull("email");
        return userMapper.selectList(queryWrapper);
    }

    /*只展示指定字段,而不将所有字段查询*/
    public List<User> selectList3()
    {
        /**
         * 查询名字中包含字母o 年龄小于40的数据
         * where name like '%o%' and age<40*/
        /*queryWrapper是条件构造器,详情观看官方文档的条件构造器,lt表示小于*/
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
//        queryWrapper.select("name","age").like("name","%o%").lt("age",40); select name age from...
        /*select 除了name的字段 from...*/
        queryWrapper.select(User.class,i -> !i.getProperty().startsWith("name")).like("name","%o%").lt("age",40);
        return userMapper.selectList(queryWrapper);
    }

    /**
     * 插入
     */
    /*插入数据,依然使用通用mapper提供的方法*/
    public void insert(User user){
        userMapper.insert(user);
    }
  	/**
     * 修改
     * */
    public void update(User user)
    {
        userMapper.updateById(user);
    }
    /**
     * 删除,除了selecte换成了delete 其它的和查询一毛一样1
     * */
    public void delete(Long id)
    {
        userMapper.deleteById(id);
    }
}

4、编写前端控制器Controller中的UserHandler

@Controller
public class UserHandler {
    @Autowired
    private UserService userService;

    /*按id查询*/
    @GetMapping("selById")
    @ResponseBody
    public User selById()
    {
        return userService.selectById(4L);//数字后面跟L才能表示为Long类型数据
    }

    /*根据多个id查询*/
    @GetMapping("selectBatchIds")
    @ResponseBody
    public List<User> selectBatchIds(){
        return userService.selectBatchIds(2L,3L,4L);
    }

    /*根据map查询*/
    @GetMapping("selectByMap")
    @ResponseBody
    public List<User> selectByMap(){
        Map<String,Object> map=new HashMap<>();
        map.put("name","Jone");//注意这里的key 不是java中实体类的属性,而是数据库中字段名,所以名字要和数据库一致
        map.put("age",18);
        /*使用map 生成的sql语句为 where name='Jone' and age=18*/
        return userService.selectByMap(map);
    }

    /*模糊查询(条件构造器查询)like 和 lt小于*/
    @GetMapping("selectList")
    @ResponseBody
    public List<User> selectList()
    {
        return userService.selectList();
    }

    /*between isNotNull*/
    @GetMapping("selectList2")
    @ResponseBody
    public List<User> selectList2(){
        return userService.selectList2();
    }

    /*只显示姓名和年龄*/
    @GetMapping("selectList3")
    @ResponseBody
    public List<User> selectList3(){
        return userService.selectList3();
    }

    /*插入数据*/
    @GetMapping("insert")
    @ResponseBody
    public void insert(){
        /*创建User对象,这里我没有给id值,mybatis plus 支持主键生成,我不给会自动帮我生成的*/
        User user=new User();
        user.setName("new");
        user.setAge(15);
        user.setEmail("959595@qq.com");
        userService.insert(user);
    }
    
    /*修改,按id进行修改*/
    @GetMapping("update")
    @ResponseBody
    public void update(){
        User user=new User();
        user.setId(1L);
        user.setName("update");
        user.setAge(15);
        user.setEmail("update@qq.com");
        userService.update(user);
    }
    
    /*按id删除*/
    @GetMapping("deleteById")
    @ResponseBody
    public void deleteById()
    {
        userService.selectById(1L);//数字后面跟L才能表示为Long类型数据
    }
}

三、自动填充

什么是自动填充

就是在插入或修改数据时,某些内容无需设置,会按你的要求,自动填充数据

1、数据库中添加两个字段,create_time添加时间,update_time 修改时间

ALTER TABLE `mybatis_plus_test`.`user` 
ADD COLUMN `create_time` datetime NULL AFTER `email`,
ADD COLUMN `update_time` datetime NULL AFTER `create_time`;

2、实体类中添加这两个字段,并添加注解

@TableField(fill= FieldFill.INSERT)         //添加时做改变
private Date createTime;
@TableField(fill= FieldFill.INSERT_UPDATE)  //添加或修改时做改变
private Date updateTime;

3、编写实现类

package com.testMybatisPlus.handler;

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

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    /*使用mp(MyBatis plus)添加时执行*/
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
        /**
         * metaObject:源数据对象,表示当前表中的数据对象
         * setFieldValByName:根据名称设置字段的属性值
         *  第一个参数 就是要修改的字段名称
         *  第二个参数 就是要设置的属性值
         *  第三个参数 就是源数据对象,找不到表一切都是空谈
         */
    }

    /*使用mp进行修改时执行*/
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

在这里插入图片描述

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

四、乐观锁(事务隔离级别)

什么是乐观锁

	1、乐观锁就是锁数据库版本号的一种方式的简称
		当我们多个用户同时操作同一条数据时,有可能发生脏读、不可重复读或幻读,为了避免这些状况,我们可以
		为数据库添加一个版本号,当用户1修改数据时,数据库版本就自动更改,假设原来是1,改过后是2。
		这时其它用户使用的还是版本1的数据库,修改时就会因为版本不对应问题而无法操作,就避免了问题

1、为数据库添加一个version字段,表示版本号

ALTER TABLE `mybatis_plus_test`.`user` 
ADD COLUMN `version` int(10) NULL AFTER `update_time`;

2、实体类中加一个version属性,并添加version注解

@Version //标志此字段是版本号
private Integer version;

3、配置乐观锁插件

package com.testMybatisPlus.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan(value = "com.testMybatisPlus.mapper") //自动扫描指定包下的mapper映射,有了这个就不需要在配置文件中指定mapper映射了,value="需要扫描的包"
public class MpConfig {

	//乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

在这里插入图片描述
4、测试(乐观锁机制是,你当前看到的内容版本,与真实版本不同,才会生效。也就是你要先查出来看到然后修改才会执行,这也是我们期望的效果)

/*修改,测试乐观锁*/
@GetMapping("updateNew")
@ResponseBody
public void updateNew(){
    User user=userService.selectById(1257962056288407554L);//先查指定id的数据
    user.setName("updateNew");//然后改
    user.setAge(5);
    user.setEmail("updateNew@qq.com");
    userService.update(user);//执行修改
}

5、需要注意的问题 数据库中version字段不能为null
数据库version字段不能为null,因为它每次执行都是+1,而null+1还是null,无法达到效果

五、分页插件

什么是分页插件:就是数据库的分页查询,查询表时,数据达到一定条数时,自动分页
1、配置分页插件(和乐观锁一样,可以配置在启动类,也可以放置配置类中)

//分页插件
 @Bean
 public PaginationInterceptor paginationInterceptor() {
     PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
     // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
     // paginationInterceptor.setOverflow(false);
     // 设置最大单页限制数量,默认 500 条,-1 不受限制
     // paginationInterceptor.setLimit(500);
     // 开启 count 的 join 优化,只针对部分 left join
     paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
     return paginationInterceptor;
 }

2、编写Userservice 分页查询方法(我的UserService类)

/*分页查询*/
 public Page<User> testPage()
  {
      //1、创建page对象,传入两个参数 当前页,每页记录数
      Page<User> page = new Page<>(1,3);
      //2、调用mp中分页查询方法,所有数据都会封装到page对象中
      userMapper.selectPage(page,null);//第二个参数是queryWrapper 条件构造器,这里我们不用,传null
      //3、通过page对象获取分页数据
      return page;
  }

3、编写前端控制器Handler

/*分页查询*/
@GetMapping("testPage")
@ResponseBody
public String testPage()
{
    Page<User> page =userService.testPage();
    String str=page.getCurrent()+       //当前页
                "\n"+page.getPages()+   //总页数
                "\n"+page.getRecords()+ //每页数据List集合
                "\n"+page.getSize()+    //记录数
                "\n"+page.getTotal()+   //总记录数
                "\n"+page.hasNext()+    //是否有下一页数据
                "\n"+page.hasPrevious();//是否有上一页
    System.out.println(str);//浏览器看着不好看,输出到控制台观察比较方便
    return str;
}

在这里插入图片描述

六、逻辑删除

什么是逻辑删除

删除有两种形式,物理删除和逻辑删除
	物理删除:永久删除数据
	逻辑删除:通过特定条件,表面上删除了,但实际会根据条件是否成立来删除
				比如,我们为表添加一个字段,专门用于判断是否删除,当数据为0时表示
				不删除,为1就删除

1、数据库添加字段
在这里插入图片描述

2、实体类添加属性和注解

@TableLogic //标志此字段用于逻辑删除
private Integer deleted;

3、测试(注意,这种方法只对mp提供的方法有效,自己写xml需要自己再配置)
在这里插入图片描述
4、再查询时,就应该判断deleted的值是不是1,若是1就不显示。mp封装了此判断,无需添加,但我们自己写的时候需要添加where deleted <> 1 或 where deleted =0

七、性能分析插件(3.2.0版本以上已移除,官方推荐使用第三方插件)

什么是性能分析插件:用于跟踪sql语句的执行,查看其执行完毕共耗费多少时间
1、配置性能分析插件

/**
 * SQL执行效率插件
 */
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
    return new PerformanceInterceptor();
}
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
1. 引入mybatis-plus的依赖:在pom.xml文件中添加以下依赖 ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> ``` 2. 在配置文件中配置数据源:在application.yml文件中添加以下配置 ``` spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root ``` 其中,url中的test为数据库名,root为数据库用户名和密码。 3. 创建实体类和Mapper接口:创建一个实体类,用于映射数据库表中的数据,同时创建一个Mapper接口,用于操作数据库。 4. 使用mybatis-plus提供的注解和方法操作数据库:使用mybatis-plus提供的注解和方法进行增删改查操作,例如: ``` @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public List<User> listUsers() { return baseMapper.selectList(null); } @Override public User getUserById(Long id) { return baseMapper.selectById(id); } @Override public boolean addUser(User user) { return baseMapper.insert(user) == 1; } @Override public boolean updateUser(User user) { return baseMapper.updateById(user) == 1; } @Override public boolean deleteUser(Long id) { return baseMapper.deleteById(id) == 1; } } ``` 以上代码中,UserService接口是一个Service接口,UserServiceImpl类是该接口的实现类,其中使用了baseMapper提供的selectList、selectById、insert、updateById、deleteById等方法进行增删改查操作。 5. 配置Mapper扫描路径:在配置文件中添加以下配置,指定Mapper接口所在的包路径。 ``` mybatis-plus: mapper-locations: classpath:mapper/*.xml ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值