第三章: Mybatis-Plus 的通用CRUD API 练习使用

目录

 1. Insert 操作 -> Create

1.1: @TableId 的 id策略

 1.2: @TableField

2. Update 操作 -> Update

2.1: 根据 ID 更新

 2.2: 根据条件更新 

 3. Delete 操作 -> Delete

3.1: deleteById

3.2: deleteByMap

3.3: delete

3.4: deleteBatchIds

4. Select 操作 -> Read

4.1: selectById

4.2: selectBatchIds

4.3: selectOne

4.4: selectCount

4.5: selectList

4.6: selectByMap

4.7: selectMaps

4.8: selectPage

4.9: selectMapsPage

4,10: exists (3.5.0版本新增的判断是否存在的API)


通过前面两章的练习理解, 了解到自定义的接口通过继承 BaseMapper 就可以获取到各种各样的单表操作, 接下来就对这些常用的 API 做个练习使用

 1. Insert 操作 -> Create

方法定义

 /**
     * 插入一条记录
     *
     * @param entity 实体对象
     */
    int insert(T entity);

 测试用例 

  @Test
    public void testInsert(){
        User user = new User();
        user.setAge(18);
        user.setEmail("sunshangxiang@163.com");
        user.setName("孙尚香");
        user.setUserName("xiangxiang");
        user.setPassword("123321");

        // 返回的 res 是受影响的行数, 并不是自增后的 id
        int res = userMapper.insert(user);

        System.out.println("res = " + res);

        // 自增后的 id 会填到对象中
        System.out.println("user.getId() = " + user.getId());
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] ==>  Preparing: INSERT INTO tb_user ( id, password, name, user_name, email, age ) VALUES ( ?, ?, ?, ?, ?, ? ) 
[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] ==> Parameters: 1657763426766651394(Long), 123321(String), 孙尚香(String), xiangxiang(String), sunshangxiang@163.com(String), 18(Integer)
[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] <==    Updates: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@faa3fed]
res = 1
user.getId() = 1657763426766651394

 可以看到,数据已经写入到了数据库,但是 id 的值不正确, 期望的是 数据库自增长, 实际是 MybatisPlus生成了 id 的值写入到了数据库

1.1: @TableId 的 id策略

默认id策略

/**
 * 表主键标识
 *
 * @author hubin
 * @since 2016-01-23
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableId {

    /**
     * 字段值(驼峰命名方式,该值可无)
     */
    String value() default "";

    /**
     * 主键ID
     * {@link IdType}
     */
    IdType type() default IdType.NONE;
}

MybatisPlus支持以下 id 策略:


package com.baomidou.mybatisplus.annotation;

import lombok.Getter;

/**
 * 生成ID类型枚举类
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    /**
     * 数据库ID自增
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(将跟随全局)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充</p>
     */
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 全局唯一ID (idWorker)
     */
    ID_WORKER(3),
    /**
     * 全局唯一ID (UUID)
     */
    UUID(4),
    /**
     * 字符串全局唯一ID (idWorker 的字符串表示)
     */
    ID_WORKER_STR(5);

    private final int key;

    IdType(int key) {
        this.key = key;
    }
}

想插入数据到数据库时为自增效果则需要去把实体类的 id 策略指定为 自增长

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
    // 指定 id 为自增长 
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

删除刚刚插入的数据再次进行测试 

数据插入成功

 1.2: @TableField

/**
 * 表字段标识
 *
 * @author hubin sjy tantan
 * @since 2016-09-09
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableField {

    /**
     * 字段值(驼峰命名方式,该值可无)
     */
    String value() default "";

    /**
     * 是否为数据库表字段
     * 默认 true 存在,false 不存在
     */
    boolean exist() default true;

    /**
     * 字段 where 实体查询比较条件
     * 默认 `=` 等值
     */
    String condition() default "";

    /**
     * 字段 update set 部分注入, 该注解优于 el 注解使用
     * <p>
     * 例1:@TableField(.. , update="%s+1") 其中 %s 会填充为字段
     * 输出 SQL 为:update 表 set 字段=字段+1 where ...
     * <p>
     * 例2:@TableField(.. , update="now()") 使用数据库时间
     * 输出 SQL 为:update 表 set 字段=now() where ...
     */
    String update() default "";

    /**
     * 字段验证策略之 insert: 当insert操作时,该字段拼接insert语句时的策略
     * IGNORED: 直接拼接 insert into table_a(column) values (#{columnProperty});
     * NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
     * NOT_EMPTY: insert into table_a(<if test="columnProperty != null and columnProperty!=''">column</if>) values (<if test="columnProperty != null and columnProperty!=''">#{columnProperty}</if>)
     *
     * @since 3.1.2
     */
    FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段验证策略之 update: 当更新操作时,该字段拼接set语句时的策略
     * IGNORED: 直接拼接 update table_a set column=#{columnProperty}, 属性为null/空string都会被set进去
     * NOT_NULL: update table_a set <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: update table_a set <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     *
     * @since 3.1.2
     */
    FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段验证策略之 where: 表示该字段在拼接where条件时的策略
     * IGNORED: 直接拼接 column=#{columnProperty}
     * NOT_NULL: <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     *
     * @since 3.1.2
     */
    FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段自动填充策略
     */
    FieldFill fill() default FieldFill.DEFAULT;

    /**
     * 是否进行 select 查询
     * <p>大字段可设置为 false 不加入 select 查询范围</p>
     */
    boolean select() default true;

    /**
     * 是否保持使用全局的 Format 的值
     * <p> 只生效于 既设置了全局的 Format 也设置了上面 {@link #value()} 的值 </p>
     * <li> 如果是 false , 全局的 Format 不生效 </li>
     *
     * @since 3.1.1
     */
    boolean keepGlobalFormat() default false;

    /**
     * JDBC类型 (该默认值不代表会按照该值生效)
     * <p>
     * {@link ResultMapping#jdbcType} and {@link ParameterMapping#jdbcType}
     *
     * @since 3.1.2
     */
    JdbcType jdbcType() default JdbcType.UNDEFINED;

    /**
     * 类型处理器 (该默认值不代表会按照该值生效)
     * <p>
     * {@link ResultMapping#typeHandler} and {@link ParameterMapping#typeHandler}
     *
     * @since 3.1.2
     */
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

    /**
     * 指定小数点后保留的位数
     * <p>
     * {@link ParameterMapping#numericScale}
     *
     * @since 3.1.2
     */
    String numericScale() default "";
}

在 MybatisPlus中通过 @TableField 注解可以指定字段的一些属性,常常解决的问题有以下两个

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

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

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
    // 指定 id 为自增长
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    // 如 数据库中字段是 email, 而实体中的字段是 mail
    // 这时候就可以使用 @TableFiled 的属性来指定数据库中的那个列的数据映射到此字段
    @TableField(value = "email")
    private String mail;

    // 该字段在数据库表中不存在就可以用 exist 属性指定. 默认为 true
    @TableField(exist = false)
    private String address;
}

其他用法: 比如

// 不将敏感数据 参与到查询中
    @TableField(select = false)
    private String password;

官方注解文档:  https://mybatis.plus/guide/annotation.html

2. Update 操作 -> Update

2.1: 根据 ID 更新

 方法定义

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

测试用例

 @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L); // 主键id
        user.setAge(101); // 更新的字段

        // 根据 id 更新,更新为null 的字段
        int res = userMapper.updateById(user);
        System.out.println("影响行数 = " + res);
    }

 测试结果

 2.2: 根据条件更新 

方法定义

    /**
     * 根据 whereEntity 条件,更新记录
     *
     * @param entity        实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

测试用例

 // 方式1:
    @Test
    public void testUpdate() {
        User user = new User();
        user.setEmail("88888@qq.com");
        // 更新的条件
        QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("user_name", "sunqi");

        System.out.println("影响行数 = " + userMapper.update(user, wrapper));
    }

    // 方式2:
    @Test
    public void testUpdate2() {
        // 更新的条件以及字段
        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                .eq("email", "test2@163.cn").set("age", 88);
        // 执行更新
        System.out.println("影响行数 = " + userMapper.update(null, wrapper));
    }

方式1方式2 均可达到 更新的效果

测试结果

 3. Delete 操作 -> Delete

3.1: deleteById

方法定义

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    int deleteById(Serializable id);
    /**
     * 根据实体(ID)删除
     *
     * @param entity 实体对象
     * @since 3.4.4
     */
    int deleteById(T entity);

测试用例:

 @Test
    public void testDeleteById(){
        int res = userMapper.deleteById(7L);
        System.out.println("影响行数 = " + res);
    }

 测试结果:

数据被删除 

3.2: deleteByMap

方法定义

    /**
     * 根据 columnMap 条件,删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

测试用例

 @Test
    public void testDeleteByMap(){
        HashMap<String, Object> columnMap = new HashMap<>();
        /* 键: 数据库列名
        *  值: 具体的值
        * */
        columnMap.put("user_name","sunqi");
        columnMap.put("age",24);
        int res = userMapper.deleteByMap(columnMap);
        System.out.println("影响行数 = " + res);
    }

测试结果

数据删除成功 

3.3: delete

方法定义

    /**
     * 根据 entity 条件,删除记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

测试用例

@Test
    public void testDelete(){
        User user = new User();
        user.setPassword("123456");
        user.setEmail("test1@163.cn");
        int res = userMapper.delete(new QueryWrapper<>(user));
        System.out.println("影响行数 = " + res);
    }

测试结果

删除数据成功

3.4: deleteBatchIds

方法定义:

    /**
     * 删除(根据ID或实体 批量删除)
     *
     * @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList);

测试用例:

 @Test
    public void testDeleteBatchIds(){
        int res = userMapper.deleteBatchIds(Arrays.asList(1L, 3L, 10L, 88L, 99L));
        System.out.println("影响行数 = " + res);
    }

测试结果:

删除数据成功 

4. Select 操作 -> Read

Mybatis-Plus提供了多种查询操作, 包括根据 id 查询,批量查询,查询单条数据,查询列表,分页查询等操作

新增几条数据

4.1: selectById

方法定义

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T selectById(Serializable id);

测试用例

 @Test
    public void testSelectById(){
        System.out.println("用户信息 = " + userMapper.selectById(13));
    }

测试结果

[indi.darylz.mapper.UserMapper.selectById]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE id=?
[main] [indi.darylz.mapper.UserMapper.selectById]-[DEBUG] ==> Parameters: 13(Integer)
[main] [indi.darylz.mapper.UserMapper.selectById]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e6ba49a]
用户信息 = User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)

4.2: selectBatchIds

方法定义

    /**
     * 查询(根据ID 批量查询)
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);

测试用例

 @Test
    public void testSelectBatchIds() {
        // 只会查询匹配的 id
        List<User> users = userMapper.selectBatchIds(Arrays.asList(2L, 4L, 5L, 11L, 13L, 51L));
        users.forEach(System.out::println);
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE id IN ( ? , ? , ? , ? , ? , ? )
[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] ==> Parameters: 2(Long), 4(Long), 5(Long), 11(Long), 13(Long), 51(Long)
[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] <==      Total: 4
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e0b9178]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)

4.3: selectOne

方法定义

    /**
     * 根据 entity 条件,查询一条记录
     * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
        List<T> list = this.selectList(queryWrapper);
        // 抄自 DefaultSqlSession#selectOne
        if (list.size() == 1) {
            return list.get(0);
        } else if (list.size() > 1) {
            throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
        } else {
            return null;
        }
    }

测试用例

// 方式1
    @Test
    public void testSelectOne() {
        User user = new User();
        user.setEmail("huoqubing@sina.com");
        System.out.println("用户信息 = " + userMapper.selectOne(new QueryWrapper<>(user)));
    }

    // 方式2
    @Test
    public void testSelectOne2() {
        System.out.println("用户信息 = " +
                userMapper.selectOne(
                        new QueryWrapper<User>()
                                .eq("user_name", "liubei")
                                .eq("age", 93)));

    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE email=?
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: huoqubing@sina.com(String)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@383f3558]
用户信息 = User(id=14, userName=huoqubing, password=1353341, name=霍去病, age=134, email=huoqubing@sina.com, address=null)

// ------------------------------------------------------

[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (user_name = ? AND age = ?)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: liubei(String), 93(Integer)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@712ca57b]
用户信息 = User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)

 注意:多条数据会报异常

测试用例

 @Test
    public void testSelectOneIfException(){
        System.out.println("用户信息 = " +
                userMapper.selectOne(new QueryWrapper<User>().eq("password", "123456")));
    }

测试结果 

4.4: selectCount

方法定义

    /**
     * 根据 Wrapper 条件,查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

测试用例

@Test
    public void testSelectCount() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        // 查询年龄大于 60 (不包括60) , 如果需要包括使用
        wrapper.gt("age", 90)
                // 或者
                .or()
                // id 小于等于6的
                .le("id", 6);

        System.out.println("匹配 = " + userMapper.selectCount(wrapper) + " 条记录");
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==>  Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE (age > ? OR id <= ?)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: 90(Integer), 6(Integer)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@294bdeb4]
匹配 = 6 条记录

4.5: selectList

方法定义

    /**
     * 根据 entity 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

测试用例

 @Test
    public void testSelectList() {
        // 查询匹配条件的用户
        /* 如果当前 selectList中的参数为null 
        或者 QueryWrapper对象为空对象(new new QueryWrapper<User>())
        则是查询全部数据 */
        userMapper.selectList(new QueryWrapper<User>()
                        .ge("age", 90).or()
                        .eq("password", "123456"))
                .forEach(System.out::println);
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age >= ? OR password = ?)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: 90(Integer), 123456(String)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <==      Total: 6
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1f86099a]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)
User(id=14, userName=huoqubing, password=1353341, name=霍去病, age=134, email=huoqubing@sina.com, address=null)
User(id=15, userName=liubang, password=13413513, name=刘邦, age=151, email=hangaozu@han.com, address=null)

4.6: selectByMap

方法定义

/**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

测试用例

 @Test
    public void testSelectByMap(){
        // 将 数据库列名和值封装在Map集合中,查询一个或 (多个实体(如果存在))
        Map<String, Object> hashMap = new HashMap<String, Object>() {{
//            put("user_name", "xiangxiang");
//            put("email", "sunshangxiang@163.com");
            put("password","123456");
        }};
        /* selectByMap(null) 则查询全部 */
       userMapper.selectByMap(hashMap).forEach(System.out::println);
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ?
[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] ==> Parameters: 123456(String)
[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] <==      Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@400d912a]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)

4.7: selectMaps

方法定义

    /**
     * 根据 Wrapper 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

测试用例

/**
     * 查询指定条件的数据,并把表中数据对应的一个实体封装到Map中
     * key: 数据库列名
     * value: 对应列中的数据值
     */
    @Test
    public void testSelectMaps(){
        // 参数1: 当前页
        // 参数2: 当前页面大小
        QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 21);
        List<Map<String, Object>> selectMaps = userMapper.selectMaps(wrapper);
        for (Map<String, Object> selectMap : selectMaps) {
            selectMap.keySet().forEach(s -> System.out.println(s.toUpperCase()));
            selectMap.values().forEach(System.out::println);
            System.out.println("-------");
        }
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] ==> Parameters: 21(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] <==      Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1f12e153]
PASSWORD
USER_NAME
NAME
ID
AGE
EMAIL
123456
zhaoliu
赵六
4
21
test4@163.cn
-------
PASSWORD
USER_NAME
NAME
ID
AGE
EMAIL
123321
xiangxiang
孙尚香
6
18
sunshangxiang@163.com
-------

4.8: selectPage

方法定义

/**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

在SpringBoot项目中配置分页拦截器 

3.1.2 版本 ~ 3.4.2 版本配置 (其中有些小版本没有)
 PaginationInterceptor 在 3.4.0 ~ 3.4.2 版本可选 

package indi.darylz.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author: daryl z
 * @description: MybatisPlus 分页拦截器配置
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 3.1.2 版本 ~ 3.4.2 版本配置 (其中有些小版本没有)
     * PaginationInterceptor 在 3.4.0 ~ 3.4.2 版本可选 
     * 配置MybatisPlus提供的 分页拦截器
     * @return 将分页拦截器放入Spring容器中
     */
    @Bean
    public PaginationInterceptor paginationInnerInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作
        /* true调回到首页 , false 继续请求 默认为 false */
//        paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量, 默认 500 条, -1 不受限制
        paginationInterceptor.setLimit(1000L);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

3.4.0 及以上版本配置 (这里测试用的 3.5.3.1 所以使用下面的配置)

package indi.darylz.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author: daryl z
 * @description: MybatisPlus 分页拦截器配置
 */
@Configuration
public class MybatisPlusConfig {


    /**
     * MybatisPlus 3.4.0 及以上版本配置
     *
     * 配置MybatisPlus提供的 分页内部拦截器
     *
     * @return 将分页内部拦截器放入Spring容器中
     */
    @Bean
    public PaginationInnerInterceptor paginationInnerInterceptor() {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // 设置最大单页限制数量, 默认 500 条 , -1 不受限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        // MYSQL("mysql", "MySql数据库"), (设置数据库类型)
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInnerInterceptor.setOptimizeJoin(true);
        return paginationInnerInterceptor;
    }

    /**
     * MybatisPlus 3.4.0 及以上版本配置
     *
     * 配置MybatisPlus提供的 MybatisPlus 拦截器
     * @return 将 MybatisPlus 拦截器放入 Spring 容器中
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 可以添加多个 分页内部拦截器
        mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor()));
        return mybatisPlusInterceptor;
    }
}

测试用例

@Test
    public void testSelectPage() {
        // 参数1: 当前页
        // 参数2: 当前页面大小
        Page<User> page = new Page<>(1, 3);
        QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 134);
        print(page, wrapper);
        // 打印出 第二页
        page.setCurrent(2);
        print(page, wrapper);

    }

    private void print(Page<User> page, QueryWrapper<User> wrapper) {
        IPage<User> userPage = userMapper.selectPage(page, wrapper);
        System.out.println("当前页数 = " + userPage.getCurrent());
        System.out.println("总页数 = " + userPage.getPages());
        System.out.println("数据总条数 = " + userPage.getTotal());

        userPage.getRecords().forEach(System.out::println);
    }

测试结果

[main] [com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize]-[DEBUG] JsqlParserCountOptimize sql=SELECT  id,user_name,password,name,age,email  FROM tb_user 
 
 WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT COUNT(1) FROM tb_user WHERE age <= ? 
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE age <= ? LIMIT ?,? 
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer), 0(Long), 3(Long)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] <==      Total: 3
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7a7d1b47]
当前页数 = 1
总页数 = 3
数据总条数 = 7
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=6, userName=xiangxiang, password=123321, name=孙尚香, age=18, email=sunshangxiang@163.com, address=null)
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4] was not registered for synchronization because synchronization is not active
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@1831717330 wrapping com.mysql.cj.jdbc.ConnectionImpl@75699e35] will not be managed by Spring
[main] [com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize]-[DEBUG] JsqlParserCountOptimize sql=SELECT  id,user_name,password,name,age,email  FROM tb_user 
 
 WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT COUNT(1) FROM tb_user WHERE age <= ? 
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE age <= ? LIMIT ?,? 
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer), 3(Long), 3(Long)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] <==      Total: 3
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4]
当前页数 = 2
总页数 = 3
数据总条数 = 7
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)
User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)

4.9: selectMapsPage

方法定义

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

测试用例

@Test
    public void testSelectMapsPage() {
        Page<Map<String, Object>> page = new Page<>(1, 2);
        QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 90);
        printMap(page, wrapper);
        page.setCurrent(2);
        printMap(page, wrapper);
    }

    private void printMap(Page<Map<String, Object>> page, QueryWrapper<User> wrapper) {
        Page<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, wrapper);
        System.out.println("当前页数 = " + mapPage.getCurrent());
        System.out.println("总页数 = " + mapPage.getPages());
        System.out.println("总条数 = " + mapPage.getTotal());

        List<Map<String, Object>> records = mapPage.getRecords();
        for (Map<String, Object> record : records) {
            // key: 数据库列名
            // value: 列名中对应的数据值
            record.forEach((key, value) -> System.out.println("键 = " + key.toUpperCase() + " , 值 = " + value));
            System.out.println("--------");
        }
    }

测试结果

[main] [com.zaxxer.hikari.HikariDataSource]-[INFO] HikariPool-1 - Starting...
[main] [com.zaxxer.hikari.pool.HikariPool]-[DEBUG] HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@8b91134
[main] [com.zaxxer.hikari.HikariDataSource]-[INFO] HikariPool-1 - Start completed.
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@909786389 wrapping com.mysql.cj.jdbc.ConnectionImpl@8b91134] will not be managed by Spring
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==>  Preparing: SELECT COUNT(*) AS total FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Parameters: 90(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] <==      Total: 1
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?) LIMIT ?
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Parameters: 90(Integer), 2(Long)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] <==      Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@13e698c7]
当前页数 = 1
总页数 = 3
总条数 = 5
键 = PASSWORD , 值 = 123456
键 = USER_NAME , 值 = lisi
键 = NAME , 值 = 李四
键 = ID , 值 = 2
键 = AGE , 值 = 88
键 = EMAIL , 值 = test2@163.cn
--------
键 = PASSWORD , 值 = 123456
键 = USER_NAME , 值 = zhaoliu
键 = NAME , 值 = 赵六
键 = ID , 值 = 4
键 = AGE , 值 = 21
键 = EMAIL , 值 = test4@163.cn
--------
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67d86804] was not registered for synchronization because synchronization is not active
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@1169894049 wrapping com.mysql.cj.jdbc.ConnectionImpl@8b91134] will not be managed by Spring
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==>  Preparing: SELECT COUNT(*) AS total FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Parameters: 90(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] <==      Total: 1
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==>  Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?) LIMIT ?,?
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Parameters: 90(Integer), 2(Long), 2(Long)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] <==      Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67d86804]
当前页数 = 2
总页数 = 3
总条数 = 5
键 = PASSWORD , 值 = 123321
键 = USER_NAME , 值 = xiangxiang
键 = NAME , 值 = 孙尚香
键 = ID , 值 = 6
键 = AGE , 值 = 18
键 = EMAIL , 值 = sunshangxiang@163.com
--------
键 = PASSWORD , 值 = 888888
键 = USER_NAME , 值 = guanyu
键 = NAME , 值 = 关羽
键 = ID , 值 = 11
键 = AGE , 值 = 90
键 = EMAIL , 值 = gaunyu@qq.com
--------

4,10: exists (3.5.0版本新增的判断是否存在的API)

方法定义

/**
     * 根据 Wrapper 条件,判断是否存在记录
     *
     * @param queryWrapper 实体对象封装操作类
     * @return 是否存在记录
     */
    default boolean exists(Wrapper<T> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0;
    }

测试用例

@Test
    public void testExists() {
        User user = new User();
        user.setAge(88);
        user.setEmail("test2@163.cn");
        user.setName("李四");
        System.out.println("是否存在 = " + userMapper.exists(new QueryWrapper<>(user)));
    }


    @Test
    public void testExists2() {
        System.out.println("是否存在 = " + userMapper.exists(
                new QueryWrapper<User>()
                        .eq("user_name", "sunqi")
                        .eq("age", 24)
                        .eq("email", "88888@qq.com")));
    }

测试结果

[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==>  Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE name=? AND age=? AND email=?
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: 李四(String), 88(Integer), test2@163.cn(String)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@203dd56b]
是否存在 = true

---------------------

[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==>  Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE (user_name = ? AND age = ? AND email = ?)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: sunqi(String), 24(Integer), 88888@qq.com(String)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <==      Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1450078a]
是否存在 = false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值