Mybatis-Plus一文详解BaseMapper和Service 使用

Mybatis-Plus简介

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

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

MyBatis Plus基础使用-helloworld

1:导包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis-plus</name>
    <description>mybatis-plus</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <!--springboot依赖-->
        <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>
        </dependency>

        <!--mybatis plus场景-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- mybatis plus 代码生成器引擎依赖-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <!-- mybatis plus 代码生成器依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join</artifactId>
            <version>1.2.4</version>
        </dependency>
        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.mybatisplus.MybatisPlusApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2:配置application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/table_name?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=true
    username: root
    password: 123456

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml,classpath:mapper/*/*.xml
  #配置日志
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3:mybatis-plus代码生成器


package com.example.mybatisplus.utils;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CodeGenerator {
 
    public static void main(String[] args){
        String url = "jdbc:mysql://127.0.0.1:3306/table_name?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=true";
        String username = "root";
        String password = "123456";
        String outPath = System.getProperty("user.dir")  + "/src/main/java";//文件输出路径
        String outPathxml = System.getProperty("user.dir") + "/src/main/resources/mapper";//xml文件输出路径
        String parent = "com.example.mybatisplus";//父包的名称
        String moduleName = "";//模块名称

        String entity = "entity";//设置实体类文件名
        String mapper = "mapper";
        String service = "service";
        String serviceImpl = "service.impl";
        String controller = "controller";

        //表名
        List<String> tables = new ArrayList<>();
        tables.add("country_dic");
 
 
        FastAutoGenerator.create(url, username, password)
                //全局配置
                .globalConfig(builder -> {
                    builder.author("wkl") // 设置作者
//                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(outPath) // 指定输出目录
                            .disableOpenDir();// 生成后不打开目录
                })
 
                //包配置
                .packageConfig(builder -> {
                    builder.parent(parent) // 设置父包名
                            .moduleName(moduleName) // 设置父包模块名
                            .entity(entity)//设置实体类文件名
                            .mapper(mapper)
                            .service(service)
                            .serviceImpl(serviceImpl)
                            .controller(controller)
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, outPathxml)); // 设置mapperXml生成路径
                })
                //策略配置
                .strategyConfig(builder -> {
                    builder.addInclude(tables) // 设置需要生成的表名
//                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
//                            .enableCapitalMode()// 开启大写命名
                            .entityBuilder()// 开启生成实体类
//                            .disableSerialVersionUID()// 禁用生成 serialVersionUID
                            .enableLombok()// 开启lombox模型
                            .enableTableFieldAnnotation() // 开启生成实体时生成字段注解
                            // 阿里巴巴开发规范之创建时间、更新时间 交由mybatis-plus处理,如若交给数据库处理,则取消此设置
                            // .addTableFills(new Column("create_time", FieldFill.INSERT), new Column("update_time", FieldFill.INSERT_UPDATE))

                            .mapperBuilder()//开启生成mapper
                            .superClass(BaseMapper.class)// 设置父类
                            .enableMapperAnnotation()// 开启mapper注解
                            .formatMapperFileName("%sMapper")//格式化mapper名称
                            .formatXmlFileName("%sMapper")//格式化xml名称
                            .enableBaseResultMap()// 生成通用的resultMap

                            .serviceBuilder()//开启生成service
                            .formatServiceFileName("%sService")//格式化service接口文件名称
                            .formatServiceImplFileName("%sServiceImpl")

                            .controllerBuilder()//开启生成controller
                            .enableHyphenStyle()//开启驼峰转连字符
                            .formatFileName("%sController")
                            .enableRestStyle();
                })
                .templateEngine(new VelocityTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }
}

在这里插入图片描述

4:分析mybatis-plus文件结构

1:实体类

在这里插入图片描述

2:Service 接口

在这里插入图片描述

3:ServiceImpl 实现

在这里插入图片描述

4:Mapper 接口

在这里插入图片描述

5:Mapper xml

在这里插入图片描述

MyBatis Plus的使用

1:BaseMapper的查询

根据 ID 查询

T selectById(Serializable id);

根据 entity 条件,查询一条记录

T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectById(4L)

查询(根据ID 批量查询)

List selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L))

根据 entity 条件,查询全部记录

List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectList(new QueryWrapper<User>().eq("age", 20)).forEach(System.out::println);

查询(根据 columnMap 条件)

List selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Map<String, Object> map = new HashMap<>();
map.put("name", "嘎嘎嘎");
map.put("age", 3);
userMapper.selectByMap(map).forEach(System.out::println);

==>  Preparing: SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
==> Parameters: 嘎嘎嘎(String), 3(Integer)
<==    Columns: id, name, age, email
<==        Row: 4, 嘎嘎嘎, 3, gagaga@gaga.com
<==      Total: 1
User(id=4, name=嘎嘎嘎, age=3, email=gagaga@gaga.com)

根据 Wrapper 条件,查询全部记录

List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectObjs(new QueryWrapper<User>().eq("age", 20)).forEach(System.out::println);

根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值

List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));

根据 entity 条件,查询全部记录(并翻页)

IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectMapsPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));

根据 Wrapper 条件,查询全部记录(并翻页)

IPage<Map<String, Object>> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);

userMapper.selectMapsPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));

根据 Wrapper 条件,查询总记录数

Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper);

System.out.println("结果:" + userMapper.selectCount(new QueryWrapper<User>().eq("id", 1L)));

==>  Preparing: SELECT COUNT( * ) FROM user WHERE (id = ?)
==> Parameters: 1(Long)
<==    Columns: COUNT( * )
<==        Row: 1
<==      Total: 1
结果:1

2:BaseMapper的新增

插入一条记录

int insert(T entity);

==>  Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 1583712489828356098(Long), Ami(String), 20(Integer), 999@mm.com(String)
<==    Updates: 1
结果:1
User(id=1583712489828356098, name=Ami, age=20, email=999@mm.com)

注:第一次用的小伙伴肯定很好奇,我没有给表主键设置自增,我也没给主键赋值,为何主键会有值呢?

MP默认使用雪花算法给主键赋值

3:BaseMapper的修改

mybatis-plus 在 serviceImpl 层可以直接使用 this.baseMapper.update 和 updateById ,
如果更新的字段值是null,这时候需更新为 null 的字段更新不成功。打印的 sql 也没有更新为 null 的字段。

原因:
Mybatis-Plus默认的更新策略设置的问题,Mybatis-Plus中FieldStrategy有三种策略:

  • IGNORED:忽略。不管有没有有设置属性,所有的字段都会设置到insert语句中,如果没设置值会更新为null;
  • NOT_NULL:非 NULL,默认策略。也就是忽略null的字段,不忽略"";
  • NOT_EMPTY:非空。为null,为空串的忽略,就是如果设置值为null,“”,不会插入数据库;

根据 whereWrapper 条件,更新记录

int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper whereWrapper);

User user = new User();
user.setId(400L);
user.setName("咕咕咕");
user.setAge(16);
user.setEmail("gugugu@gugu.com");
System.out.println("结果:" + userMapper.update(user, 
                                             new UpdateWrapper<User>().eq("id", 4L)));

==>  Preparing: UPDATE user SET name=?, age=?, email=? WHERE (id = ?)
==> Parameters: 咕咕咕(String), 16(Integer), gugugu@gugu.com(String), 4(Long)
<==    Updates: 1
结果:1

根据 ID 修改

int updateById(@Param(Constants.ENTITY) T entity);

User user = new User();
user.setId(4L);
user.setName("嘎嘎嘎");
user.setAge(3);
user.setEmail("gagaga@gaga.com");
System.out.println("结果:" + userMapper.updateById(user));

==>  Preparing: UPDATE user SET name=?, age=?, email=? WHERE id=?
==> Parameters: 嘎嘎嘎(String), 3(Integer), gagaga@gaga.com(String), 4(Long)
<==    Updates: 1
结果:1

4:BaseMapper的删除

根据 entity 条件,删除记录

int delete(@Param(Constants.WRAPPER) Wrapper wrapper);

userMapper.delete(new QueryWrapper<User>().eq("id", 1L))

删除(根据ID 批量删除)

int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L))

根据 ID 删除

int deleteById(Serializable id);

==>  Preparing: DELETE FROM user WHERE id=?
==> Parameters: 1583712489828356098(Long)
<==    Updates: 1
结果:1

根据 columnMap 条件,删除记录

int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("age", 20);
System.out.println("结果:" + userMapper.deleteByMap(map));

==>  Preparing: DELETE FROM user WHERE name = ? AND age = ?
==> Parameters: 张三(String), 20(Integer)
<==    Updates: 0
结果:0

2:Wrapper查询

通过BaseMapper提供的一些方法我们可以完成一些基本的CRUD,但无法完成复杂条件的查询;对于复杂条件的查询,MyBatis Plus提供了Wrapper接口来处理;

Wrapper是MyBatis Plus提供的一个条件构造器,主要用于构建一系列条件,当Wrapper构建完成后,可以使用Wrapper中的条件进行查询、修改、删除等操作;

1:Wrapper的继承体系如下

在这里插入图片描述
Wrapper是条件构造抽象类,最顶端父类,其主要实现类有如下:

  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
    • QueryWrapper : Query条件封装
    • UpdateWrapper : Update条件封装
    • AbstractLambdaWrapper : 使用Lambda语法
      • LambdaQueryWrapper :基于Lambda语法使用的查询Wrapper
      • LambdaUpdateWrapper : 基于Lambda语法使用的更新Wrapper

2:Wrapper的基本方法

AbstractWrapper是其他常用Wrapper的父类,用于生成 sql 的 where 条件
1)基本方法介绍
AbstractWrapper提供了很多公有的方法,其子类全部具备这些方法,方法列表如下

* 基本⽐较操作
方法名解释示例
eq等于 =eq(“name”, “老王”)—>name = ‘老王’
ne不等于 <>ne(“name”, “老王”)—>name <> ‘老王’
gt大于 >gt(“age”, 18)—>age > 18
ge大于等于 >=ge(“age”, 18)—>age >= 18
lt小于 <lt(“age”, 18)—>age < 18
le小于等于 <=le(“age”, 18)—>age <= 18
betweenbetween 值1 and 值2between(“age”, 18, 30)—>age between 18 and 30
notBetweennot between 值1 and 值2notBetween(“age”, 18, 30)—>age not between 18 and 30
* 模糊查询
方法名解释示例
likeLIKE ‘%值%’like(“name”, “王”)—>name like ‘%王%’
notLikeNOT LIKE ‘%值%’notLike(“name”, “王”)—>name not like ‘%王%’
likeLeftLIKE ‘%值’likeLeft(“name”, “王”)—>name like ‘%王’
likeRightLIKE ‘值%’likeRight(“name”, “王”)—>name like ‘王%’
* 分组排序
方法名解释示例
groupBy分组:GROUP BY 字段, …groupBy(“id”, “name”)—>group by id,name
orderByAsc排序:ORDER BY 字段, … ASCorderByAsc(“id”, “name”)—>order by id ASC,name ASC
orderByDesc排序:ORDER BY 字段, … DESCorderByDesc(“id”, “name”)—>order by id DESC,name DESC
orderBy排序:ORDER BY 字段, …orderBy(true, true, “id”, “name”)—>order by id ASC,name ASC
havingHAVING ( sql语句 )例1:having(“sum(age) > 10”) —>having sum(age) > 10,例2:having(“sum(age) > {0}”, 11)—>having sum(age) > 11
* 子查询
方法名解释示例
isNull字段 IS NULLisNull(“name”)—>name is null
isNotNull字段 IS NOT NULLisNotNull(“name”)—>name is not null
in字段 IN (v0, v1, …)in(“age”, 1, 2, 3)—>age in (1,2,3)
notIn字段 NOT IN (v0, v1, …)notIn(“age”, 1, 2, 3)—>age not in (1,2,3)
inSql字段 IN ( sql语句 )inSql(“id”, “select id from table where id < 3”)—>id in (select id from table where id < 3)
notInSql字段 NOT IN ( sql语句 )notInSql(“id”, “select id from table where id < 3”) —> id not in (select id from table where id < 3)
* 逻辑拼接
方法名解释示例
func主要解决条件拼接func(i -> if(true) {i.eq(“id”, 1)} else {i.ne(“id”, 1)})
or拼接 OReq(“id”,1).or().eq(“name”,“老王”)—>id = 1 or name = ‘老王’
andAND 嵌套and(i -> i.eq(“name”, “李白”).ne(“status”, “活着”))—>and (name = ‘李白’ and status <> ‘活着’)
nested用于多条件拼接时nested(i -> i.eq(“name”, “李白”).ne(“status”, “活着”))—>(name = ‘李白’ and status <> ‘活着’)
apply用于拼接SQL语句例1:apply(“id = 1”)—>id = 1,例2:apply(“id = {0}”,1)—>id = 1,例3:apply(“name like {0} and age > {1}”,“%J%”,18) —>name like ‘%J%’ and age > 18
last无视优化规则直接拼接到 sql 的最后last(“limit 1”) —>在SQL语句最后面拼接:limit 1
exists拼接 EXISTS ( sql语句 )exists(“select id from table where age = 1”)—>exists (select id from table where age = 1)
notExists拼接 NOT EXISTS ( sql语句 )notExists(“select id from table where age = 1”)—>not exists (select id from table where age = 1)

3:创建Wrapper对象:

  • Wrappers静态方法:public static QueryWrapper query()
    • QueryWrapper wrapper = Wrappers.query();
  • 通过QueryWrapper对象的构造方法:public QueryWrapper()
    • QueryWrapper wrapper2 = new QueryWrapper<>();

4:QueryMapper

QueryMapper是AbstractWrapper的子类,主要用于查询指定字段,方法列表如下:

方法名解释示例
select(String… sqlSelect)设置查询字段例1:select(“id”, “name”, “age”),例2:select(i -> i.getProperty().startsWith(“test”))
 // 选择查询的字段
    @Test
    public void test1() throws Exception {
        QueryWrapper<User> wrapper = Wrappers.query();

        // 确定要查询的字段
        wrapper.select("id", "name", "sex");

        // in
        wrapper.in("id","1","2");

        // SQL: SELECT id,name,sex FROM user WHERE (id IN (?,?))
        List<User> userList = userMapper.selectList(wrapper);

        userList.forEach(System.out::println);
    }

5:UpdateWrapper

UpdateWrapper也是AbstractWrapper的子类,因此UpdateWrapper也具备之前的那些查询方法,不同的是,UpdateMapper在那些方法基础之上还提供了很多有关于更新操作的方法;

方法名解释示例
set(String column, Object val)设置查询字段例1:set(“name”, “张三”),例2:set(“name”, “”)—>数据库字段值变为空字符串,例3:set(“name”, null)—>数据库字段值变为null
setSql(String sql)设置set子句的部分SQL例1:setSql(“name = ‘张三’”),例2:setSql(“name = ‘张三’,age=22 where id=1”)
	@Test
    public void test4() throws Exception {
        User user = new User();
        user.setId(1L);

        // user当做查询条件
        UpdateWrapper<User> wrapper = Wrappers.update(user);
        wrapper.set("name", "xiaohui");
        wrapper.set("sex", "0");
        wrapper.set("age", "22");

        // SQL : UPDATE user SET name=?,sex=?,age=? WHERE id=?
        userMapper.update(null, wrapper);
    }

	@Test
    public void test5() throws Exception {
        UpdateWrapper<User> wrapper = Wrappers.update();
        wrapper.setSql("name='abc',sex='0',age=18 where id=1");

        // SQL: UPDATE user SET name='abc',sex='0',age=18 where id=1
        userMapper.update(null, wrapper);
    }

6:LambdaQueryWrapper

LambdaQueryWrapper是QueryWrapper的子类,具备QueryWrapper的所有方法,在QueryWrapper的方法上提供了一系列有关于方法链的操作;

	@Test
    public void test1() throws Exception {

        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();        
       
        wrapper.in(User::getId,"1","2","3")
                .like(User::getName,"a")
                .select(User::getId,User::getName,User::getAge);

        List<User> userList = userMapper.selectList(wrapper);
        for (User user : userList) {
            System.out.println(user);
        }
    }

7:LambdaUpdateMapper

LambdaUpdateMapper同样是UpdateMapper的子类,具备UpdateMapper的所有方法,在UpdateMapper的方法上提供了一系列有关于方法链式的操作;

 @Test
    public void test2() throws Exception {

        LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate();

        wrapper.eq(User::getId,"1").set(User::getName,"lili").set(User::getAge,18);

        userMapper.update(null,wrapper);
    }

MyBatis Plus的Service查询

1:通用Service简介

通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行、remove删除、list 查询集合、page查询分页
在这里插入图片描述

在这里插入图片描述

2:通用service常用方法

新增:

  • default boolean save(T entity):新增记录
  • boolean saveBatch(Collection entityList):批量插入
  • saveBatch(Collection entityList, int batchSize):一次性批量插入batchSize条记录
	@Test
    public void test1() throws Exception {
        User user = new User(null, "zhagnsan", "0", 21);
        userService.save(user);
    }

删除:

  • boolean removeById(Serializable id):根据id删除
  • boolean removeByMap(Map<String, Object> columnMap):根据条件删除
  • boolean remove(Wrapper queryWrapper):使用Wrapper封装条件删除
  • boolean removeByIds(Collection<? extends Serializable> idList):删除一批
	@Test
    public void test2() throws Exception {
        userService.removeById(1L);
    }

修改:

  • boolean updateById(T entity):修改
  • boolean update(Wrapper updateWrapper):根据Wrapper修改
  • boolean update(T entity, Wrapper updateWrapper):使用Wrapper查询出结果,修改为entity
  • boolean updateBatchById(Collection entityList):批量修改
  • updateBatchById(Collection entityList, int batchSize):一次性批量修改batchSize条记录
  • boolean saveOrUpdate(T entity):如果id存在则修改,如果id不存在则新增
/**
     * 如果id存在则修改,不存在则新增
     *
     * @throws Exception
     */
    @Test
    public void test3() throws Exception {
        User user = new User(1L, "zhagnsan", "0", 18);
        userService.saveOrUpdate(user);
    }

 /**
     * 根据id修改
     *
     * @throws Exception
     */
    @Test
    public void test4() throws Exception {

        User user = new User(1L, "xiaolan", "1", 18);
        userService.updateById(user);
    }

查询:

  • T getById(Serializable id):根据id查询
  • List listByIds(Collection<? extends Serializable> idList):根据一批id查询多条记录
  • List listByMap(Map<String, Object> columnMap):根据条件查询多条记录
  • T getOne(Wrapper queryWrapper):根据Wrapper查询一条记录,如果查询到多条则抛出异常
  • T getOne(Wrapper queryWrapper, boolean throwEx):根据Wrapper查询一条记录,通过throwEx决定是否抛出异常
  • int count():查询总记录数
  • int count(Wrapper queryWrapper):根据条件查询总记录数

	/**
     * 根据id查询
     *
     * @throws Exception
     */
    @Test
    public void test5() throws Exception {
        User user = userService.getById(1L);
        System.out.println(user);
    }

    /**
     * 查询列表
     *
     * @throws Exception
     */
    @Test
    public void test6() throws Exception {

        QueryWrapper<User> wrapper = Wrappers.query();
        wrapper.in("id", "1", "2");

        // 查询所有
//        List<User> userList = userService.list();

        // 通过wrapper查询
        List<User> userList = userService.list(wrapper);

        for (User user : userList) {
            System.out.println(user);
        }
    }


    /**
     * 查询总记录数
     *
     * @throws Exception
     */
    @Test
    public void test7() throws Exception {

        QueryWrapper<User> wrapper = Wrappers.query();
        wrapper.like("name", "a");

        // 查询总记录数
//        int count = userService.count();

        // 根据条件查询总记录数
        int count = userService.count(wrapper);

        System.out.println(count);
    }

分页:

  • <E extends IPage> E page(E page, Wrapper queryWrapper):带条件分页查询,当前页数据为T类型
  • <E extends IPage> E page(E page):无条件分页
  • List<Map<String, Object>> pageMaps(E page,Wrapper queryWrapper):带条件分页查询,当前页数据为HashMap类型
  • List<Map<String, Object>> pageMaps(E page):无条件分页
	/**
     * 分页查询(当前页类型为指定类型)
     *
     * @throws Exception
     */
    @Test
    public void test8() throws Exception {

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

        userService.page(page);

        // 当前页数据
        List<User> pageData = page.getRecords();
        for (User user : pageData) {
            System.out.println(user);
        }

        System.out.println("------------");

        System.out.println("当前页:" + page.getCurrent());
        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());
    }


    /**
     * 分页查询(当前页结果为HashMap类型)
     *
     * @throws Exception
     */
    @Test
    public void test9() throws Exception {

        Page page = new Page<>(1, 3);

        userService.pageMaps(page);

        // 当前页数据
        List<HashMap<String, Object>> pageData = page.getRecords();
        for (HashMap userMap : pageData) {
            System.out.println(userMap);
        }

        System.out.println("------------");

        System.out.println("当前页:" + page.getCurrent());
        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());
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/782941.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea 默认路径修改

1.查看 idea 的安装路径&#xff08;右键点击 idea 图标&#xff0c;查看路径 &#xff09; “C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin\idea64.exe” 在 bin 目录查看 idea.properties 文件&#xff0c;修改以下四个路径文件 # idea.config.path${user.home}/…

Linux的前世今生

Unix的起源和发展 1969年&#xff0c;AT&T贝尔实验室的Ken Thompson和Dennis Ritchie等人开发了Unix操作系统。Unix的设计理念强调小而简洁的工具&#xff0c;文本流和系统模块化&#xff0c;这些理念后来成为Linux开发的重要基础。1973年&#xff0c;Unix用C语言重新编写…

昇思25天学习打卡营第17天 | K近邻算法实现红酒聚类

内容介绍&#xff1a; K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;是机器学习最基础的算法之一。它正是基于以上思想&#xff1a;要确定一个样本的类别&#xff0c;可以计算它与所有训练样本的距离&#xff0…

LVGL移植与VS模拟器使用

一、移植文件介绍 二、移植部分 第一步&#xff1a;创建LVGL文件夹 第二步&#xff1a; 构造LVGL文件夹&#xff1a;LVGL - GUI - lvgl - 第三步&#xff1a;添加文件 3.1 从examples中添加2个.c文件 3.2 从src中添加文件 draw文件 extra文件 第四步&#xff1a; 三、Ke…

分享2个iPhone恢复照片的方法,赶紧码住收藏!

手机已经成为我们生活中不可或缺的一部分&#xff0c;它不仅仅是通讯工具&#xff0c;更是我们记录生活点滴的重要工具之一。然而&#xff0c;正如其他任何设备一样&#xff0c;iPhone上存储的照片有时也会不小心被删除或丢失。 别担心&#xff0c;即使你误删了重要的照片&…

网安加·百家讲坛 | 马云卓:漏洞扫描工具漏洞报告对比

作者简介&#xff1a;马云卓&#xff0c;某安全公司安全专家&#xff0c;持有注册信息安全专业人员及渗透测试工程师&#xff08;CISP-PTE&#xff09;和项目管理专业人士&#xff08;PMP&#xff09;证书&#xff0c;拥有丰富的行业经验&#xff0c;长期专注于网络安全攻防技术…

用SOLIDWORKS批量打印工程图纸,没有难度

在工程师完成产品设计后&#xff0c;一般需要打印纸质工程图&#xff0c;如果打印的数量比较多&#xff0c;效率就会比较低&#xff0c;其实SOLIDWORKS软件提供了专用工具用来处理工作量比较大且重复性的工作&#xff0c;这个工具就是SOLIDWORKS Task Scheduler。 SOLIDWORKS T…

css实现鼠标禁用(鼠标滑过显示红色禁止符号)

css实现鼠标禁用&#xff08;鼠标滑过显示红色禁止符号&#xff09; 创作背景css鼠标禁用 创作背景 从本文开始&#xff0c;将会用三篇文章来一步一步实现 vueantdts实战后台管理系统中table表格的不可控操作。中间会补充两篇css知识文章 &#xff0c;方便后续功能的实现。 实…

面向对象编程:定义、特点、应用场景、优缺点及示例代码

目录 前言1. 面向对象编程的定义2. 面向对象编程的特点2.1 封装2.2 继承2.3 多态2.4 抽象 3. 面向对象编程的应用场景3.1 大型软件系统3.2 GUI应用程序3.3 游戏开发 4. 面向对象编程的优缺点4.1 优点4.2 缺点 5. 代表性的编程语言5.1 Java5.2 C5.3 Python 6. 示例代码结语 前言…

【爱上C++】vector用法详解

文章目录 一:vector简介二:vector的创建和初始化三:vector的遍历1.[]下标2.at()3.迭代器遍历4.范围for 四:vector的空间1.size2.max_size3.capacity4.reserve5.resize6.empty 五:vector的增删查改1.push_back2.pop_back3.find4.insert5.erase6.swap7.assign Hello~同学们好&…

ESP32CAM物联网教学10

ESP32CAM物联网教学10 MicroPython 应用体验 小智偶然地发现&#xff0c;有一种新兴的编程模式MicroPython&#xff0c;也能编写ESP32Cam的应用程序了&#xff0c;于是欣然地体验了一把。 编程环境搭建 小智偶然地从下面这家店铺买了一块ESP32Cam&#xff0c;并从客服那里得到…

【人工智能】-- 智能家居

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a; 专业知识 文章目录 &#x1f349;引言 &#x1f349;基于深度卷积神经网络的表情识别 &#x1f348;流程图 &#x1f348;模型设计 &#x1f34d;网络架…

复旦微JFMVU3P-2FFVC1517 FPGA+AI全国产化人工智能数据处理平台,适用于雷达与中频信号采集、视频图像采集

板载FPGA实时处理器&#xff1a;JFMVU3P-2FFVC1517支持1个FMC&#xff08;HPC&#xff09;扩展接口支持2路QSFP光纤接口支持x8 Gen3 PCIE主机接口&#xff0c;系统带宽&#xff1e;5GByte/s支持1个R45自适应千兆以太网口支持1个GPIO/RS422接口 基于复旦微16nm工艺JFM9VU3P FPG…

【Linux】记录一起网站劫持事件

故事很短&#xff0c;处理也简单。权当记录一下&#xff0c;各位安全大大们手下留情。 最近一位客户遇到官网被劫持的情况&#xff0c;想我们帮忙解决一下&#xff08;本来不关我们的事&#xff0c;毕竟情面在这…还是无偿地协助一下&#xff09;&#xff0c;经过三四轮“谦让…

Java-SpringBoot启动报端口被占用,如何找到占用端口的进程并杀掉

背景 当我们本地启动多个项目&#xff0c;可能会出现端口被占用的情况&#xff0c;当然有时候可能idea窗口关闭&#xff0c;但是进程并没有kill掉&#xff0c;导致再次启动项目时也会报端口被占用的错误。 通常的做法是打开任务管理器&#xff0c;然后kill掉对应的进程。 首先…

“除了C盘都不见了“:现象解析、恢复策略与预防之道

现象概述&#xff1a;非系统盘突然消失之谜 在日常的计算机使用中&#xff0c;不少用户可能遭遇过一个令人措手不及的问题——“除了C盘都不见了”。这一现象发生时&#xff0c;用户惊讶地发现除了作为系统盘的C盘外&#xff0c;原本存放着各类文档、图片、视频等个人资料的D盘…

在一行中实现每个盒子间隔相等

达成效果&#xff1a; 1. 使用justify-content: space-evenly; <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

Nginx Lua Waf 插件一键部署

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

直播平台集成美颜工具详解:视频美颜SDK开发指南

本篇文章&#xff0c;小编将详细介绍如何在直播平台中集成美颜工具&#xff0c;帮助开发者更好地理解视频美颜SDK的开发过程。 一、美颜工具的作用和原理 1.1 美颜工具的作用 美颜工具主要用于提升直播视频的画面质量&#xff0c;让主播和观众在镜头前看起来更加美观。这些功…

哈喽GPT-4o,程序员如何通过GPT-4o提高工作效率

目录 一、编写代码Prompt&#xff1a;请用Java语言编写一个二分查找的样例 二、修正代码错误、代码优化Prompt&#xff1a;我们上传一张华为OD算法题的题目描述&#xff0c;再给它我的Java解题代码&#xff0c;问问它有什么问题&#xff1f; 三、解读代码功能、代码翻译Prompt&…