MyBatis-Plus总结

MyBatis-Plus总结

一、MyBatis回顾

(1)什么是MyBatis:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。MyBatis-Plus其实就是对MyBatis的加强。

二、什么是MyBatis-Plus

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

(2)MyBatis-Plus所需要的依赖:

<?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>

    <groupId>cn.wolfcode.mp</groupId>
    <artifactId>mybatis_plus_demo</artifactId>
    <version>1.0</version>

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.4.3</version>

    </parent>

    <dependencies>

        <dependency>

            <groupId>com.baomidou</groupId>

            <artifactId>mybatis-plus-boot-starter</artifactId>

            <version>3.4.0</version>

        </dependency>

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>druid-spring-boot-starter</artifactId>

            <version>1.1.17</version>

        </dependency>

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>8.0.22</version>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

        </dependency>

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <version>1.18.16</version>

            <scope>provided</scope>

        </dependency>

    </dependencies>
</project>

(3)创建自定义一个mapper接口(如:EmployeeMapper.java)然后继承BaseMapper,如:

public interface EmployeeMapper extends BaseMapper<Employee> {
}

三、MyBatis-Plus常用注解

(1)@TableName:表名注解。作用:该注解是用于当你所创建的实体类的类名与你的表名不一致时,可使用该注解。如:

如果表名为t_employee,而对应的实体类为Employee,此时就需要使用@TableName注解

@TableName("t_employee")
public class Employee{}

(2)@TableField:字段注解(非主键)。作用:当实体类中的属性名与对应表的列名不一致时,则需要使用该注解,该注解有两种使用方式。如:

使用方式一:

现在有一个表叫employee表,表中有一个ename列,而对应的实体类中的属性名为name,此时就需要使用到@TableField声明。

@TableField("ename")
private String name;

使用方式二:当我们需要在对应表的实体类中声明一个非该表中的列的属性时,如:现在Employee类中声明一个isDelete属性,而该属性在对应的employee表中并没有对应的列,则此时该使用@TableField(exist=false),其中:exist属性表示当前属性是否映射数据库列。

(3)@TableId:主键注解。作用:标记当前属性映射对应表中的主键。如:

@TableId(value = "id", type = IdType.AUTO)
    private Long id;

其中:type属性指定主键类型

① IdType.AUTO

数据库ID自增

② IdType.NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

③ IdType.INPUT

insert前自行set主键值

④ IdType.ASSIGN_ID

分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

⑤ IdType.ASSIGN_UUID

分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

四、通用Mapper接口

4.1 inser接口:

/**
 * 需求:插入一条记录
 * insert接口
 * 拼接的sql:INSERT INTO employee ( name, password, email, age, admin, dept_id ) VALUES ( ?, ?, ?, ?, ?, ? )
 */
@Test
public void testSave() {
    Employee employee = new Employee();
    employee.setAdmin(1);
    employee.setAge(18);
    employee.setDeptId(1L);
    employee.setEmail("dafei@wolfcode.cn");
    employee.setName("dafei");
    employee.setPassword("1");
    employeeMapper.insert(employee);
}

4.2 update接口:

4.2.1 updateById接口
 /**
     * 需求:更新id为1的name为dafei
     * updateById接口
     * 拼接的sql:UPDATE employee SET name=?, age=?, admin=? WHERE id=?
     */
    @Test
    public void testUpdateById() {
        Employee employee = new Employee();
        employee.setId(1L);
        employee.setName("dafei");
        employeeMapper.updateById(employee);
    }

注意:(1)使用updateById接口方式,当传入的实体对象参数,如果属性类型是基本数据类型,则mybatis-plus会认为有默认值,则会参与sql的拼接。

​ (2)使用updateById接口方式,当传入的实体对象参数,如果属性类型是包装类类型,则不会参与sql的拼接。

4.2.2 update接口

注意:该接口里需要传一个 entity和 wrapper 集合 这两个参数

/**
     *需求:更新id为1的name为zhoujie
     * update接口:该接口里需要传一个 entity和 wrapper 集合 这两个参数
     * 拼接的sql:UPDATE employee SET name=? WHERE (id = ?)
     *  wrapper.eq("id", 1L)等价于sql中的:WHERE (id = ?)
     *  wrapper.set("name", "zhoujie")等价于sql中的:SET name=?
     */
    @Test
    public void testUpdate() {
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", 1L).set("name", "zhoujie");
        employeeMapper.update(null, wrapper);
    }

(1)其中 wrapper.eq(“id”, 1L)等价于:WHERE (id = 1L), wrapper.set(“name”, “zhoujie”)等价于:SET name=zhoujie

(2)update 与 updateById 的选用:

​ updateById: 1> 更新条件为id。 2> 全量(所有字段)更新。

​ update: 1> 更新条件有多个(不仅限于根据id更新)。2> 局部(部分字段)更新。

4.3 delete接口:

4.3.1 deleteById接口
    /**
     * 需求:根据id删除
     * deleteById接口
     * 拼接的sql:DELETE FROM employee WHERE id=?
     */
    @Test
    public void testDeleteById() {
        employeeMapper.deleteById(1L);
    }
4.3.2 deleteBatchIds接口

(该接口需要传一个集合,可用于批量删除)

/**
     * 需求:删除id=1, id=2的员工信息
     * deleteBatchIds接口:该接口需要传一个集合,可用于批量删除
     * 拼接的sql:DELETE FROM employee WHERE id IN ( ? , ? )
     */
    @Test
    public void testDeleteBatchIds() {
        employeeMapper.deleteBatchIds(Arrays.asList(1L,2L));

    }
4.3.3 deleteByMap接口

注意:该接口里面需要传一个map集合,且拼接出的sql语句中的条件只能是使用and进行连接

 /**
     * 需求:删除name=dafei并且age=18的员工信息
     * deleteByMap接口:该接口里面需要传一个map集合
     * 拼接的sql:Preparing: DELETE FROM employee WHERE name = ? AND age = ?
     */
    @Test
    public void testDeleteByMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "赵一明");
        map.put("age", 25);
        employeeMapper.deleteByMap(map);
    }
4.3.4 delete接口

注意: delete接口:该接口里面需要传一个 wrapper 集合

 /**
     * 需求:删除name=钱总并且age=31的员工信息 wrapper 集合
     * delete接口:该接口里面需要传一个 wrapper 集合
     * sql:DELETE FROM employee WHERE (name = ? AND age = ?)
     */
    @Test
    public void testDelete() {
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
        wrapper.eq("name", "钱总").eq("age", 31);
        employeeMapper.delete(wrapper);
    }

4.4 select接口:

4.4.1 selectById接口
/**
     * 需求:查询id=5的员工信息
     * selectById接口
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id=?
     */
    @Test
    public void testSelectById() {
        System.out.println(employeeMapper.selectById(5L));
    }
4.4.2 selectBatchIds接口

**注意:**selectBatchIds接口:该接口里面需要传一个list集合

 /**
     * 需求:查询id=1,id=2的员工信息
     * selectBatchIds接口:该接口里面需要传一个list集合
     * 适用场景:当需要查指定哪些id的数据时可使用,其拼接的sql语句使用的是in来实现的。
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? )
     */
    @Test
    public void testSelectBatchIds() {
        employeeMapper.selectBatchIds(Arrays.asList(5L,6L)).forEach(System.out::println);
    }
4.4.3 selectByMap接口

注意:selectByMap接口:里面需要传一个 map 集合,传的map集合,且拼接出的sql语句中的条件只能是使用and进行连接

 /**
     * 需求: 查询name=钱二明, age=25的员工信息
     * selectByMap接口:里面需要传一个 map 集合,传的map集合,需拼接出的sql语句中的条件只能是使用and进行连接
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
     */
    @Test
    public void testSelectByMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "钱二明");
        map.put("age", 25);
        employeeMapper.selectByMap(map);
    }

4.4.4 selectCount接口

注意:selectCount接口:里面需要传一个 wrapper 集合,若 wrapper 集合中不设置任何条件值,则默认查询全部数量

 /**
     * 需求: 查询满足条件的所有的员工个数
     * selectCount接口:里面需要传一个 wrapper 集合,若 wrapper 集合中不设置任何条件值,则默认查询全部数量
     * 拼接的sql: SELECT COUNT( 1 ) FROM employee
     */
    @Test
    public void testSelectCount() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        employeeMapper.selectCount(wrapper);
    }
4.4.5 selectList接口

注意:selectList接口:里面需要传一个 wrapper 集合

 /**
     * 需求: 查询满足条件的所有的员工信
     * selectList接口:里面需要传一个 wrapper 集合
     * 返回值: List<Employee>
     * 拼接的sql:
     *      当 wrapper 集合中没有设置条件时,即查询全部:SELECT id,name,password,email,age,admin,dept_id FROM employee
     *      当 wrapper 集合中设置了条件时,即按设置的条件查询:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ?)
     */
    @Test
    public void testSelectList() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("age", 25);
        List<Employee> employees = employeeMapper.selectList(wrapper);
    }
4.4.6 selectMaps接口

注意:selectMaps接口:里面需要传一个 wrapper 集合

/**
     * 需求: 查询满足条件的所有的员工信息
     * selectMaps接口:里面需要传一个 wrapper 集合
     * 返回值:List<Map<String, Object>>
     * 拼接的sql:
     *      当 wrapper 集合中没有设置条件时,即查询全部:SELECT id,name,password,email,age,admin,dept_id FROM employee
     *      当 wrapper 集合中设置了条件时,即按设置的条件查询:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ?)
     */
    @Test
    public void testSelectMaps() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
    }

注意:什么时候使用 selectList 接口,什么时候使用 selectMaps 接口?

能封装成对象时,使用 selectList 接口,不能封装成对象时,使用 selectMaps 接口
      比如如下要求:
           查询每个部门下员工的个数
           sql: select dept_id , count(id) count from employee group by dept_id
           结果是:dept_id 与 count 列,而表与对应的实体类并没有 count 列/属性,此时,如果使用 selectList 进行查询,则会丢失数据。
4.4.7 selectPage接口

步骤1:在启动类中配置分页拦截器

//分页拦截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true); //合理化
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }

步骤2:

注意:

​ (1)分页返回的数据是实体对象(page)

​ (2)selectPage接口:该接口里面需要传一个 Page 对象,wrapper 集合,其中 wrapper 是过滤条件

​ (3)Page<>(2,3)中的参数:参数1:当前页。参数2:每页显示条数

 /**
     * 需求:查询第二页员工数据, 每页显示3条
     * 分页返回的数据是实体对象(page)
     * selectPage接口:该接口里面需要传一个 Page 对象,wrapper 集合,其中 wrapper 是过滤条件
     * Page<>(2,3)中的参数:参数1:当前页。参数2:每页显示条数
     * 拼接的sql:
     *      SELECT COUNT(1) FROM employee
     *      SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
     */
    @Test
    public void testSelectPage() {
        IPage<Employee> page = new Page<>(2,3);
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        page = employeeMapper.selectPage(page, wrapper);
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("每页显示条数:" + page.getSize());
        System.out.println("总页数:" + page.getPages());
        System.out.println("总数:" + page.getTotal());
        System.out.println("当前页数据:" + page.getRecords());
    }

五、条件构造器

5.1 继承体系

(1)继承体系图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V2rwTKxX-1642229759087)(D:\图片\java\image-20211222115421170.png)]

(2)继承关系说明:

​ 1> Wapper:条件构造抽象类,最顶端父类。

​ 2> AbstractWrapper: 用于查询条件封装,生成 sql 的 where 条件。继承 Wapper 抽象类。

​ 3> QueryWrapper: Entity 对象封装操作类,不是用lambda语法。适用于查询。

​ 4> UpdateWrapper: Update 条件封装,适用于Entity对象更新操作。

​ 5> AbstractLambdaWrapper: Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。

​ 6> LambdaQueryWrapper:看名称也能明白就是用于Lambda语法使用的查询Wrapper。

​ 7> LambdaUpdateWrapper: Lambda 更新封装Wrapper。

5.1.1 共有条件方法(经常使用的)

(1)allEq方法

/**
     * allEq方法
     * 拼接的sql:
     *      wrapper.allEq(Map<String, Object> prams):
     *      SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
     *      wrapper.allEq(Map<String, Object> prams, boolean null2IsNull):
     *      该方法的第二参数表示:
     *          当你拼接的条件中有null,并且第二个参数设置为true时,则在拼接sql语句时,会把条件拼接上去,如:
     *          SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age IS NULL)
     *          当你拼接的条件中有null,并且第二个参数设置为false时,则在拼接sql语句时,不会把条件拼接上去,如:
     *          SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ?)
     */
    @Test
    public void testAllEq() {
        Employee employee = new Employee();
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        Map<String, Object> map = new HashMap<>();
        map.put("name", "xiaofei");
        map.put("age", null);
        wrapper.allEq(map);
//        wrapper.allEq(map, false);
        System.out.println(employeeMapper.selectOne(wrapper));
    }

(2)eq方法

/**
     * eq方法:等价于 sql 语句中的 where 列名 = ?
     * 拼接的sql:
     *      SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
     *      加了wrapper.or();语句:
     *      SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? OR age = ?)
     */
    @Test
    public void testEq() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "xiaofei");
//        wrapper.or();
        wrapper.eq("age", 18);
        employeeMapper.selectOne(wrapper);
    }

(3)ne方法

/**
     * ne方法:等价于sql语句中的 where 列名 != ? (WHERE (name <> ?))
     * 拼接的sql:
     *      SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name <> ?)
     */
    @Test
    public void testNe() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.ne("name", "xiaofei");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(4)like方法

 /**
     * like方法:等价于 sql 语句中的 where 列名 like ?
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
     * 条件中的 ? 参数:%值%
     *
     */
    @Test
    public void testLike() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.like("name", "李");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
5.2 更新操作
5.2.1 UpdateWrapper更新之setSql
 /**
     * 需求:将id=20的用户name改为dafei
     * 拼接的sql:UPDATE employee SET name='dafei' WHERE (id = ?)
     */
    @Test
    public void testSetSql() {
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", 20);
        wrapper.setSql("name='dafei'");
        employeeMapper.update(null , wrapper);
    }
5.2.2 LambdaUpdateWrapper更新
 /**
     * LambdaUpdateWrapper更新
     * 需求:将id=1的用户name改为xiaofei
     * 拼接的sql:UPDATE employee SET name=? WHERE (id = ?)
     */
    @Test
    public void testLambdaUpdateWrapperUpdate() {
        LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Employee::getId, 20L);
        wrapper.set(Employee::getName,"xiaofei");
        employeeMapper.update(null , wrapper);
    }
5.3 查询操作
5.3.1 QueryWrapper查询
 /**
     * QueryWrapper查询
     * 需求:查询name=dafei, age=18的用户
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
     */
    @Test
    public void testQueryWrapperSelect() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "dafei").eq("age", 18);
        employeeMapper.selectList(wrapper);
    }
5.3.2 LambdaQueryWrapper查询
/**
     * LambdaQueryWrapper查询
     * 需求:查询name=dafei, age=18的用户
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
     */
    @Test
    public void testLambdaQueryWrapperSelect() {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getName,"dafei");
        wrapper.eq(Employee::getAge,18);
        employeeMapper.selectList(wrapper);
    }

六、高级查询

6.1 列投影(select)

    /**
     * 需求:查询所有员工, 返回员工name, age列
     * 拼接的sql:SELECT name,age FROM employee
     * wrapper.select("name","age");等价于sql语句中的:SELECT name,age
     */
    @Test
    public void testSelect() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.select("name","age");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
6.2 排序
6.2.1 orderByAsc/orderByDesc排序
/**
     * 需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
     * wrapper.orderByAsc("age","id");等价于sql语句中的:ORDER BY age ASC,id ASC
     */
    @Test
    public void testSort() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("age","id");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
6.2.2 orderBy排序
/**
     * 需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排
     * 参数说明:参数一:是否进行排序、参数二:是否进行正序排序、参数三:排序的列名
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
     */
    @Test
    public void testOrderBy() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.orderBy(true, true, "age","id");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
6.3 分组查询
6.3.1 groupBy
/**
     * 需求: 以部门id进行分组查询,查每个部门员工个数
     * 拼接的sql:SELECT dept_id,count(id) FROM employee GROUP BY dept_id
     
     *  wrapper.groupBy("dept_id");等价于sql中的:GROUP BY dept_id
     */
    @Test
    public void testGroupBy() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.groupBy("dept_id");
        wrapper.select("dept_id","count(id)");
        employeeMapper.selectMaps(wrapper).forEach(System.out::println);
    }
6.3.2 having
 /**
     * 需求: 以部门id进行分组查询,查每个部门员工个数, 将大于3人的部门过滤出来
     * 拼接的sql:SELECT dept_id,count(id) count FROM employee GROUP BY dept_id HAVING count > 3
     *  wrapper.having("count > 3");等价于sql中的:HAVING count > 3
     */
    @Test
    public void testHaving() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.groupBy("dept_id");
        wrapper.select("dept_id","count(id) count");
        wrapper.having("count > 3");
        employeeMapper.selectMaps(wrapper).forEach(System.out::println);
    }
6.4 条件查询
6.4.1 比较运算符

(1)大于(gt)、小于(lt)、大于等于(ge)、小于等于(le)

 /**
     * 大于:gt
     * 需求:查询age 大于18岁员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age > ?)
     * wrapper.gt("age", 18);等价于sql中的:WHERE (age > ?)
     */
    @Test
    public void testGt() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.gt("age", 18);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 小于:lt
     * 需求:查询age 小于30岁员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age < ?)
     * wrapper.lt("age", 30);等价于sql中的WHERE (age < ?)
     */
    @Test
    public void testLt() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.lt("age", 30);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 大于等于:ge
     * 需求:查询age 大于等于20岁员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age >= ?)
     * wrapper.ge("age", 20);等价于sql中的WHERE (age >= ?)
     */
    @Test
    public void testGe() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.ge("age", 20);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 小于等于:le
     * 需求:查询age 小于等于20岁员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age <= ?)
     * wrapper.le("age", 20);等价于sql中的:WHERE (age <= ?)
     */
    @Test
    public void testLe() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.le("age", 20);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(2)between/notBetween

/**
     * 需求:查询年龄介于18~30岁的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
     * wrapper.between("age", 18, 30);等价于sql中的:WHERE (age BETWEEN ? AND ?)
     */
    @Test
    public void testBetweenAnd() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.between("age", 18, 30);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 需求:查询年龄小于18或者大于30岁的员工信息【用between实现】
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age NOT BETWEEN ? AND ?)
     * wrapper.notBetween("age", 18, 30);等价于sql中的WHERE (age NOT BETWEEN ? AND ?)
     */
    @Test
    public void testNotBetweenAnd() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.notBetween("age", 18, 30);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(3)isNull/isNotNull

/**
     * 需求: 查询dept_id 为null 员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NULL)
     * wrapper.isNull("dept_id");等价于sql中的WHERE (dept_id IS NULL)
     */
    @Test
    public void testIsNull() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.isNull("dept_id");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 需求: 查询dept_id 不为null 员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NOT NULL)
     * wrapper.isNotNull("dept_id");等价于sql中的:WHERE (dept_id IS NOT NULL)
     */
    @Test
    public void testIsNotNull() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("dept_id");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(4)in/notIn/inSql/notInSql

/**
     * in方法
     * 需求: 查询id为1, 2 的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (?,?))
     * wrapper.in("id", 1,2);等价于sql中的:WHERE (id IN (?,?))
     */
    @Test
    public void testIn() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.in("id", 1,2);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * notIn方法
     * 需求: 查询id不为1, 2 的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?))
     * wrapper.notIn("id", 1,2);等价于sql中的:WHERE (id NOT IN (?,?))
     */
    @Test
    public void testNotIn() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.notIn("id", 1,2);
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * inSql方法
     * 需求: 查询id为1, 2 的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (1,2))
     * wrapper.inSql("id", 1,2);等价于sql中的:WHERE (id IN (1,2))
     */
    @Test
    public void testinSql() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.inSql("id", "1,2");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * notInSql方法
     * 需求: 查询id为1, 2 的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (1,2))
     * wrapper.notInSql("id", 1,2);等价于sql中的:WHERE (id NOT IN (1,2))
     */
    @Test
    public void testNotInSql() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.notInSql("id", "1,2");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
}
6.4.2 模糊查询

(1)like/notLike

 @Test
    public void testLike() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.like("name", "李");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
/**
     * 需求: 查询name中不含有fei字样的员工
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name NOT LIKE ?)
     * 拼接的参数:%fei%
     * wrapper.notLike("name", "fei");等价于sql中的:WHERE (name NOT LIKE ?)
     */
    @Test
    public void testNotLike() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.notLike("name", "fei");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(2)likeLeft/likeRight

 /**
     * 需求: 查询name以fei结尾的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
     * 拼接的参数:%fei
     * wrapper.likeRight("name", "fei");等价于sql中的:WHERE (name LIKE ?)
     */
    @Test
    public void testLkeLeft() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.likeLeft("name", "fei");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

    /**
     * 需求: 查询name以fei开头的员工信息
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
     * 拼接的参数:fei%
     * wrapper.likeRight("name", "fei");等价于sql中的:WHERE (name LIKE ?)
     */
    @Test
    public void testLkeRight() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.likeRight("name", "fei");
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }
6.4.3 逻辑运算符

(1)嵌套or

/**
     * 需求:查询name含有fei字样的,或者 年龄在18到30之间的用户
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age >= ? AND age <= ?))
     * rapper.like("name", "fei").or(wp -> wp.ge("age", 18).le("age", 30));等价于sql中的:WHERE (name LIKE ? OR (age >= ? AND age <= ?))
     */
    @Test
    public void testOr() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.like("name", "fei")
                .or(
                        wp -> wp.ge("age", 18).le("age", 30)
                );
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

(2)嵌套and

/**
     * 需求:查询name含有fei字样的并且 年龄在小于18或者大于30的用户
     * 拼接的sql:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? AND (age <= ? OR age >= ?))
     * wrapper.like("name", "fei").and(wp -> wp.le("age", 18).or().ge("age", 30));等价于sql中的:WHERE (name LIKE ? AND (age <= ? OR age >= ?))
     */
    @Test
    public void testAnd() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.like("name", "fei")
                .and(
                        wp -> wp.le("age", 18)
                        .or()
                        .ge("age", 30)
                );
        employeeMapper.selectList(wrapper).forEach(System.out::println);
    }

七、通用Service接口

7.1 通用方式

步骤一:自定义一个 Service 接口,然后继承 IService。其中里面的泛型应给实体类。

public interface IEmployeeService extends IService<Employee> {
}

步骤二:自定义一个 Service 接口的实现类 ServiceImpl ,然后继承 ServiceImpl<M,T> 的同时实现 Service 接口。

其中 ServiceImpl<M,T> 中的泛型解释:泛型一:对应的 Mapper 接口。泛型二:对应的实体类

public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
}

7.2 常用方法

7.2.1 getBaseMapper()方法
@Test
    public void testGetBaseMapper() {
        BaseMapper<Employee> baseMapper = employeeService.getBaseMapper();
        System.out.println(baseMapper);
    }
7.2.2 getOne(wrapper)方法
/**
     * getOne方法
     * 指定条件查询单个, 结果数据超过1个报错
     */
    @Test
    public void testGetOne() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "xiaofei");
        System.out.println(employeeService.getOne(wrapper));
    }
7.2.3 list(wrapper)方法
/**
     * list方法
     * 指定条件查询多个
     */
    @Test
    public void testList() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("age", 25);
        employeeService.list(wrapper).forEach(System.out::println);
    }
7.2.4 page(page, wrapper)
Service接口:
    public interface IEmployeeService extends IService<Employee> {
    Page<Employee> queryPage(EmployeeQuery qo);
}

ServiceImpl实现类:
    @Service
@Transactional
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
    @Override
    public Page<Employee> queryPage(EmployeeQuery qo) {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        Page<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        wrapper.like(StringUtils.hasLength(qo.getKeyWord()), "name", qo.getKeyWord());
        return super.page(page, wrapper);
    }
}

测试类:
     /**
     * 分页+高级查询
     * 拼接的sql: SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?) LIMIT ?
     */
    @Test
    public void testPage() {
        EmployeeQuery qo = new EmployeeQuery();
//        qo.setKeyWord("孙");
        qo.setCurrentPage(1);
        qo.setPageSize(3);
        Page<Employee> page = employeeService.queryPage(qo);
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("总页数:" + page.getPages());
        System.out.println("每页显示条数:" + page.getSize());
        System.out.println("当前页显示记录:" + page.getRecords());
    }
7.2.5 saveOrUpdate方法
 /**
     * saveOrUpdate方法
     * 拼接的sql:INSERT INTO employee ( name, age ) VALUES ( ?, ? )
     */
    @Test
    public void testSaveOrUpdate() {
        Employee employee = new Employee();
        employee.setName("xiaojie");
        employee.setAge(21);
        employeeService.saveOrUpdate(employee);
    }
  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值