Mybatis插件之Mybatis-Plus(一)

2023-05-16

目录

一、简介

二、开发时注意事项:

1.Mybatis + MP(纯Mybatis与Mybatis-Plus整合)

2.Spring + Mybatis + MP

3.SpringBoot + Mybatis + MP

三、通用的CRUD

1. 注解

2.CRUD

四、配置

1.基本配置

2.进阶配置

3. DB 策略配置

五、条件构造器

1.allEq

2.基本比较操作

3.模糊查询

4.排序

5.逻辑查询

6. select


一、简介

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

文档地址:https://mybatis.plus/guide/

源码地址:https://github.com/baomidou/mybatis-plus

MP架构

二、开发时注意事项:

1.Mybatis + MP(纯Mybatis与Mybatis-Plus整合)

1)将UserMapper继承BaseMapper,将拥有BaseMapper中所有方法

2)出现table表不存在的时候需要在User对象中添加@TableName,指定数据库表名  

3)mybatis和mybatis—plus的写法略有不同,在获取方法的时候mybatis需要写出方法比如findAll但是mp自带方法selectList可以直接使用,只需要接口继承基础类

2.Spring + Mybatis + MP

引入了Spring框架,数据源、构建等工作就交给了Spring管理

1)applicationContext.xml写法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="classpath:*.properties"/>

    <!-- 定义数据源 -->
    <!--在测试的时候${jdbc.url}可能会找不到,原因是这个配置文件放在了main文件夹下,而不是test文件夹下,这时有两种解决办法
        要么就把${jdbc.url}写死,要么就把文件applicationContest.xml放在test文件夹下,其他的视情况而定
    -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="5"/>
    </bean>

    <!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="globalConfig">
            <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">
                <property name="dbConfig">
                    <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                        <property name="idType" value="AUTO"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!--扫描mapper接口,使用的依然是Mybatis原生的扫描器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.itcast.mp.simple.mapper"/>
    </bean>

2)基于spring的测试要加上这两行,并且用注解注入mapper

3.SpringBoot + Mybatis + MP

使用SpringBoot将进一步的简化MP的整合,需要注意的是,由于使用SpringBoot需要继承parent,所以需要重新创建工程,并不是创建子Module

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <groupId>cn.itcast.mp</groupId>
    <artifactId>itcast-mp-springboot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--简化代码的工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--mybatis-plus的springboot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2)基于springboot的测试要加上这两行,并且用注解注入mapper

三、通用的CRUD

1. 注解

@TableId

@TableId(type = IdType.AUTO)//指定id类型为自增长,可以在数据库中设置下一个自增长的数字

MP支持的id策略

//生成ID类型枚举类

AUTO(0),//数据库ID自增

NONE(1),//该类型为未设置主键类型

INPUT(2),/* 用户输入ID,<p>该类型可以通过自己注册自动填充插件进行填充</p>

/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */

ID_WORKER(3),//全局唯一ID (idWorker)

UUID(4),//全局唯一ID (UUID)

ID_WORKER_STR(5);//字符串全局唯一ID (idWorker 的字符串表示)

@TableField

在MP中通过@TableField注解可以指定字段的一些属性,解决的问题有2个:

对象中的属性名和字段名不一致的问题(非驼峰)

对象中的属性字段在表中不存在的问题

2.CRUD

@RunWith(SpringRunner.class)//SpringRunner继承SpringJUnit4ClassRunner
//也可以写这个@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestUserMapper {

    @Autowired
    private UserMapper userMapper;

    //新增
    //更新
    //删除
    //查询
}

1)新增

//新增
    //int insert(T entity);
        //entity 实体对象
    @Test
    public void testInsert() {
        User user = new User();
        user.setMail("2@itcast.cn");
        user.setAge(301);
        user.setUserName("caocao1");
        user.setName("曹操1");
        user.setPassword("123456");
        user.setAddress("北京");

        int result = this.userMapper.insert(user); //result数据库受影响的行数
        System.out.println("result => " + result);

        //获取自增长后的id值, 自增长后的id值会回填到user对象中
        System.out.println("id => " + user.getId());
    }

2)更新

//更新  在MP中,更新操作有2种,一种是根据id更新,另一种是根据条件更新。
    //根据id更新
    //方法定义:int updateById(@Param(Constants.ENTITY) T entity);
        //entity 实体对象
    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L); //条件,根据id更新
        user.setAge(19); //更新的字段
        user.setPassword("666666");

        int result = this.userMapper.updateById(user);
        System.out.println("result => " + result);
    }
    //根据条件更新(有两种方法)
    //方法定义:int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
         //根据 whereEntity 条件,更新记录
         //entity 实体对象 (set 条件值,可以为 null)
         //updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

    //QueryWrapper和UpdateWrapper是有区别的,UpdateWrapper有.set方法
    @Test
    public void testUpdate() {
        User user = new User();
        user.setAge(20); //更新的字段
        user.setPassword("8888888");

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //eq后面都是字段的名字,不是属性的名字
        wrapper.eq("user_name", "zhangsan"); //匹配user_name = zhangsan 的用户数据

        //根据条件做更新
        int result = this.userMapper.update(user, wrapper);
        System.out.println("result => " + result);
    }
    @Test
    public void testUpdate2() {

        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.set("age", 21).set("password", "999999") //更新的字段
        .eq("user_name", "zhangsan"); //更新的条件

        //根据条件做更新
        int result = this.userMapper.update(null, wrapper);
        System.out.println("result => " + result);
    }

3)删除

  //删除
    //根据id删除数据
    //方法定义:int deleteById(Serializable id);
        //@param id 主键ID
    @Test
    public void testDeleteById(){
        int result = this.userMapper.deleteById(9L);
        System.out.println("result => " + result);
    }
    // 根据map删除数据,多条件之间是and关系
    //方法定义:int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
        //columnMap 表字段 map 对象
    @Test
    public void testDeleteByMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("user_name", "zhangsan");
        map.put("password", "999999");
        int result = this.userMapper.deleteByMap(map);
        System.out.println("result => " + result);
    }
    //根据条件删除
    //方法定义:int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
        //@param wrapper 实体对象封装操作类(可以为 null)
    @Test
    public void testDelete(){
        //用法一:
        /*
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", "caocao1")
                .eq("password", "123456");

        //根据包装条件做删除
        int result = this.userMapper.delete(wrapper);
        System.out.println("result => " + result);
        */

        //用法二:(推荐用法)
        User user = new User();
        user.setPassword("123456");
        user.setUserName("caocao");

        QueryWrapper<User> wrapper = new QueryWrapper<>(user);

        // 根据包装条件做删除
        int result = this.userMapper.delete(wrapper);
        System.out.println("result => " + result);
    }
    // 根据id批量删除数据
    //方法定义:int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
        //@param idList 主键ID列表(不能为 null 以及 empty)
    @Test
    public void  testDeleteBatchIds(){
        int result = this.userMapper.deleteBatchIds(Arrays.asList(10L, 11L));
        System.out.println("result => " + result);
    }

4)查询

 //查询   MP提供了多种查询操作,包括根据id查询、批量查询、查询单条数据、查询列表、分页查询等操作。
    //根据id进行查询
    //方法定义:T selectById(Serializable id);
        //@param id 主键ID
    @Test
    public void testSelectById() {
        User user = this.userMapper.selectById(2L);
        System.out.println(user);
    }
    // 根据id批量查询数据
    //方法定义:List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
        //@param idList 主键ID列表(不能为 null 以及 empty)
    @Test
    public void testSelectBatchIds(){
        List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 4L, 100L));
        for (User user : users) {
            System.out.println(user);
        }
    }
    //查询一条数据
    //方法定义:T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
        //@param queryWrapper 实体对象封装操作类(可以为 null)
    @Test
    public void testSelectOne(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //查询条件
        wrapper.eq("password", "123456");
        // 查询的数据超过一条时,会抛出异常,查询一条或没有数据时不会报错的
        User user = this.userMapper.selectOne(wrapper);
        System.out.println(user);
    }

    //根据 Wrapper 条件,查询总记录数
    //方法定义:Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
        //@param queryWrapper 实体对象封装操作类(可以为 null)
    @Test
    public void testSelectCount(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.gt("age", 20); // 条件:年龄大于20岁的用户

        // 根据条件查询数据条数
        Integer count = this.userMapper.selectCount(wrapper);
        System.out.println("count => " + count);
    }

    //查询全部记录
    //方法定义:List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
        //@param queryWrapper 实体对象封装操作类(可以为 null)
    @Test
    public void testSelectList(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.like("email", "itcast");

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

5)分页查询

//配置分页插件


package cn.itcast.mp;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("cn.itcast.mp.mapper") //设置mapper接口的扫描包
    //(有了配置类,@MapperScan就写在了这里,要不写在MyApplication.java中)

public class MybatisPlusConfig {
    @Bean  //配置分页插件
    public PaginationInterceptor paginationInterceptor() {//拦截器
        return new PaginationInterceptor();
    }
}

//上面是springboot中的配置,如果是mybatis原生器,就可以配置到mybatisConfig文件中
 // 测试分页查询
    //IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
        //@param page 分页查询条件(可以为 RowBounds.DEFAULT)
        //@param queryWrapper 实体对象封装操作类(可以为 null)
    @Test
    public void testSelectPage(){
        Page<User> page = new Page<>(3,1); //查询第一页,查询1条数据

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.like("email", "itcast");

        IPage<User> iPage = this.userMapper.selectPage(page, wrapper);
        System.out.println("数据总条数: " + iPage.getTotal());
        System.out.println("数据总页数: " + iPage.getPages());
        System.out.println("当前页数: " + iPage.getCurrent());

        List<User> records = iPage.getRecords();
        for (User record : records) {
            System.out.println(record);
        }

    }

四、配置

1.基本配置

指定全局配置文件需要加在application中

1]configLocation

MyBatis 配置文件位置,如果有单独的 MyBatis 配置,将其路径配置到 configLocation 中。 MyBatisConfiguration 的具体内容请参考MyBatis 官方文档

Spring Boot:

        mybatis-plus.config-location = classpath:1 mybatis-config.xml

Spring MVC:

        <bean id="sqlSessionFactory"

        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

                <property name="configLocation" value="classpath:mybatis-config.xml"/>

        </bean>

2]mapperLocations

MyBatis Mapper 所对应的 XML 文件位置,如果在 Mapper 中有自定义方法(XML 中有自定义实现),需要进行该配置,告诉所对应的 XML 文件位置。

Spring Boot:

        mybatis-plus.mapper-locations = classpath*:mybatis/*.xml

Spring MVC:

        <bean id="sqlSessionFactory"

        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

                <property name="mapperLocations" value="classpath*:mybatis/*.xml"/>

        </bean>

有*表示可以扫描依赖中所有的classpath下面的mybatis下面的.xml文件,没有*只扫描resources下面的.xml文件(因为application是在resources下面的)

Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)

3] typeAliasesPackage

MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在Mapper 对应的 XML 文件中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名)。

Spring Boot:

        mybatis-plus.type-aliases-package 1 = cn.itcast.mp.pojo

Spring MVC:

        <bean id="sqlSessionFactory"

        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

                <property name="typeAliasesPackage"

                        value="com.baomidou.mybatisplus.samples.quickstart.entity"/>

        </bean>

2.进阶配置

本部分(Configuration)的配置大都为 MyBatis 原生支持的配置,意味着可以通过 MyBatis XML 配置文件的形式进行配置。

1] mapUnderscoreToCamelCase

类型: Boolean               默认值: true

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射。

注意:此属性在 MyBatis 中原默认值为 false,在 MyBatis-Plus 中,此属性也将用于生成最终的 SQL 的 select body

如果数据库命名符合规则无需使用 @TableField 注解指定数据库字段名

Springboot:

        #关闭自动驼峰映射,该参数不能和mybatis-plus.config-location同时存在

        mybatis-plus.configuration.map-underscore-to-camel-case=false

2] cacheEnabled

 类型: Boolean               默认值: true

全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true。

(有需求的话就配置一下,没有需求不用配置)

        mybatis-plus.configuration.1 cache-enabled=false

3. DB 策略配置

1] idType

类型: com.baomidou.mybatisplus.annotation.IdType                默认值: ID_WORKER

全局默认主键类型,设置后,即可省略实体对象中的@TableId(type = IdType.AUTO)配置。

SpringBoot:

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

SpringMVC:

        <!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合-->

        <bean id="sqlSessionFactory"

        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

                <property name="dataSource" ref="dataSource"/>

                <property name="globalConfig">

                        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">

                                <property name="dbConfig">

                                        <bean

                              class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">

                                                <property name="idType" value="AUTO"/>

                                        </bean>

                                </property>

                        </bean>

                </property>

        </bean>

2] tablePrefix

类型: String        默认值: null

表名前缀,全局配置后可省略@TableName()配置。

SpringBoot:

        mybatis-plus.global-config.db-config.1 table-prefix=tb_

SpringMVC:

        <bean id="sqlSessionFactory"

        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

                <property name="dataSource" ref="dataSource"/>

                <property name="globalConfig">

                        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">

                                <property name="dbConfig">

                                        <bean

                              class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">

                                                <property name="idType" value="AUTO"/>

                                                <property name="tablePrefix" value="tb_"/>

                                        </bean>

                                </property>

                        </bean>

                </property>

        </bean>

五、条件构造器

在MP中,Wrapper接口的实现类关系如下:

AbstractWrapper和AbstractChainWrapper是重点实现,接下来我们重点学习AbstractWrapper以及其子类。

说明:

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类 用于生成 sql的 where 条件, entity 属性也用于生成 sql 的 where 条件 注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

官网文档地址:https://mybatis.plus/guide/wrapper.html 

1.allEq

 @Test
    public void testAllEq(){

        Map<String,Object> params = new HashMap<>();
        params.put("name", "李四");
        params.put("age", "20");
        params.put("password", null);

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //allEq
        //params : key 为数据库字段名, value 为字段值
        //null2IsNull : 为true 则在map 的value 为null 时调用 isNull 方法,为false 时则忽略value 为null 的
        //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE password IS NULL AND name = ? AND age = ?
        wrapper.allEq(params);
        //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? AND age = ?
        // false这个位置要判断是否为条件进行查询,false没有 is null这个条件,默认值true会有is null这个条件
        wrapper.allEq(params, false);

        //设置一个过滤 filter : 过滤函数,是否允许字段传入比对条件中 params 与 null2IsNull
        //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE age = ?
        wrapper.allEq((k, v) -> (k.equals("age") || k.equals("id")) , params);
        //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? AND age = ?
        wrapper.allEq((k, v) -> (k.equals("age") || k.equals("id") || k.equals("name")) , params);

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

2.基本比较操作

 @Test
    public void testEq() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*
        基本操作比较
        eq	等于 =
        ne 	不等于 <>
        gt 	大于 >
        ge 	大于等于 >=
        lt  	小于 <
        le  小于等于 <=
        between		BETWEEN 值1 AND 值2
        notBetween		NOT BETWEEN 值1 AND 值2
        in				字段 IN (value.get(0), value.get(1), ...)
        notIn			字段 NOT IN (v0, v1, ...)
        */

        //SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >= ? AND name IN (?,?,?)
        wrapper.eq("password", "123456")
               .ge("age", 20)
               .in("name", "李四", "王五", "赵六");

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

3.模糊查询

 @Test
    public void testLike(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*
        模糊查询
        like        LIKE '%值%'		例: like("name", "王") ---> name like '%王%'
        notLike		NOT LIKE '%值%'
        likeLeft	LIKE '%值'		例: likeLeft("name", "王") ---> name like '%王'
        likeRight	LIKE '值%'		例: likeRight("name", "王") ---> name like '王%'
        */

        // SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name LIKE ?
        // 参数:%五(String)
        wrapper.likeLeft("name", "五");

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

4.排序

 @Test
    public void testOrderByAgeDesc(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*
        排序
        orderBy			ORDER BY 字段, ...	          例: orderBy(true, true, "id", "name") ---> order by id ASC,name ASC
        orderByAsc		ORDER BY 字段, ... ASC        例: orderByAsc("id", "name") ---> order by id ASC,name ASC
        orderByDesc		ORDER BY 字段, ... DESC       例: orderByDesc("id", "name") ---> order by id DESC,name DESC
        */

        //按照年龄倒序排序
        // SELECT id,user_name,name,age,email AS mail FROM tb_user ORDER BY age DESC
        wrapper.orderByDesc("age");

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

5.逻辑查询

 @Test
    public void testOr(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*
        逻辑查询
        or		拼接 OR       主动调用or 表示紧接着下一个方法不是用and 连接!(不调用or 则默认为使用and 连接)
        and		AND 嵌套      例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status<> '活着')
        */

        // SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? OR age = ?
        wrapper.eq("name", "王五").or().eq("age", 21);

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

6. select

 @Test
    public void testSelect(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*select    在MP查询中,默认查询所有的字段,如果有需要也可以通过select方法进行指定字段*/

        //SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?
        wrapper.eq("name", "王五")
                .or()
                .eq("age", 21)
                .select("id","name","age"); //指定查询的字段

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mybatis插件之Mybatis-Plus(一) 的相关文章

随机推荐

  • Ubuntu开启关闭网卡

    关闭网卡 sudo ifconfig ens33 down 开启网卡 sudo ifconfig ens33 up 查看结果 ifconfig
  • Mysql数据库数据的分页查询显示【重点】

    x1f352 作者简介 xff1a 大学机械本科 xff0c 野生程序猿 xff0c 学过C语言 xff0c 玩过前端 xff0c 还鼓捣过嵌入式 xff0c 设计也会一点点 xff0c 不过如今痴迷于网络爬虫 xff0c 因此现深耕Pyt
  • UI自动化中的图片文字识别

    UI自动化中的图片文字识别 一 通过超级鹰脚本实现对图片文字的识别 1 超级鹰网址 http www chaojiying com 2 下载Python脚本 3 超级鹰的价格体系以及我们后面需要用到的验证码类型 4 关注超级鹰公众号免费领取
  • stm32Hal库函数的一个基本介绍和使用

    以下是一些常用的STM32 HAL库函数 xff1a GPIO相关函数 xff1a HAL GPIO Init HAL GPIO WritePin HAL GPIO ReadPin 等 进行定时器操作的函数 xff0c 例如 xff1a H
  • 【一起学Rust | 框架篇 | Frui框架】rust一个对开发者友好的GUI框架——Frui

    文章目录 前言一 新建项目1 创建项目2 导入idea3 引入依赖4 执行案例代码 二 实现计数器Demo1 导入资源2 编写窗口代码3 运行效果 总结完整代码 前言 本次内容接上回 rust原生跨平台GUI框架 iced xff0c 最近
  • 【一起学Rust | 框架篇 | ws-rs框架】属于Rust的Websocket框架——ws-rs

    文章目录 前言一 创建项目1 创建服务端项目2 创建客户端项目 二 编写测试代码1 服务端2 客户端 三 运行效果总结完整代码服务端客户端 前言 ws rs实现了MIO的WebSockets RFC6455标准 它允许在单个线程上处理多个连
  • kubeadm极速部署Kubernetes 1.26版本集群

    kubeadm极速部署Kubernetes 1 26版本集群 一 Kubernetes 1 26版本集群部署 1 1 Kubernetes 1 26版本集群部署环境准备 1 1 1 主机操作系统说明 序号操作系统及版本备注1CentOS7u
  • idea配置maven仓库

    1 去达内开发文档服务器下载对应插件 达内开发文档服务器 找到配置文件下载 xff0c 下载阿里云Maven创库配置 以上下载压缩包先不动 2 创建maven项目 打开idea file new project 点击左侧选择maven然后n
  • 双系统ubuntu18.04如何更新到22.04

    将双系统中的Ubuntu 18 04更新到22 04 xff0c 按照以下步骤操作 xff1a 1 打开终端并更新系统 xff0c 使用以下命令 xff1a span class token function sudo span span
  • 如何查看自己的ubuntu系统的镜像源,并且换源

    1 查看自己的Ubuntu系统当前使用的镜像源 xff1a 1 打开终端 xff1a 按下Ctrl 43 Alt 43 T xff0c 或者在菜单中搜索 终端 2 输入以下命令并按Enter键 xff1a span class token
  • linux中找不到my.cnf的解决方法

    通过rpm来安装MySQL是不会安装 etc my cnf文件 xff0c 所以配置主从复制的时候就不知道怎么配置 具体启动mysql的时候 xff0c 这个文件只是它内置的一个启动参数 即使找不到又想配置这个文件可以在文件路径中进行查找
  • iOS8定位与地图

    iOS开发系列 地图与定位 转载 xff1a http www cnblogs com kenshincui 概览 现在很多社交 电商 团购应用都引入了地图和定位功能 xff0c 似乎地图功能不再是地图应用和导航应用所特有的 的确 xff0
  • python 实现邮件发送详细解析 附代码(全)

    目录 前言1 基本逻辑2 smtplib2 1 发送邮件 3 zmail3 1 发送邮件3 2 获取邮件内容 4 yagmail 前言 统计某个统计量超过一定的阈值或者设置一个定时任务等 xff0c 触发发送邮件相关信息来告警 xff0c
  • 云服务器上安装 R语言 以及 RStudio Server 详细图文操作(全)

    目录 前言 1 更换镜像源 2 安装R 2 1 R包版本 最新 3 安装RStudio Server 4 后续细节 4 1 关闭防火墙 4 2 入口规则 端口 4 3 增加用户 5 验证 6 问题汇总 6 1 多用户登录 6 2 更改端口
  • Mac M1及以上芯片在Ubuntu上使用conda安装JupyterLab

    Mac M1及以上芯片在Ubuntu上使用conda安装JupyterLab 1 下载最新版本的Miniconda安装包 xff1a span class token function wget span https repo anacon
  • 【python】tkinter程序打包成exe可执行文件 全流程记录(windows系统)

    需求背景 Tkinter 是 Python 的标准 GUI 库 Python 使用 Tkinter 可以快速的创建 GUI 应用程序 我用python写了一个可视化界面 xff0c 利用算法计算患COVID 19的概率 现在需要将Pytho
  • STM32F103系列点灯程序

    STM32F103系列点灯程序 点灯流程1 找到LED灯对应寄存器引脚的基地址1 1在原理图上找到LED灯的位置1 2找到LED灯对应的引脚1 3打开数据手册找到对应的基地址 2 设置PE5 PB5寄存器模式为推挽输出模式2 1配置PE5
  • Rust GUI 库的状态

    图形用户界面 GUI 为与计算机交互提供了直观的可视化前端 与使用文本进行输入和输出操作的命令行界面 CLI 不同 xff0c GUI 使用图标 窗口和菜单等视觉指示器来实现更好的用户交互和体验 随着时间的推移 xff0c Rust 越来越
  • 使用 Rust 和 React 构建实时聊天应用程序

    如果您希望构建既快速又可靠的实时聊天应用程序 xff0c 请考虑使用 Rust 和 React Rust 以其速度和可靠性着称 xff0c 而React 是最流行的用于构建用户界面的前端框架之一 在本文中 xff0c 我们将演示如何使用 R
  • Mybatis插件之Mybatis-Plus(一)

    目录 一 简介 二 开发时注意事项 xff1a 1 Mybatis 43 MP xff08 纯Mybatis与Mybatis Plus整合 xff09 2 Spring 43 Mybatis 43 MP 3 SpringBoot 43 My