自学笔记:Mybatis-Plus


Mybatis-Plus

使用中的问题合集

1.从数据库中查询的数据无法封装进实体类对象

实体类的属性(对应表中的字段)都使用驼峰式命名。

例如Student表中,有一个字段stu_name

则对应实体类中为private String stuName,不能直接命名为stu_name


简介

什么是Mybatis-plus?
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 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 查询
  • 分页插件支持多种数据库:支持 MySQLMariaDBOracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

快速入门

  1. 环境准备,mysql数据库准备一张表。为了简单演示,我准备了一个student表,只有id和name两个属性,其中随便插点数据即可。
    在这里插入图片描述

  2. 创建一个springboot项目,导入mybatis-plusmysql的启动器。

    <dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter</artifactId>
    		</dependency>
    
    		<!--导入mysql数据库-->
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<!--导入mybatis-plus启动器-->
    		<dependency>
    			<groupId>com.baomidou</groupId>
    			<artifactId>mybatis-plus-boot-starter</artifactId>
    			<version>3.4.1</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
  3. 配置配置文件:配置连接数据库的信息

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql:///test01?serverTimezone=Asia/Shanghai
        username: root
        password: root
    
  4. 编写实体类Student.class(略)

  5. 编写mapper,继承BaseMapper

    public interface StudentMapper extends BaseMapper<Student> {
    }
    
  6. 在启动类上添加@MapperScan注解,扫描mapper包。

    @SpringBootApplication
    @MapperScan("com.sixu.mapper")
    public class BaomidouMybatisPlusApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(BaomidouMybatisPlusApplication.class, args);
    	}
    }
    
  7. 接下来就可以编写测试类了,进行测试。

    @SpringBootTest
    class BaomidouMybatisPlusApplicationTests {
    	@Autowired
    	private StudentMapper studentMapper;
    
    	@Test
    	void test01() {
    		List<Student> list = studentMapper.selectList(null);	//UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件
    		for (Student student : list) {
    			System.out.println(student);
    		}
    	}
    }
    
  8. 结果演示:
    在这里插入图片描述

这次入门,便能认识到Mybatis-plus的简便之处,甚至连简单的sql语句都省略了。


代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

顾名思义,就是自动生成那些简单结构的代码。

演示:

  1. 添加依赖:

    注意:MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖

    模板引擎:MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。

    注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

    AutoGenerator generator = new AutoGenerator();
    
    // set freemarker engine
    generator.setTemplateEngine(new FreemarkerTemplateEngine());
    
    // set beetl engine
    generator.setTemplateEngine(new BeetlTemplateEngine());
    
    // set custom engine (reference class is your custom engine class)
    generator.setTemplateEngine(new CustomTemplateEngine());
    
    // other config
    ...
    
    		<!--导入mybatis-plus启动器-->
    		<dependency>
    			<groupId>com.baomidou</groupId>
    			<artifactId>mybatis-plus-boot-starter</artifactId>
    			<version>3.4.1</version>
    		</dependency>
    		<!--添加 代码生成器 依赖-->
    		<dependency>
    			<groupId>com.baomidou</groupId>
    			<artifactId>mybatis-plus-generator</artifactId>
    			<version>3.4.1</version>
    		</dependency>
    		<!--添加 模板引擎 依赖-->
    		<dependency>
    			<groupId>org.apache.velocity</groupId>
    			<artifactId>velocity-engine-core</artifactId>
    			<version>2.2</version>
    		</dependency>
    
  2. 编写自动生成代码类,在其中编写配置

    public class MyCodeGenerator {
        public static void Generator() {
            String projectPath = System.getProperty("user.dir");
    
            // 全局配置
            GlobalConfig globalConfig = new GlobalConfig();
            globalConfig.setOutputDir(projectPath + "/quickStart/src/main/java")
                    .setAuthor("sixu")              //设置作者名字
                    .setBaseResultMap(true)         //SQL 映射文件
                    .setBaseColumnList(true)        //SQL 片段
                    .setOpen(false);
    
            // 数据源配置
            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig.setUrl("jdbc:mysql:///test01?serverTimezone=Asia/Shanghai")
                    .setDriverName("com.mysql.jdbc.Driver")
                    .setUsername("root")
                    .setPassword("root");
    
            //配置包路径
            PackageConfig pc = new PackageConfig();
            pc.setParent("com.sixu")        //配置父包路径
                    .setModuleName("mybatisPlusAutoGenerator")      //配置业务包路径
                    .setMapper("mapper")
                    .setEntity("entity")
                    .setService("service")
                    .setController("controller");
    
            // 自定义配置
            InjectionConfig cfg = new InjectionConfig() {
                @Override
                public void initMap() {
                    // to do nothing
                }
            };
    
            //下面的模板引擎是 velocity,如果模板引擎是freemarker,则 String templatePath = "/templates/mapper.xml.ftl"
            String templatePath = "/templates/mapper.xml.vm";
            // 自定义输出配置
            List<FileOutConfig> focList = new ArrayList<>();
            // 自定义配置会被优先输出
            focList.add(new FileOutConfig(templatePath) {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                    return projectPath + "/quickStart/src/main/resources/mapper/" + pc.getModuleName()
                            + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                }
            });
    
            cfg.setFileOutConfigList(focList);
    
            // 配置模板
            TemplateConfig templateConfig = new TemplateConfig();
            templateConfig.setXml(null);
    
            //策略配置
            StrategyConfig strategy = new StrategyConfig();
            strategy.setNaming(NamingStrategy.underline_to_camel)           //设置命名规则  underline_to_camel 底线变驼峰
                    .setColumnNaming(NamingStrategy.underline_to_camel)     //设置设置列命名  underline_to_camel 底线变驼峰
                    //.setSuperEntityClass()                                //你自己的父类实体,没有就不用设置!
                    //.setSuperControllerClass()                            //你自己的父类控制器,没有就不用设置!
                    .setEntityLombokModel(true)                             //是否加入lombok
                    .setInclude("student")                                  //设置表名
                    .setSuperEntityColumns("id")                            //设置超级超级列
                    .setControllerMappingHyphenStyle(true)                  //设置controller映射联字符
                    .setTablePrefix(pc.getModuleName() + "_");              //表的前缀
    
            // 代码生成器
            AutoGenerator mpg = new AutoGenerator();
            mpg.setGlobalConfig(globalConfig)
                    .setDataSource(dataSourceConfig)
                    .setPackageInfo(pc)
                    .setCfg(cfg)
                    .setTemplate(templateConfig)
                    .setStrategy(strategy)
                    .execute();
        }
    
        public static void main(String[] args) {
            Generator();        // 开始生成
        }
    }
    
  3. 开始生成

    • 生成前:
      在这里插入图片描述

    • 生成后:
      在这里插入图片描述

由此可见,这个代码自动生成极大的减轻了程序员的负担。

但同时也提醒我们,要不断学习,现在这个时代,不进步就是在退步。


CRUD接口

Mapper层CRUD

MybatisPlus内置了mapper层的简单的CURD操作。

只需要mapper层的接口继承BaseMappe<T\>,然后再启动类添加注解@MapperScan()将mapper层扫描进去。

    • 方法

      int insert(T entity);		//entity代表一个实体类对象
      

    案例:

    • service层
        /*增*/
        public void addStudent(Student student){
            studentMapper.insert(student);
        }
    
    • controller层

         @GetMapping("addStudent/{name}")
         public String addStudent(String name){
             studentService.addStudent(new Student("mapper层增加测试"));
             return "增加成功";
         }
      
    • 测试:

    在这里插入图片描述

    • 方法

      // 根据 ID 删除
      int deleteById(Serializable id);
      // 根据 entity 条件,删除记录
      int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
      // 删除(根据ID 批量删除)
      int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
      // 根据 columnMap 条件,删除记录
      int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
      

    案例:

    • service层

          /*删*/
          public void delStudent(int id){
              studentMapper.deleteById(id);
          }
      
    • controller层

          @GetMapping("deleteStu/{id}")
          public String deleteStu(@PathVariable int id){
              studentService.delStudent(id);
              return "删除成功";
          }
      
    • 测试:
      在这里插入图片描述

    • 方法

      // 根据 whereEntity 条件,更新记录
      int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
      // 根据 ID 修改
      int updateById(@Param(Constants.ENTITY) T entity);
      

    案例:

    • service层

          /*改*/
          public void updateStu(Student student){
              studentMapper.updateById(student);
          }
      
    • controller层

          @GetMapping("updateStu/{id}/{name}")
          public String updateStu(@PathVariable int id,@PathVariable String name){
              studentService.updateStu(new Student(id,name));
              return "修改id:"+id+" 的学生成功";
          }
      
    • 测试:
      在这里插入图片描述

    • 方法
    //单条记录查询
    T selectById(Serializable id);		// 根据 ID 查询										
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);		// 根据 entity 条件,查询一条记录
    
    //多条记录查询
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);		// 查询(根据ID 批量查询)
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);		// 根据 entity 条件,查询全部记录。为null时代表不设条件,查询全部记录
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);		// 查询(根据 columnMap 条件)
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);		// 根据 Wrapper 条件,查询全部记录
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
    
    //多条记录分页查询
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);		// 根据 entity 条件,查询全部记录(并翻页)
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);		// 根据 Wrapper 条件,查询全部记录(并翻页)
    
    // 根据 Wrapper 条件,查询总记录数
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    

    案例:

    • service层:

          /*查*/
          public List<Student> findAll(){
              List<Student> students = studentMapper.selectList(null);
              return students;
          }
      
    • controller层:

          @GetMapping("findStudent")
          public String findStudent(){
              return studentService.findAll().toString();
          }
      
    • 测试:
      在这里插入图片描述


Service层CRUD

MybatisPlus 也内置了servic层的一些简单操作。

步骤:

  1. 自定义sevice接口,继承IService(T)
    在这里插入图片描述

  2. 再自定义service的实现类,实现自定义接口service接口,同时继承ServiceImpl(M extends BaseMapper<T>,T)。

    在这里插入图片描述

    如上图:我在实现Student01Service 的同时又继承了ServiceImpl,并且将StudentMapper作为泛型传入,所以在controller可以同时使用mapper层和service层的内置方法。为了将servie层方法和mapper层方法区分开来,service层的方法都是以save(增) 、remove(删)、update(改)、get|list|page|count (查) 开头的。

  • 查询

    1. 查询单条:get

      // 根据 ID 查询
      T getById(Serializable id);
      // 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
      T getOne(Wrapper<T> queryWrapper);
      // 根据 Wrapper,查询一条记录
      T getOne(Wrapper<T> queryWrapper, boolean throwEx);
      // 根据 Wrapper,查询一条记录
      Map<String, Object> getMap(Wrapper<T> queryWrapper);
      // 根据 Wrapper,查询一条记录
      <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
      
    2. 查询多条:list

      List<T> list();		// 查询所有
      List<T> list(Wrapper<T> queryWrapper);		// 查询列表
      Collection<T> listByIds(Collection<? extends Serializable> idList);		// 查询(根据ID 批量查询)
      Collection<T> listByMap(Map<String, Object> columnMap);		// 查询(根据 columnMap 条件)
      List<Map<String, Object>> listMaps();		// 查询所有列表
      List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);		// 查询列表
      List<Object> listObjs();		// 查询全部记录
      <V> List<V> listObjs(Function<? super Object, V> mapper);		// 查询全部记录
      List<Object> listObjs(Wrapper<T> queryWrapper);		// 根据 Wrapper 条件,查询全部记录
      <V> List<V> listObjs(Wrpper<T> queryWrapper, Function<? super Object, V> mapper);		// 根据 Wrapper 条件,查询全部记录
      
    3. 分页查询:page

      IPage<T> page(IPage<T> page);		// 无条件分页查询,page 表示翻页对象
      IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);		// 条件分页查询
      IPage<Map<String, Object>> pageMaps(IPage<T> page);		// 无条件分页查询
      IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);		// 条件分页查询
      
    4. 查询记录数:count

      int count();		// 查询总记录数
      int count(Wrapper<T> queryWrapper);		// 根据 Wrapper 条件,查询总记录数
      
  • 新增save

    // 插入一条记录(选择字段,策略插入)
    boolean save(T entity);
    // 插入(批量)
    boolean saveBatch(Collection<T> entityList);
    // 插入(批量)
    boolean saveBatch(Collection<T> entityList, int batchSize);
    
  • 删除:remove

    // 根据 entity 条件,删除记录
    boolean remove(Wrapper<T> queryWrapper);
    // 根据 ID 删除
    boolean removeById(Serializable id);
    // 根据 columnMap 条件,删除记录
    boolean removeByMap(Map<String, Object> columnMap);
    // 删除(根据ID 批量删除)
    boolean removeByIds(Collection<? extends Serializable> idList);
    
  • 修改:update

    // 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
    boolean update(Wrapper<T> updateWrapper);
    // 根据 whereEntity 条件,更新记录
    boolean update(T entity, Wrapper<T> updateWrapper);
    // 根据 ID 选择修改
    boolean updateById(T entity);
    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList);
    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList, int batchSize);
    

条件构造器

参考:https://blog.csdn.net/m0_46159545/article/details/107161814

在mybatisplus中,使用内置的mapper层或service层查询语句时,需要传入一个参数,这个参数就是条件。

例如,在使用mapper层内置方法 selectList()方法时,如果传入参数为null则表示没有条件,查询全部。

如果需要给查询设置一些条件,例如上面例子student表,想要模糊查询name中带有 “sixu” 的学生,则需要传入条件构造器。

条件构造器体系
在这里插入图片描述

  • Wrapper: 条件构造抽象类,最顶端父类
  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件。
  • QueryWrapper : Entity 对象封装操作类,不是用lambda语法。适用于Mp的 查询或删除有关的条件。
  • UpdateWrapper : Update 条件封装,用于Entity对象更新操作。适和作为有关于Mp的修改的条件。
  • AbstractLambdaWrapper :Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
  • LambdaQueryWrapper :适用于Lambda语句,查询删除
  • LambdaUpdateWrapper :适用于Lambda语句,修改。

其实QueryWrapperUpdateWrapper的大多数方法都是继承自AbstractWrapper,两者在大部分条件下都是可以互相替换的。使用方法也很简单,只需要new一个条件对象,然后使用方法来设置条件即可,接下来介绍那些可以设置条件的方法。

AbstractWrapper

说明:

  • 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为Wrapper的子类实例(均具有AbstractWrapper的所有方法)
  • 以下方法在入参中出现的R为泛型,在普通wrapper中是String,在LambdaWrapper中是函数(例:Entity::getId,Entity为实体类,getId为字段idgetMethod)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!
  • 使用中如果入参的Map或者List,则不会加入最后生成的sql中!!!
  • 有任何疑问就点开源码看,看不懂函数的,点击我学习新知识

下面简单介绍一下经常使用到的方法。

  1. eq、ne、lt、gt、le、ge

    • eq:等于 =

      eq("name", "老王");		//	name ='sixu'
      
    • ne:不等于 <>

      ne("name", "老王");		//	name <> 'sixu'
      
    • lt:小于 <

      lt("id",10);		//	id < 10
      
    • gt: 大于 >

      gt("id",10);		//	id > 10
      
    • le: 小于等于 <=

      le("id",10);		//	id <= 10
      
    • ge: 大于等于 >=

      gt("id",10);		//	id >= 10
      
  2. isNull、isNotNull

    isNull:字段 IS NULL

    isNull(R column)
    isNull(boolean condition, R column)
    isNull("name");		//name is null
    

    isNotNull:字段 IS NOT NULL

    isNotNull(R column)
    isNotNull(boolean condition, R column)
    isNotNull("name");		//name is not null
    
  3. like、notLike、likeLeft、likeRight

    • like:用于模糊查询 Like ‘%值%’

      like(R column, Object val)
      like(boolean condition, R column, Object val)
      like("name","si");		//	name LIKE '%si%'
      
    • notLike: not Like ‘%值%’

      notLike(R column, Object val)
      notLike(boolean condition, R column, Object val)
      notLike("name","si");		//	name NOT LIKE '%si%'
      
    • likeLeft:Like ‘%值’

      likeLeft(R column, Object val)
      likeLeft(boolean condition, R column, Object val)
      likeLeft("name","xu");		//Like '%xu', 表示以‘xu’结尾
      
    • likeRight:Like ‘值%’

      likeRight(R column, Object val)
      likeRight(boolean condition, R column, Object val)
      likeRight("name","si");		//Like 'si%', 表示以'si'开头
      
  4. between、notbetween

    between:BETWEEN 值1 AND 值2

    between(R column, Object val1, Object val2)
    between(boolean condition, R column, Object val1, Object val2)
    between("id",0,10);		//BETWEEN 0 AND 10			
    

    notbetween:NOT BETWEEN 值1 AND 值2

    notBetween(R column, Object val1, Object val2)
    notBetween(boolean condition, R column, Object val1, Object val2)
    notBetween("id",0,10);		//NOT BETWEEN 0 AND 10		
    
  5. in、notIn、inSql、notInSql、exists、notExists

    • in:IN (v1,v2,…,vn)

      in(R column, Collection<?> value)
      in(boolean condition, R column, Collection<?> value)
      in("id",{1,5,8})		//	id in (1,5,8)
      
    • notIn:NOT IN (v1,v2,…,vn),可以传入数组形式的参数,也可以传入Object类型的多个参数。

      notIn(R column, Collection<?> value)
      notIn(boolean condition, R column, Collection<?> value)
      notIn(R column, Object... values)
      notIn(boolean condition, R column, Object... values)
      notIn("age",{1,2,3})		//age not in (1,2,3)
      notIn("age", 1, 2, 3)		//age not in (1,2,3)
      
    • inSql:与in的区别在于传入参数,in的传入参数一般是数组或者集合(继承于Collection);而 insql的传入参数是以字符串形式的(可以直接传入一个复杂的SQL语句)。

      inSql(R column, String inValue)
      inSql(boolean condition, R column, String inValue)
      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)
      
    • notInSql:参数是字符串,sql语句

      notInSql(R column, String inValue)
      notInSql(boolean condition, R column, String inValue)
      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)
      
    • exists:拼接EXISTS语句

      EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。如何其子句有结果,就相当于True。

      例如:下面两个sql语句的效果相同。

      假设有两张表,TableIn 和TableEx ,要查询TableIn 表中ANAME与TableEx 表中BNAME相同的信息。

      select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
      select * from TableIn where ANAME in(select BNAME from TableEx)

      exists(String existsSql)
      exists(boolean condition, String existsSql)
      exists("select id from table where age = 1")		//exists (select id from table where age = 1)
      
    • notExists:拼接NOTEXISTS语句

      notExists(String notExistsSql)
      notExists(boolean condition, String notExistsSql)
      notExists("select id from table where age = 1")		//not exists (select id from table where age = 1)
      
  6. or、and

    • or:拼接OR。

      注意:主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)

      or()
      or(boolean condition)
      eq("id",1).or().eq("name","老王")		//id = 1 or name = '老王'
      
    • and:拼接and

      and(Consumer<Param> consumer)
      and(boolean condition, Consumer<Param> consumer)
      and(i -> i.eq("name", "李白").ne("status", "活着"))		//and (name = '李白' and status <> '活着')
      
  7. groupBy

    groupBy(R... columns)
    groupBy(boolean condition, R... columns)
    groupBy("id", "name")		//group by id,name
    
  8. orderBy、orderByAsc、orderByDesc

    • orderBy

      orderBy(boolean condition, boolean isAsc, R... columns)
      orderBy(true, true, "id", "name")		//order by id ASC,name ASC
      
    • orderByAsc:默认升序

      orderByAsc(R... columns)
      orderByAsc(boolean condition, R... columns)
      orderByAsc("id", "name")		//order by id ASC,name ASC
      
    • orderByDesc:默认降序


QueryWrapper

继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件。

可以通过 new QueryWrapper().lambda() 方法获取LambdaQueryWrapper

select

select(String... sqlSelect)
select(Predicate<TableFieldInfo> predicate)
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)

UpdateWrapper

继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件。
可以通过 new UpdateWrapper().lambda() 方法获取LambdaUpdateWrapper

  1. set

    set(String column, Object val)
    set(boolean condition, String column, Object val)
    set("name", "思绪")
    
  2. setSql

    setSql(String sql)
    setSql("name = '思绪'")
    

查询结果分页

​ 以快速入门环境为例,在该案例的基础上,进行改造,实现分页浏览;

  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. 然后再mapper中定义一个方法

            @Select("select * from student")
            IPage<Student> selectPageVo(Page<Student> page);
    
  3. service层

        /*分页查询*/
        @Override
        public IPage<Student> selectPageVo(Page<Student> page) {
            return studentMapper.selectPageVo(page);
        }
    
  4. controller层

        @GetMapping("selectPageVo/{pageNum}")
        public String selectPageVo(@PathVariable int pageNum){
            IPage<Student> studentIPage=new Page<Student>(pageNum,3);       //第一个参数表示当前第几页,第二个参数表示每页最大记录
            studentIPage=studentService.selectPageVo((Page<Student>) studentIPage);
            List<Student> lists = studentIPage.getRecords();
            return lists.toString();
        }
    
  5. 测试:
    在这里插入图片描述


已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页