找回密码
 立即注册
首页 业界区 业界 MybatisPlus使用详情

MybatisPlus使用详情

氛疵 2025-9-26 10:41:26
一、简介

1.1 概述

MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatisPlus官网:https://baomidou.com/
1.2 特性


  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本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操作智能分析阻断,也可自定义拦截规则,预防误操作
1.3 支持的数据库

任何能使用MyBatis进行CRUD,并且支持标准SQL的数据库,具体支持情况如下,如果不在下列表查看分页部分教程PR您的支持。

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
1.4 核心架构

1.jpeg

二、入门案例

创建测试表
  1. DROP TABLE IF EXISTS user;
  2. CREATE TABLE `user`
  3. (
  4.     `id`       bigint(20) NOT NULL COMMENT '主键ID',
  5.     `name`     varchar(30) DEFAULT NULL COMMENT '姓名',
  6.     `sex`      char(1)     DEFAULT NULL COMMENT '性别 0:男 1:女',
  7.     `age`      int(11)     DEFAULT NULL COMMENT '年龄',
  8.     `birthday` date        DEFAULT NULL COMMENT '生日',
  9.     PRIMARY KEY (`id`)
  10. );
  11. INSERT INTO `user` VALUES (1, 'Jone', '1', 27, '2001-10-04');
  12. INSERT INTO `user` VALUES (2, 'Jack', '0', 20, '1999-10-04');
  13. INSERT INTO `user` VALUES (3, 'Tom', '1', 28, '1996-08-12');
  14. INSERT INTO `user` VALUES (4, 'Sandy', '1', 21, '2001-10-04');
  15. INSERT INTO `user` VALUES (5, 'Billie', '0', 24, '1992-09-07');
  16. INSERT INTO `user` VALUES (6, 'Jackson', '0', 18, '1996-08-12');
  17. INSERT INTO `user` VALUES (7, 'Hardy', '1', 25, '1992-09-07');
  18. INSERT INTO `user` VALUES (8, 'Rose', '1', 21, '1992-09-07');
  19. INSERT INTO `user` VALUES (9, 'June', '0', 28, '1992-09-07');
  20. INSERT INTO `user` VALUES (10, 'Aidan', '0', 17, '2001-10-04');
复制代码
引入依赖
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>com.test</groupId>
  7.     01_MyBatisPlus</artifactId>
  8.     <version>1.0-SNAPSHOT</version>
  9.     <parent>
  10.         <groupId>org.springframework.boot</groupId>
  11.         spring-boot-starter-parent</artifactId>
  12.         <version>2.6.3</version>
  13.         <relativePath/>
  14.     </parent>
  15.     <dependencies>
  16.         
  17.         <dependency>
  18.             <groupId>org.springframework.boot</groupId>
  19.             spring-boot-starter</artifactId>
  20.         </dependency>
  21.         
  22.         <dependency>
  23.             <groupId>org.springframework.boot</groupId>
  24.             spring-boot-starter-test</artifactId>
  25.             <scope>test</scope>
  26.         </dependency>
  27.         
  28.         <dependency>
  29.             <groupId>com.baomidou</groupId>
  30.             mybatis-plus-boot-starter</artifactId>
  31.             <version>3.4.2</version>
  32.         </dependency>
  33.         
  34.         <dependency>
  35.             <groupId>junit</groupId>
  36.             junit</artifactId>
  37.             <version>4.13</version>
  38.             <scope>test</scope>
  39.         </dependency>
  40.         
  41.         <dependency>
  42.             <groupId>mysql</groupId>
  43.             mysql-connector-java</artifactId>
  44.         </dependency>
  45.         
  46.         <dependency>
  47.             <groupId>org.projectlombok</groupId>
  48.             lombok</artifactId>
  49.         </dependency>
  50.     </dependencies>
  51. </project>
复制代码
实体类
  1. package com.test.entity;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class User {
  9.     private Long id;
  10.     private String name;
  11.     private String sex;
  12.     private Integer age;
  13.     private String birthday;
  14. }
复制代码
Mapper接口
  1. package com.test.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.test.entity.User;
  4. import org.apache.ibatis.annotations.Mapper;
  5. @Mapper
  6. public interface UserMapper extends BaseMapper<User> {
  7. }
复制代码
application.yml
  1. spring:
  2.   datasource:
  3.     driver-class-name: com.mysql.jdbc.Driver
  4.   url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=GMT%2b8
  5.   username: root
  6.   password: admin
  7. #配置日志
  8. mybatis-plus:
  9.   configuration:
  10.     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
复制代码
启动类
  1. package com.test;
  2. import org.mybatis.spring.annotation.MapperScan;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. @SpringBootApplication
  6. @MapperScan("com.test.mapper")
  7. public class MyBatisPlusApplication {
  8.     public static void main(String[] args) {
  9.         SpringApplication.run(MyBatisPlusApplication.class, args);
  10.     }
  11. }
复制代码
测试类
  1. package com.test;
  2. import com.test.entity.User;
  3. import com.test.mapper.UserMapper;
  4. import org.junit.Assert;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import java.util.List;
  10. import javax.annotation.Resource;
  11. @SpringBootTest(classes = MyBatisPlusApplication.class)
  12. @RunWith(SpringRunner.class)
  13. public class Demo01 {
  14.     @Resource
  15.     private UserMapper userMapper;
  16.     @Test
  17.     public void testSelect() {
  18.         // 传递null代表查询全部
  19.         List<User> userList = userMapper.selectList(null);
  20.         for (User user : userList) {
  21.             System.out.println(user);
  22.         }
  23.     }
  24. }
复制代码
三、BaseMapper接口

在MyBatisPlus中,我们编写的Mapper接口都继承与MyBatisPlus提供的BaseMapper接口,BaseMapper接口包含了MyBatisPlus帮我们提供操作数据库的一系列方法;
官网案例:https://baomidou.com/pages/49cc81/#mapper-crud-接口
使用示例:
  1. package com.test;
  2. import com.test.entity.User;
  3. import com.test.mapper.UserMapper;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import java.util.Arrays;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import javax.annotation.Resource;
  12. @SpringBootTest(classes = MyBatisPlusApplication.class)
  13. @RunWith(SpringRunner.class)
  14. public class Demo01_BaseMapper {
  15.     @Resource
  16.     private UserMapper userMapper;
  17.     /**
  18.      * 新增
  19.      * INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
  20.      */
  21.     @Test
  22.     public void insert() {
  23.         User user = new User(100L, "Ken", "0", 20);
  24.         userMapper.insert(user);
  25.     }
  26.     /**
  27.      * 修改
  28.      * UPDATE user SET name=?, age=?, email=? WHERE id=?
  29.      */
  30.     @Test
  31.     public void update() {
  32.         User user = new User(100L, "Kevin", "0", 25);
  33.         userMapper.updateById(user);
  34.     }
  35.     /**
  36.      * 根据id查询
  37.      * SELECT id,name,age,email FROM user WHERE id=?
  38.      */
  39.     @Test
  40.     public void selectById() {
  41.         User user = userMapper.selectById(100L);
  42.         System.out.println(user);
  43.     }
  44.     /**
  45.      * 根据一批id查询
  46.      * SELECT id,name,age,email FROM user WHERE id IN ( ?, ?, ? )
  47.      */
  48.     @Test
  49.     public void selectBatchIds() {
  50.         List<User> userList = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
  51.         for (User user : userList) {
  52.             System.out.println(user);
  53.         }
  54.     }
  55.     /**
  56.      * 根据条件查询数据
  57.      * SELECT id,name,age,email FROM user WHERE name = ? AND id = ?
  58.      */
  59.     @Test
  60.     public void selectByMap() {
  61.         // 封装条件
  62.         HashMap<String, Object> param = new HashMap<>();
  63.         param.put("id", 10L);
  64.         param.put("name", "Kevin");
  65.         // 根据条件查询,map中的多个条件是并列关系 id=10 and name='小灰灰'
  66.         List<User> userList = userMapper.selectByMap(param);
  67.         for (User user : userList) {
  68.             System.out.println(user);
  69.         }
  70.     }
  71.     /**
  72.      * 根据id删除
  73.      * DELETE FROM user WHERE id=?
  74.      */
  75.     @Test
  76.     public void deleteById() {
  77.         userMapper.deleteById(100L);
  78.     }
  79.     /**
  80.      * 根据id删除一批
  81.      * DELETE FROM user WHERE id IN ( ?, ?, ? )
  82.      */
  83.     @Test
  84.     public void deleteBatchIds() {
  85.         userMapper.deleteBatchIds(Arrays.asList(1, 2, 3));
  86.     }
  87.     /**
  88.      * 根据条件删除数据
  89.      * DELETE FROM user WHERE name = ? AND id = ?
  90.      */
  91.     @Test
  92.     public void deleteByMap() {
  93.         // 封装条件
  94.         HashMap<String, Object> param = new HashMap<>();
  95.         param.put("id", 100L);
  96.         param.put("name", "Kevin");
  97.         userMapper.deleteByMap(param);
  98.     }
  99. }
复制代码
四、Wrapper接口

通过BaseMapper提供的一些方法我们可以完成一些基本的CRUD,但无法完成复杂条件的查询;对于复杂条件的查询,MyBatisPlus提供了Wrapper接口来处理;
Wrapper是MyBatisPlus提供的一个条件构造器,主要用于构建一系列条件,当Wrapper构建完成后,可以使用Wrapper中的条件进行查询、修改、删除等操作;
Wrapper的继承体系如下:

Wrapper是条件构造抽象类,最顶端父类,其主要实现类有如下:

  • AbstractWrapper:用于查询条件封装,生成sql的where条件

    • QueryWrapper:Query条件封装
    • UpdateWrapper:Update条件封装
    • AbstractLambdaWrapper:使用Lambda语法

      • LambdaQueryWrapper:基于Lambda语法使用的查询Wrapper
      • LambdaUpdateWrapper:基于Lambda语法使用的更新Wrapper


官方文档:https://baomidou.com/pages/10c804/
4.1 基本方法

AbstractWrapper是其他常用Wrapper的父类,用于生成sql的where条件
4.1.1 方法介绍

AbstractWrapper提供了很多公有的方法,其子类全部具备这些方法,方法列表如下:
方法名解释示例eq等于 =eq(“name”, “老王”)--->
name = ‘老王’ne不等于 ne(“name”, “老王”)--->
name  ‘老王’gt大于 >gt(“age”, 18)--->
age > 18ge大于等于 >=ge(“age”, 18)--->
age >= 18lt小于 </tdtdlt(“age”, 18)strong---></strong>
age < 18le小于等于 </strong>
age </strong>
age between 18 and 30notBetweennot between 值1 and 值2notBetween(“age”, 18, 30)--->
age not between 18 and 30likeLIKE ‘%值%’like(“name”, “王”)--->      
     name like ‘%王%’notLikeNOT LIKE ‘%值%’notLike(“name”, “王”)--->
name not like ‘%王%’likeLeftLIKE ‘%值’likeLeft(“name”, “王”)--->
name like ‘%王’likeRightLIKE ‘值%’likeRight(“name”, “王”)--->         
name like ‘王%’isNull字段 IS NULLisNull(“name”)--->                  
     name is nullisNotNull字段 IS NOT NULLisNotNull(“name”)--->            
   name is not nullin字段 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)groupBy分组:GROUP BY 字段, …groupBy(“id”, “name”)--->
group by id,nameorderByAsc排序:ORDER BY 字段, … ASCorderByAsc(“id”, “name”)--->
order by id ASC,name ASCorderByDesc排序:ORDER BY 字段, … DESCorderByDesc(“id”, “name”)--->
order by id DESC,name DESCorderBy排序:ORDER BY 字段, …orderBy(true, true, “id”, “name”)--->
order by id ASC,name ASChavingHAVING ( sql语句 )例1:having(“sum(age) > 10”)--->  
  having sum(age) > 10
例2:having(“sum(age) > {0}”, 11)--->
having sum(age) > 11func主要解决条件拼接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 > 18last无视优化规则直接拼接到 sql 的最后last(“limit 1”) --->   
在SQL语句最后面拼接:limit 1exists拼接 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)创建Wrapper对象:

  • Wrappers静态方法:

    • public static  QueryWrapper query()

  • 通过QueryWrapper对象的构造方法:

    • public QueryWrapper()

代码示例:
  1. @SpringBootTest(classes = MyBatisPlusApplication.class)
  2. @RunWith(SpringRunner.class)
  3. public class Demo02_Wrapper {
  4.     @Resource
  5.     private UserMapper userMapper;
  6.     /**
  7.      * QueryWrapper的创建
  8.      * SELECT id,name,age,email FROM user
  9.      */
  10.     @Test
  11.     public void test1() {
  12.         // 创建QueryWrapper,默认情况下查询所有数据
  13.         QueryWrapper<User> wrapper = Wrappers.query();
  14.         QueryWrapper<User> wrapper2 = new QueryWrapper<>();
  15.         List<User> users = userMapper.selectList(wrapper);
  16.         users.forEach(System.out::println);
  17.     }
  18. }
复制代码
4.1.2 基本方法的使用

官网案例:https://baomidou.com/pages/10c804/#abstractwrapper
使用示例:
  1. @Test
  2. public void test2() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // name ='Jack'
  5.     // wrapper.eq("name","Jack");
  6.     //参数1: 是否要进行name条件的拼接
  7.     String name = "Jack";
  8.     wrapper.eq(StringUtils.isNotBlank(name), "name", name);
  9.     // name != 'Jack'
  10.     // wrapper.ne("name","Jack");
  11.     // age > 20
  12.     // wrapper.gt("age",20);
  13.     // age < 20
  14.     // wrapper.lt("age",20);
  15.     // age=20
  16.     // wrapper.lt("age",20);
  17.     // age between 20 and 24
  18.     // wrapper.between("age",20,24);
  19.     // age not between 20 and 24
  20.     // wrapper.notBetween("age",20,24);
  21.     // name like "%J%"   自动拼接左右的%
  22.     // wrapper.like("name","J");
  23.     // name not like "%J%"
  24.     // wrapper.notLike("name","J");
  25.     // name like "%J"
  26.     // wrapper.likeLeft("name","J");
  27.     // name like 'J%'
  28.     // wrapper.likeRight("name","J");
  29.     // name is null
  30.     // wrapper.isNull("name");
  31.     // name is not null
  32.     // wrapper.isNotNull("name");
  33.     // name in ('Jack','Tom','Jone')
  34.     // wrapper.in("name","Jack","Tom","Jone");
  35.     // name not in ('Jack','Tom','Jone')
  36.     // wrapper.notIn("name","Jack","Tom","Jone");
  37.     List<User> users = userMapper.selectList(wrapper);
  38.     users.forEach(System.out::println);
  39. }
复制代码
4.1.3 子查询

示例代码:
  1. @Test
  2. public void test3() {
  3.     // 创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     // 相当于: name in (select name from user where age > 21)
  6.     wrapper.inSql("name", "select name from user where age > 21");
  7.     // 相当于: name not in (select name from user where age > 21)
  8.     // wrapper.notInSql("name","select name from user where age > 21");
  9.     List<User> users = userMapper.selectList(wrapper);
  10.     users.forEach(System.out::println);
  11. }
复制代码
4.1.4 分组与排序

1)分组:
通过Wrapper.query()构建的查询字段默认是表中的所有字段,因此在这种情况下分组是没有意义的,分组具体的用法我们后面再详细介绍;
  1. @Test
  2. public void test4() {
  3.     // 创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     // 相当于 select * from user where group sex
  6.     // 这是一个没有意义的分组,分组必须结合查询的字段来体现,后续学QueryWrapper的select方法再介绍
  7.     wrapper.groupBy("sex");
  8.     List<User> users = userMapper.selectList(wrapper);
  9.     users.forEach(System.out::println);
  10. }
复制代码
2)having操作
  1. @Test
  2. public void test5() {
  3.     // 创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     // group by sex having sex = 0
  6.     wrapper.groupBy("sex");
  7.     wrapper.having("sex", "0");
  8.     List<User> users = userMapper.selectList(wrapper);
  9.     users.forEach(System.out::println);
  10. }
复制代码
3)排序:
  1. @Test
  2. public void test6() {
  3.     //  创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     /**
  6.      * 参数1: 是否是Asc排序(升序), true : asc排序, false: desc排序
  7.      * 参数2: 排序的字段
  8.      */
  9.     // wrapper.orderByAsc("age");                // order by age asc
  10.     // wrapper.orderByDesc("age");                // order by age desc
  11.     List<User> users = userMapper.selectList(wrapper);
  12.     users.forEach(System.out::println);
  13. }
复制代码
4.1.5 多条件的拼接

Wrapper对象在调用每一个方法时都会返回当前对象(Wrapper),这样可以很好的方便我们链式编程;另外MyBatisPlus在拼接多个条件时默认使用and拼接,如果需要使用or,那么需要显示的调用or()方法;
1)and拼接条件:
  1. @Test
  2. public void test7() {
  3.     //创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     // 默认情况下,多条件是以and拼接
  6.     // SQL语句: name LIKE "%a%" AND age > 20 AND sex = 0
  7.     wrapper.like("name", "%a%")
  8.             .lt("age", 20)
  9.             .eq("sex", 0);
  10.     List<User> users = userMapper.selectList(wrapper);
  11.     users.forEach(System.out::println);
  12. }
复制代码
2)or拼接条件:
  1. @Test
  2. public void test8() {
  3.     //  创建wrapper对象
  4.     QueryWrapper<User> wrapper = Wrappers.query();
  5.     /*
  6.     默认情况下,多条件是以and拼接
  7.     SQL语句: name LIKE "%a%" OR age > 20 AND sex = 0
  8.     */
  9.     wrapper.like("name", "%a%")
  10.             .or()
  11.             .lt("age", 20)
  12.             .eq("sex", 0);   // 该条件仍然以AND拼接
  13.     List<User> users = userMapper.selectList(wrapper);
  14.     users.forEach(System.out::println);
  15. }
复制代码
4.1.6 其他方法

1)and方法:用于拼接一个其他的整体条件;示例如下:
  1. @Test
  2. public void test1() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // 生成的SQL为: (age < ? AND (sex = ? OR name LIKE ?))
  5.    
  6. //    wrapper.lt("age", 20);
  7. //    wrapper.and(new Consumer<QueryWrapper<User>>() {
  8. //        @Override
  9. //        public void accept(QueryWrapper<User> userQueryWrapper) {
  10. //            userQueryWrapper.eq("sex", 0)
  11. //                    .or()
  12. //                    .like("name", "J");
  13. //        }
  14. //    });
  15.   
  16.     // 生成的SQL为:  (age < ? AND sex = ? OR name LIKE ?)
  17.     wrapper.lt("age", 20)
  18.             .eq("sex", 0)
  19.             .or()
  20.             .like("name", "J");
  21.     List<User> users = userMapper.selectList(wrapper);
  22.     users.forEach(System.out::println);
  23. }
复制代码
2)func方法:用于多条件的拼接,直接使用之前的方法也可以做到这个功能;示例如下:
  1. @Test
  2. public void test2() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // 生成的SQL语句条件: (age < ? AND name LIKE ? AND sex = ?)
  5.     wrapper.lt("age", 20);
  6.     wrapper.func(new Consumer<QueryWrapper<User>>() {
  7.         @Override
  8.         public void accept(QueryWrapper<User> userQueryWrapper) {
  9.             userQueryWrapper.like("name", "a");
  10.             userQueryWrapper.eq("sex", "0");
  11.         }
  12.     });
  13.     // 等价于:
  14. //    wrapper.lt("age", 20)
  15. //            .like("name", "a")
  16. //            .eq("sex", "0");
  17.     List<User> users = userMapper.selectList(wrapper);
  18.     users.forEach(System.out::println);
  19. }
复制代码
3)nested方法:功能等价于and方法
  1. @Test
  2. public void test3() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // 生成的SQL语句条件为: (id = ? AND (name LIKE ? OR age > ?))
  5.     // nested()等价于and方法()
  6.     wrapper.eq("id", 1);
  7.     wrapper.nested(new Consumer<QueryWrapper<User>>() {
  8.         @Override
  9.         public void accept(QueryWrapper<User> userQueryWrapper) {
  10.             // 默认情况下是用and来拼接多个条件
  11.             userQueryWrapper.like("name", "a")
  12.                     .or().gt("age", 20);
  13.         }
  14.     });
  15.     List<User> users = userMapper.selectList(wrapper);
  16.     users.forEach(System.out::println);
  17. }
复制代码
4)apply方法:可以使用占位符进行参数传参;示例如下:
  1. @Test
  2. public void test4() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // SQL: (name like ? and age > ?)
  5.     // wrapper.apply("name like {0} and age > {1}", "%J%", 18);
  6.     // SQL: (date_format(birthday, '%Y-%m-%d') = ?)
  7.     wrapper.apply("date_format(birthday, '%Y-%m-%d') = {0}", "2001-10-04");
  8.     List<User> users = userMapper.selectList(wrapper);
  9.     users.forEach(System.out::println);
  10. }
复制代码
5)last方法:无视优化规则直接拼接到 sql 的最后,只能调用一次,多次调用以最后一次为准 有sql注入的风险
Tips:apply方法可以防止SQL注入,但last方法不能;
  1. @Test
  2. public void test5() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // 无视优化规则直接拼接到 sql 的最后,只能调用一次,多次调用以最后一次为准 有sql注入的风险
  5.     // SQL: name = 'Jone'
  6.     // String name = "Jone";
  7.     // wrapper.last("where name = '" + name + "'");
  8.     // SQL: SELECT id,name,sex,age FROM user where name ='' or 1=1; -- '
  9.     String name = "' or 1=1; -- ";
  10.     wrapper.last("where name ='" + name + "'");  // 出现SQL注入问题
  11.     List<User> users = userMapper.selectList(wrapper);
  12.     users.forEach(System.out::println);
  13. }
复制代码
6)exists方法:用于exists语句
  1. @Test
  2. public void test6() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // SQL: (EXISTS (select 1))
  5.     wrapper.exists("select 1");
  6.     List<User> users = userMapper.selectList(wrapper);
  7.     users.forEach(System.out::println);
  8. }
复制代码
7)notExists方法:
  1. @Test
  2. public void test7() {
  3.     QueryWrapper<User> wrapper = Wrappers.query();
  4.     // SQL: (NOT EXISTS (select 1))
  5.     wrapper.notExists("select 1");
  6.     List<User> users = userMapper.selectList(wrapper);
  7.     users.forEach(System.out::println);
  8. }
复制代码
4.2 QueryWrapper

QueryWrapper是AbstractWrapper的子类,主要用于查询指定字段,方法列表如下:
方法名解释示例select(String… sqlSelect)设置查询字段例1:select(“id”, “name”, “age”)
例2:select(i -> i.getProperty().startsWith(“test”))示例代码:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  4. import com.test.entity.User;
  5. import com.test.mapper.UserMapper;
  6. import org.junit.Test;
  7. import org.junit.runner.RunWith;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. @SpringBootTest(classes = MyBatisPlusApplication.class)
  13. @RunWith(SpringRunner.class)
  14. public class Demo04_QueryWrapper {
  15.     @Resource
  16.     private UserMapper userMapper;
  17.     // 选择查询的字段
  18.     @Test
  19.     public void test1() throws Exception {
  20.         QueryWrapper<User> wrapper = Wrappers.query();
  21.         // 确定要查询的字段
  22.         wrapper.select("id", "name", "sex");
  23.         // in
  24.         wrapper.in("id", "1", "2");
  25.         // SQL: SELECT id,name,sex FROM user WHERE (id IN (?,?))
  26.         List<User> userList = userMapper.selectList(wrapper);
  27.         userList.forEach(System.out::println);
  28.     }
  29.     @Test
  30.     public void test2() throws Exception {
  31.         User user = new User();
  32.         user.setId(1L);
  33.         // user当做查询的条件
  34.         QueryWrapper<User> wrapper = Wrappers.query(user);
  35.         // 指定查询的列
  36.         wrapper.select("id", "name", "sex");
  37.         // SQL: SELECT id,name,sex FROM user WHERE id=?
  38.         List<User> userList = userMapper.selectList(wrapper);
  39.         userList.forEach(System.out::println);
  40.     }
  41. }
复制代码
4.3 UpdateWrapper

UpdateWrapper也是AbstractWrapper的子类,因此UpdateWrapper也具备之前的那些查询方法,不同的是,UpdateMapper在那些方法基础之上还提供了很多有关于更新操作的方法;
方法如下:
方法名解释示例set(String column, Object val)设置查询字段例1:set("name", "老李头")
例2:set("name", "")
—>数据库字段值变为空字符串
例3:set("name", null)
—>数据库字段值变为nullsetSql(String sql)设置set子句的部分SQL例1:setSql("name = '老李头'")  
例2:setSql("name = '老李头',age=20 where id=1")示例代码:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  3. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  4. import com.test.entity.User;
  5. import com.test.mapper.UserMapper;
  6. import org.junit.Test;
  7. import org.junit.runner.RunWith;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. @SpringBootTest(classes = MyBatisPlusApplication.class)
  13. @RunWith(SpringRunner.class)
  14. public class Demo05_UpdateWrapper {
  15.     @Resource
  16.     private UserMapper userMapper;
  17.     @Test
  18.     public void test1() throws Exception {
  19.         UpdateWrapper<User> wrapper = Wrappers.update();
  20.         // UpdateWrapper也是AbstractWrapper的子类,因此也具备一些基本的查询方法
  21.         wrapper.like("name", "J");
  22.         List<User> userList = userMapper.selectList(wrapper);
  23.         for (User user : userList) {
  24.             System.out.println(user);
  25.         }
  26.     }
  27.     /**
  28.      * 第一种方法: 使用wrapper来修改,并且指定查询条件
  29.      *
  30.      * @throws Exception
  31.      */
  32.     @Test
  33.     public void test2() throws Exception {
  34.         UpdateWrapper<User> wrapper = Wrappers.update();
  35.         wrapper.set("name", "Jackson");
  36.         wrapper.set("age", "16");
  37.         wrapper.set("sex", "1");
  38.         wrapper.eq("id", 2L);
  39.         // SQL: UPDATE user SET name=?, sex=?, age=? WHERE (id = ?)
  40.         userMapper.update(null, wrapper);
  41.     }
  42.     /**
  43.      * 第二种方法: 使用wrapper来封装条件,使用entity来封装修改的数据
  44.      *
  45.      * @throws Exception
  46.      */
  47.     @Test
  48.     public void test3() throws Exception {
  49.         UpdateWrapper<User> wrapper = Wrappers.update();
  50.         wrapper.eq("id", 2L);
  51.         User user = new User(null, "Jack", "0", 28);
  52.         // SQL: UPDATE user SET name=?, sex=?, age=? WHERE (id = ?)
  53.         userMapper.update(user, wrapper);
  54.     }
  55.     /**
  56.      * 第三种方法: Wrappers.update(user)传递查询的条件,使用wrapper来修改
  57.      *
  58.      * @throws Exception
  59.      */
  60.     @Test
  61.     public void test4() throws Exception {
  62.         User user = new User();
  63.         user.setId(1L);
  64.         // user当做查询条件
  65.         UpdateWrapper<User> wrapper = Wrappers.update(user);
  66.         wrapper.set("name", "xiaohui");
  67.         wrapper.set("sex", "0");
  68.         wrapper.set("age", "22");
  69.         // SQL : UPDATE user SET name=?,sex=?,age=? WHERE id=?
  70.         userMapper.update(null, wrapper);
  71.     }
  72.     /**
  73.      * setSql方法
  74.      *
  75.      * @throws Exception
  76.      */
  77.     @Test
  78.     public void test5() throws Exception {
  79.         UpdateWrapper<User> wrapper = Wrappers.update();
  80.         wrapper.setSql("name='abc',sex='0',age=18 where id=1");
  81.         // SQL: UPDATE user SET name='abc',sex='0',age=18 where id=1
  82.         userMapper.update(null, wrapper);
  83.     }
  84. }
复制代码
4.4 LambdaQueryWrapper

LambdaQueryWrapper是QueryWrapper的子类,具备QueryWrapper的所有方法,QueryWrapper的方法上提供了一系列有关于方法引的操作;
使用示例:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5. import com.test.entity.User;
  6. import com.test.mapper.UserMapper;
  7. import org.junit.Test;
  8. import org.junit.runner.RunWith;
  9. import org.springframework.boot.test.context.SpringBootTest;
  10. import org.springframework.test.context.junit4.SpringRunner;
  11. import java.util.List;
  12. import javax.annotation.Resource;
  13. @SpringBootTest(classes = MyBatisPlusApplication.class)
  14. @RunWith(SpringRunner.class)
  15. public class Demo06_LambdaQueryWrapper {
  16.     @Resource
  17.     private UserMapper userMapper;
  18.     /**
  19.      * 使用QueryWrapper
  20.      * @throws Exception
  21.      */
  22.     @Test
  23.     public void test1() throws Exception {
  24.         QueryWrapper<User> wrapper = Wrappers.query();
  25.         wrapper.eq("id", "1");
  26.         List<User> userList = userMapper.selectList(wrapper);
  27.         for (User user : userList) {
  28.             System.out.println(user);
  29.         }
  30.     }
  31.     /**
  32.      * 使用LambdaQueryWrapper
  33.      * @throws Exception
  34.      */
  35.     @Test
  36.     public void test2() throws Exception {
  37.         LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
  38.         // id=1
  39.         // wrapper.eq(User::getId,1);
  40.         // select id,name,age from user where id in (1,2,3) and name like "%a%"
  41.         wrapper.in(User::getId, "1", "2", "3")
  42.                 .like(User::getName, "a")
  43.                 .select(User::getId, User::getName, User::getAge);
  44.         List<User> userList = userMapper.selectList(wrapper);
  45.         for (User user : userList) {
  46.             System.out.println(user);
  47.         }
  48.     }
  49. }
复制代码
4.5 LambdaUpdateMapper

LambdaUpdateMapper同样是UpdateMapper的子类,具备UpdateMapper的所有方法,UpdateMapper的方法上提供了一系列有关于方法引的操作;
示例代码:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  4. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5. import com.test.entity.User;
  6. import com.test.mapper.UserMapper;
  7. import org.junit.Test;
  8. import org.junit.runner.RunWith;
  9. import org.springframework.boot.test.context.SpringBootTest;
  10. import org.springframework.test.context.junit4.SpringRunner;
  11. import javax.annotation.Resource;
  12. @SpringBootTest(classes = MyBatisPlusApplication.class)
  13. @RunWith(SpringRunner.class)
  14. public class Demo07_LambdaUpdateWrapper {
  15.     @Resource
  16.     private UserMapper userMapper;
  17.     /**
  18.      * 使用UpdateWrapper
  19.      *
  20.      * @throws Exception
  21.      */
  22.     @Test
  23.     public void test1() throws Exception {
  24.         UpdateWrapper<User> wrapper = Wrappers.update();
  25.         wrapper.eq("id", "1");
  26.         wrapper.set("name", "xiaohui");
  27.         wrapper.set("age", 20);
  28.         userMapper.update(null, wrapper);
  29.     }
  30.     /**
  31.      * 使用LambdaUpdateWrapper
  32.      *
  33.      * @throws Exception
  34.      */
  35.     @Test
  36.     public void test2() throws Exception {
  37.         LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate();
  38.         wrapper.eq(User::getId, "1");
  39.         wrapper.set(User::getName, "xiaolan");
  40.         wrapper.set(User::getAge, 18);
  41.         userMapper.update(null, wrapper);
  42.     }
  43. }
复制代码
五、Mapper分页查询

5.1 配置

在MyBatis中提供有Page对象来帮助我们实现分页查询,在Page对象中有如下成员:
成员变量说明List getRecords()当前页数据public long getTotal()总记录数public long getSize()页大小public long getCurrent()当前页default long getPages()总页数public boolean hasNext()是否有上一页public boolean hasPrevious()是否有上一页MyBatisPlus的分页逻辑底层是通过分页插件来完成的,因此我们首先要配置MyBatisPlus的分页插件;
配置分页插件:
  1. package com.test.config;
  2. import com.baomidou.mybatisplus.annotation.DbType;
  3. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  4. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. @Configuration
  9. @MapperScan("com.test.mapper")          // mapper接口的所在位置
  10. public class MyBatisPlusConfig {
  11.     @Bean
  12.     public MybatisPlusInterceptor mybatisPlusInterceptor() {
  13.         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  14.         interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  15.         return interceptor;
  16.     }
  17. }
复制代码
5.2 分页查询

在BaseMapper中主要提供有如下方法来完成分页查询:

  • E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper):

    • 参数1:分页配置类
    • 参数2:分页查询条件
    • 解释:根据分页配置和分页查询条件来完成分页查询,当前页数据为指定类型

  • E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper)

    • 参数1:分页配置类
    • 参数2:分页查询条件
    • 解释:根据分页配置和分页查询条件来完成分页查询,当前页数据为Map类型

1)无条件分页查询:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.test.entity.User;
  6. import com.test.mapper.UserMapper;
  7. import org.junit.Test;
  8. import org.junit.runner.RunWith;
  9. import org.springframework.boot.test.context.SpringBootTest;
  10. import org.springframework.test.context.junit4.SpringRunner;
  11. import java.util.List;
  12. import javax.annotation.Resource;
  13. @SpringBootTest(classes = MyBatisPlusApplication.class)
  14. @RunWith(SpringRunner.class)
  15. public class Demo06_BaseMapper {
  16.     @Resource
  17.     private UserMapper userMapper;
  18.     /**
  19.      * 无条件分页查询
  20.      * @throws Exception
  21.      */
  22.     @Test
  23.     public void test1() throws Exception {
  24.         // 封装分页信息
  25.         Page<User> page = new Page<>(1, 3);
  26.         /*
  27.         执行分页查询,并将结果封装到page中
  28.         参数1: 分页配置
  29.         参数2: 查询条件
  30.         */
  31.         userMapper.selectPage(page, null);
  32.         // 当前页数据
  33.         List<User> pageData = page.getRecords();
  34.         for (User user : pageData) {
  35.             System.out.println(user);
  36.         }
  37.         System.out.println("------------");
  38.         System.out.println("当前页:" + page.getCurrent());
  39.         System.out.println("每页显示的条数:" + page.getSize());
  40.         System.out.println("总记录数:" + page.getTotal());
  41.         System.out.println("总页数:" + page.getPages());
  42.         System.out.println("是否有上一页:" + page.hasPrevious());
  43.         System.out.println("是否有下一页:" + page.hasNext());
  44.     }
  45. }
复制代码
查询结果:
  1. # 首先查询总记录数
  2. ==>  Preparing: SELECT COUNT(*) FROM user
  3. ==> Parameters:
  4. <==    Columns: COUNT(*)
  5. <==        Row: 10
  6. <==      Total: 1
  7. # 再查询分页
  8. ==>  Preparing: SELECT id,name,sex,age FROM user LIMIT ?
  9. ==> Parameters: 3(Long)
  10. <==    Columns: id, name, sex, age
  11. <==        Row: 1, Jone, 1, 27
  12. <==        Row: 2, Jack, 0, 20
  13. <==        Row: 3, Tom, 1, 28
  14. <==      Total: 3
  15. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@226eba67]
  16. User(id=1, name=Jone, sex=1, age=27)
  17. User(id=2, name=Jack, sex=0, age=20)
  18. User(id=3, name=Tom, sex=1, age=28)
  19. ------------
  20. 当前页:1
  21. 每页显示的条数:3
  22. 总记录数:10
  23. 总页数:4
  24. 是否有上一页:false
  25. 是否有下一页:true
  26. 2022-11-15 15:28:16 INFO 8724 --- com.zaxxer.hikari.HikariDataSource: HikariPool-1 - Shutdown initiated...
  27. 2022-11-15 15:28:16 INFO 8724 --- com.zaxxer.hikari.HikariDataSource: HikariPool-1 - Shutdown completed.
  28. Process finished with exit code 0
复制代码
九、ActiveRecord使用

9.1 ActiveRecord简介

ActiveRecord也属于ORM(对象关系映射)层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。
ActiveRecord的主要思想是:
1)每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录,通常表的每个字段在类中都有相应的Field;
2)ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;
3)ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑。
简而言之,AR建立了Java对象与数据库表逻辑上的直接映射,方便了程序的编写。而在MyBatisPlus中使用AR非常简单,只需让JavaBean继承Model类即可。
9.2 Model类使用

在MyBatisPlus中,只要将我们的JavaBean继承与Model类即可获取AR功能,即JavaBean自身实现自身的CURD;
让JavaBean继承Model:
  1. /**
  2. * 带条件分页查询
  3. *
  4. * @throws Exception
  5. */
  6. @Test
  7. public void test2() throws Exception {
  8.     QueryWrapper<User> wrapper = Wrappers.query();
  9.     wrapper.like("name", "a");
  10.     // 封装分页信息
  11.     Page<User> page = new Page<>(1, 3);
  12.     /*
  13.     执行分页查询,并将结果封装到page中
  14.     参数1: 分页配置
  15.     参数2: 查询条件
  16.     */
  17.     userMapper.selectPage(page, wrapper);
  18.     // 当前页数据
  19.     List<User> pageData = page.getRecords();
  20.     for (User user : pageData) {
  21.         System.out.println(user);
  22.     }
  23.     System.out.println("------------");
  24.     System.out.println("当前页:" + page.getCurrent());
  25.     System.out.println("每页显示的条数:" + page.getSize());
  26.     System.out.println("总记录数:" + page.getTotal());
  27.     System.out.println("总页数:" + page.getPages());
  28.     System.out.println("是否有上一页:" + page.hasPrevious());
  29.     System.out.println("是否有下一页:" + page.hasNext());
  30. }
复制代码
测试代码:
  1.   ==>  Preparing: SELECT COUNT(*) FROM user WHERE (name LIKE ?)
  2.   ==> Parameters: %a%(String)
  3.   <==    Columns: COUNT(*)
  4.   <==        Row: 5
  5.   <==      Total: 1
  6.   ==>  Preparing: SELECT id,name,sex,age FROM user WHERE (name LIKE ?) LIMIT ?
  7.   ==> Parameters: %a%(String), 3(Long)
  8.   <==    Columns: id, name, sex, age
  9.   <==        Row: 2, Jack, 0, 20
  10.   <==        Row: 4, Sandy, 1, 21
  11.   <==        Row: 6, Jackson, 0, 18
  12.   <==      Total: 3
  13.   Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58a2b4c]
  14.   User(id=2, name=Jack, sex=0, age=20)
  15.   User(id=4, name=Sandy, sex=1, age=21)
  16.   User(id=6, name=Jackson, sex=0, age=18)
  17. ------------
  18. 当前页:1
  19. 每页显示的条数:3
  20. 总记录数:5
  21. 总页数:2
  22. 是否有上一页:false
  23. 是否有下一页:true
复制代码
十、多数据源配置

1)引入多数据源依赖:
  1. /**
  2. * 查询结果以Map返回
  3. *
  4. * @throws Exception
  5. */
  6. @Test
  7. public void test3() throws Exception {
  8.     // 封装分页信息
  9.     Page page = new Page<>(1, 3);
  10.     userMapper.selectMapsPage(page, null);
  11.     // 每一条记录都是一个HashMap
  12.     List<HashMap<String, Object>> pageData = page.getRecords();
  13.     for (HashMap userMap : pageData) {
  14.         System.out.println(userMap);
  15.     }
  16.     System.out.println("------------");
  17.     System.out.println("当前页:" + page.getCurrent());
  18.     System.out.println("每页显示的条数:" + page.getSize());
  19.     System.out.println("总记录数:" + page.getTotal());
  20.     System.out.println("总页数:" + page.getPages());
  21.     System.out.println("是否有上一页:" + page.hasPrevious());
  22.     System.out.println("是否有下一页:" + page.hasNext());
  23. }
复制代码
2)准备两个数据库
  1.   ==>  Preparing: SELECT COUNT(*) FROM user
  2.   ==> Parameters:
  3.   <==    Columns: COUNT(*)
  4.   <==        Row: 10
  5.   <==      Total: 1
  6.   ==>  Preparing: SELECT id,name,sex,age FROM user LIMIT ?
  7.   ==> Parameters: 3(Long)
  8.   <==    Columns: id, name, sex, age
  9.   <==        Row: 1, Jone, 1, 27
  10.   <==        Row: 2, Jack, 0, 20
  11.   <==        Row: 3, Tom, 1, 28
  12.   <==      Total: 3
  13.   Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7123be6c]
  14.   {sex=1, name=Jone, id=1, age=27}
  15.   {sex=0, name=Jack, id=2, age=20}
  16.   {sex=1, name=Tom, id=3, age=28}
  17. ------------
  18. 当前页:1
  19. 每页显示的条数:3
  20. 总记录数:10
  21. 总页数:4
  22. 是否有上一页:false
  23. 是否有下一页:true
  24. 2022-11-15 15:50:37 INFO 20980 --- com.zaxxer.hikari.HikariDataSource: HikariPool-1 - Shutdown initiated...
  25. 2022-11-15 15:50:37 INFO 20980 --- com.zaxxer.hikari.HikariDataSource: HikariPool-1 - Shutdown completed.
  26. Process finished with exit code 0
复制代码
3)多数据源配置:
  1. package com.test.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.test.entity.User;
  4. public interface IUserService extends IService<User> {
  5. }
复制代码
4)启动类:
  1. package com.test;
  2. import org.mybatis.spring.annotation.MapperScan;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. @SpringBootApplication
  6. @MapperScan("com.test.mapper")
  7. public class MyBatisPlusApplication {
  8.     public static void main(String[] args) {
  9.         SpringApplication.run(MyBatisPlusApplication.class, args);
  10.     }
  11. }
复制代码
5)实体类:
  1. package com.test;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  4. import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
  5. import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
  6. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  7. import com.test.entity.User;
  8. import com.test.service.IUserService;
  9. import org.junit.Test;
  10. import org.junit.runner.RunWith;
  11. import org.springframework.boot.test.context.SpringBootTest;
  12. import org.springframework.test.context.junit4.SpringRunner;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import javax.annotation.Resource;
  16. @SpringBootTest(classes = MyBatisPlusApplication.class)
  17. @RunWith(SpringRunner.class)
  18. public class Demo07_Service {
  19.     @Resource
  20.     private IUserService userService;
  21.     /**
  22.      * 新增
  23.      *
  24.      * @throws Exception
  25.      */
  26.     @Test
  27.     public void test1() throws Exception {
  28.         User user = new User(null, "xiaohui", "0", 20);
  29.         userService.save(user);
  30.     }
  31.     /**
  32.      * 如果id存在则修改,不存在则新增
  33.      *
  34.      * @throws Exception
  35.      */
  36.     @Test
  37.     public void test2() throws Exception {
  38.         User user = new User(1L, "xiaohui", "0", 20);
  39.         userService.saveOrUpdate(user);
  40.     }
  41.     /**
  42.      * 根据id删除
  43.      *
  44.      * @throws Exception
  45.      */
  46.     @Test
  47.     public void test3() throws Exception {
  48.         userService.removeById(1L);
  49.     }
  50.     /**
  51.      * 根据id修改
  52.      *
  53.      * @throws Exception
  54.      */
  55.     @Test
  56.     public void test4() throws Exception {
  57.         User user = new User(1L, "xiaolan", "1", 18);
  58.         userService.updateById(user);
  59.     }
  60.     /**
  61.      * 根据id查询
  62.      *
  63.      * @throws Exception
  64.      */
  65.     @Test
  66.     public void test5() throws Exception {
  67.         User user = userService.getById(1L);
  68.         System.out.println(user);
  69.     }
  70.     /**
  71.      * 查询列表
  72.      *
  73.      * @throws Exception
  74.      */
  75.     @Test
  76.     public void test6() throws Exception {
  77.         QueryWrapper<User> wrapper = Wrappers.query();
  78.         wrapper.in("id", "1", "2");
  79.         // 查询所有
  80.         // List<User> userList = userService.list();
  81.         // 通过wrapper查询
  82.         List<User> userList = userService.list(wrapper);
  83.         for (User user : userList) {
  84.             System.out.println(user);
  85.         }
  86.     }
  87.     /**
  88.      * 查询总记录数
  89.      *
  90.      * @throws Exception
  91.      */
  92.     @Test
  93.     public void test7() throws Exception {
  94.         QueryWrapper<User> wrapper = Wrappers.query();
  95.         wrapper.like("name", "a");
  96.         // 查询总记录数
  97.         //int count = userService.count();
  98.         // 根据条件查询总记录数
  99.         int count = userService.count(wrapper);
  100.         System.out.println(count);
  101.     }
  102.     /**
  103.      * 分页查询(当前页类型为指定类型)
  104.      *
  105.      * @throws Exception
  106.      */
  107.     @Test
  108.     public void test8() throws Exception {
  109.         Page<User> page = new Page<>(1, 3);
  110.         userService.page(page);
  111.         // 当前页数据
  112.         List<User> pageData = page.getRecords();
  113.         for (User user : pageData) {
  114.             System.out.println(user);
  115.         }
  116.         System.out.println("------------");
  117.         System.out.println("当前页:" + page.getCurrent());
  118.         System.out.println("每页显示的条数:" + page.getSize());
  119.         System.out.println("总记录数:" + page.getTotal());
  120.         System.out.println("总页数:" + page.getPages());
  121.         System.out.println("是否有上一页:" + page.hasPrevious());
  122.         System.out.println("是否有下一页:" + page.hasNext());
  123.     }
  124.    
  125.     /**
  126.      * 分页查询(当前页结果为HashMap类型)
  127.      *
  128.      * @throws Exception
  129.      */
  130.     @Test
  131.     public void test9() throws Exception {
  132.         Page page = new Page<>(1, 3);
  133.         userService.pageMaps(page);
  134.         // 当前页数据
  135.         List<HashMap<String, Object>> pageData = page.getRecords();
  136.         for (HashMap userMap : pageData) {
  137.             System.out.println(userMap);
  138.         }
  139.         System.out.println("------------");
  140.         System.out.println("当前页:" + page.getCurrent());
  141.         System.out.println("每页显示的条数:" + page.getSize());
  142.         System.out.println("总记录数:" + page.getTotal());
  143.         System.out.println("总页数:" + page.getPages());
  144.         System.out.println("是否有上一页:" + page.hasPrevious());
  145.         System.out.println("是否有下一页:" + page.hasNext());
  146.     }
  147.    
  148.     /**
  149.      * 链式查询
  150.      *
  151.      * @throws Exception
  152.      */
  153.     @Test
  154.     public void test10() throws Exception {
  155.         QueryChainWrapper<User> chainWrapper = userService.query();
  156.         // SQL: SELECT id,name,age FROM user WHERE (id IN (?,?,?) AND name LIKE ?)
  157.         List<User> userList = chainWrapper.select("id", "name", "age")
  158.                 .in("id", "1", "2", "3")
  159.                 .like("name", "a")
  160.                 .list();
  161.         for (User user : userList) {
  162.             System.out.println(user);
  163.         }
  164.     }
  165.    
  166.     /**
  167.      * 链式修改
  168.      *
  169.      * @throws Exception
  170.      */
  171.     @Test
  172.     public void test11() throws Exception {
  173.         UpdateChainWrapper<User> chainWrapper = userService.update();
  174.         // SQL: UPDATE user SET age=? WHERE (id IN (?,?) OR sex = ?)
  175.         chainWrapper.in("id","1","2")
  176.                 .or()
  177.                 .eq("sex","0")
  178.                 .set("age",20)
  179.                 .update();
  180.     }
  181. }
复制代码
6)编写两个Mapper:
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @TableName("t_user")
  5. public class User {
  6.     private Long id;
  7.     private String name;
  8.     private String sex;
  9.     private Integer age;
  10. }
复制代码
  1. mybatis-plus:
  2.   global-config:         # MyBatisPlus全局配置
  3.     db-config:          # 配置数据库
  4.       table-prefix: t_  #配置表名前缀为t_
复制代码
7)测试类:
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @TableName("t_user")
  5. public class User {
  6.     // 将当前属性所对应的字段作为主键
  7.     @TableId
  8.     private Long id;
  9.     private String name;
  10.     private String sex;
  11.     private Integer age;
  12. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册