MyBatis-Plus(实用篇)

一、基础组件

简介

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

1、BaseMapper接口API

  • BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型为操作的实体类型
  • Mapper继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
  • BaseMapper接口,增删改返回影响数据条数的Integer

在这里插入图片描述

BaseMapper中提供的CRUD方法

  • 增加:insert

在这里插入图片描述

  • 删除:delete

在这里插入图片描述

  • 修改:update
  • update方法:entity实体对象某属性为null,则不会修改此属性

在这里插入图片描述

  • 查询:select

在这里插入图片描述

  • selectObjs方法:只返回第一个字段的值
  • selectPage方法:分页需要添加分页插件,否则不生效

在这里插入图片描述

2、IService接口API

  • 封装IService接口,进一步封装CRUD采用get查询单行、remove删除、list查询集合、page分页前缀命名方式
  • IService接口,增删改返回是否操作成功的boolean
  • 泛型 T 为任意实体对象

在这里插入图片描述

IService中提供的CRUD方法

  • 增加:save

在这里插入图片描述

  • 删除:remove

在这里插入图片描述

  • 修改:update

在这里插入图片描述

  • 新增或修改:主键存在则根据主键修改,主键不存在则新增

在这里插入图片描述

  • 查询:单个get,集合list
  • getOne方法,多个抛出异常,第二个参数throwEx设置为false则获取第一条数据

在这里插入图片描述
在这里插入图片描述

  • 查询记录数:count

在这里插入图片描述

  • 分页查询:page

在这里插入图片描述
在这里插入图片描述

  • 集合查询:list
  • listObjs方法,可以将查询结果T类型转换成V类型返回List<V>

在这里插入图片描述

3、创建Service层操作数据

  • Mapper接口:创建UserMapper对象并继承BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {}
  • Service接口:创建UserService并继承IService
/**
  * UserService继承IService模板提供的基础功能 
  */
public interface UserService extends IService<User> {}
  • Service实现类:创建UserService的实现类并继承ServiceImpl
/**
  * ServiceImpl实现了IService,提供了IService中基础功能的实现 
  * 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
  */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService{}

二、常用注解

1、@TableName

  • 在实体类类型上添加@TableName(“t_user”),标识实体类对应的表
  • 不加注解,默认驼峰转下划线则是表明,如实体OrderInfo,则默认对应表名order_info
@Data
@TableName("t_user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
  • 为实体类所对应的表名设置默认的前缀,那么就不需要在每个实体类上通过@TableName标识实体类对应的表
mybatis-plus:
  global-config:
    db-config:
      # 设置实体类所对应的表的统一前缀
      table-prefix: t_

2、@TableId

2.1、value属性

  • 不加注解,默认情况Long id就是主键
  • 如果想其他字段作为主键,且实体与数据库字段不一致,则添加@TableId(value = “tid”)
@Data
public class User {
    @TableId(value = "tid")
    private Long uid;
    private String name;
    private Integer age;
    private String email;
}

2.2、type属性

常用主键策略:

枚举值描述
IdType.AUTO数据库ID自增;该类型请确保数据库设置了ID自增,否则无效
IdType.INPUT用户输入ID;该类型可以通过自己注册自动填充插件进行填充
IdType.ASSIGN_ID(默认)主键类型为number或string的雪花算法;只有当插入对象ID 为空,才自动填充
IdType.ASSIGN_UUID主键类型为string,UUID.replace(“-”,“”);只有当插入对象ID 为空,才自动填充
IdType.NONE没有设置主键类型;跟随全局;全局的主键策略如果没有设置,默认是雪花算法
@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Long uid;
    private String name;
    private Integer age;
    private String email;
}

Mybatis-plus中的内置雪花算法

  • 在某些情况下,我们想提前获取这个ID,调用com.baomidou.mybatisplus.core.toolkit.IdWorker.getId()方法即可

3、@TableField

3.1、value属性

  • 解决对象中字段名和数据库不匹配(没有遵循小驼峰或者完全不匹配)
//指定数据库字段名称
@TableField(value = "email")
private string mail
  • 解决关键字报错
// 执行的sql语句就变成`关键字`,这样sql就不会报错了
@TableField(value = "`desc`")
private string desc

3.2、exist属性

  • 解决对象中的属性字段在表中不存在的问题
@TableField(exist = false)
private Boolean checked;

3.3、select属性

  • 在查询操作中某个字段值不想被查询展示出来(比如密码password),可使用此注解
@TableField(select = false)
private String password;

3.4、condition属性

  • 预处理where查询条件
// 实体注解-实现模糊查询
@TableField(condition = SqlCondition.LIKE)
private String name;

// 业务代码
User user = new User();
user.setName("张");
userService.lambdaQuery(user).list();

// 打印sql
SELECT id,user_name,age FROM user WHERE name LIKE CONCAT('%',?,'%')
  • 链式查询不生效(没有模糊查询)
userService.lambdaQuery().eq(User::getName,"张").list();

3.5、update属性

  • 预处理update set 部分
  • 方式一:@TableField(update="%s+1") update 表 set 字段=字段+1 where …
  • 方式二:@TableField(update="now()") 使用数据库时间,update 表 set 字段=now() where …
// 方式三:
// 实体注解-实现修改字段时候,前后添加“**” 其中 %s 会填充为字段
@TableField(update = "CONCAT('**',%s,'**')")
private String name;

// 业务代码
User user = new User();
user.setId(1);
user.setName("张三");
userService.updateById(user);

// 打印sql
UPDATE user SET name=CONCAT('**',name,'**') WHERE id=?
  • 链式查询不生效(前后没有填充**)
userService.lambdaQuery().eq(User::getName,"张").list();

3.6、fill属性

  • 解决每个数据库表都有create_time 和 update_time字段,我们可以使用自动填充功能维护这两个字段
// 实体字段注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

// 枚举类
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入填充字段
     */
    INSERT,
    /**
     * 更新填充字段
     */
    UPDATE,
    /**
     * 插入和更新填充字段
     */
    INSERT_UPDATE
}

创建MyMetaObjectHandler配置类,实现MetaObjectHandler接口

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
	Date date = new Date();
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, date);
        this.strictInsertFill(metaObject, "updateTime", Date.class, date);
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, date);
    }
}

3.7、insertStrategy、updateStrategy、whereStrategy属性

  • insertStrategy:当insert操作时,该字段拼接insert语句时的策略
  • updateStrategy:当更新操作时,该字段拼接set语句时的策略
  • whereStrategy:表示该字段在拼接where条件时的策略
public enum FieldStrategy {
    /**
     * 忽略判断,所有字段都进行更新和插入
     * 无论什么值,直接拼接,没有值,则拼接null
     */
    IGNORED,
    /**
     * 只更新和插入非NULL值
     * 相当于添加if判断,不为null才操作
     * <if test="columnProperty != null">column=#{columnProperty}</if>
     */
    NOT_NULL,
    /**
     * 只更新和插入非NULL值且非空字符串
     * 相当于添加if判断,不为null而且不是空字符串才操作
     * <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     */
    NOT_EMPTY,
    /**
     * 默认NOT_NULL
     */
    DEFAULT,
    /**
     * 永远不进行更新和插入
     */
    NEVER
}

3.8、typeHandler属性

  • 类型处理器,设置存入数据库的类型
  • 设置mysql数据库字段info为json类型@TableField(typeHandler = JacksonTypeHandler.class)表示将UserInfo对象转为json对象入库
  • 此时user出现对象嵌套List<Address>,需要设置resultMap响应对象,@TableName(autoResultMap = true)表示自动映射resultMap

在这里插入图片描述

4、@TableLogic

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

实现逻辑删除

  • 数据库中创建逻辑删除状态列,设置默认值为0

在这里插入图片描述

  • 实体类中添加逻辑删除属性

在这里插入图片描述

  • 测试删除功能,真正执行的是修改
public void testDeleteById(){
    int result = userMapper.deleteById(1527472864163348482L);
    System.out.println(result > 0 ? "删除成功!" : "删除失败!");
    System.out.println("受影响的行数为:" + result);
}

在这里插入图片描述

  • 此时执行查询方法,查询的结果为自动添加条件is_deleted=0
public void testSelectList(){
    List<User> users = userMapper.selectList(null);
}

在这里插入图片描述

三、条件构造器

1、wapper介绍

在这里插入图片描述

  • Wrapper:条件构造抽象类,最顶端父类
    • AbstractWrapper:用于查询条件封装,生成sql的where条件
      • QueryWrapper:查询条件封装
      • UpdateWrapper:update条件封装
      • AbstractLambdaWrapper:使用Lambda语法
        • LambdaQueryWrapper:用于Lambda语法使用的查询Wrapper
        • LambdaUpdateWrapper:用于Lambda语法更新Wrapper

2、构造器常用方法

函数名说明说明/例子
eq等于=例:eq(“name”,“zhangsan”) —> name = ‘zhangsan’
ne不等于<>例:ne(“name”,“zhangsan”) —> name <> ‘zhangsan’
gt大于>例:gt(“age”,18) —> age > 18
ge大于等于>=例:ge(“age”,18) —> age >= 18
lt小于<例:lt(“age”,18) —> age < 18
le小于等于<=例:le(“age”,18) —> age <= 18
betweenbetween 值1 and 值2例:between(“age”,10,20) —> age between 10 and 20
notBetweennot between 值1 and 值2例:notBetween(“age”,10,20) —> age not between 10 and 20
likelike ‘%值%’例:like(“name”,“强”) —> name like ‘%强%’
notLikenot like ‘%值%’例:notLike(“name”,“强”) —> name not like ‘%强%’
likeLeftlike ‘%值’例:like(“name”,“飞”) —> name like ‘%强’
likeRightlike ‘值%’例:like(“name”,“王”) —> name like ‘王%’
isNull字段 is null例:isNull(“emal”) —> email is null
isNotNull字段 is not null例:isNotNull(“emal”) —> email is not null
in字段 in (值1,值2…)例:in(“age”,{10,18,30}) —> age in (10,18,30)
notIn字段 not in (值1,值2…)例:notIn(“age”,{10,18,30}) —> age not in (10,18,30)
inSql字段 in ( sql语句 )inSql(“id”, “select id from table where name like ‘%J%’”)
—> id in (select id from table where name like ‘%J%’)
notInSql字段 not in ( sql语句 )notInSql(“id”, “select id from table where name like ‘%J%’”)
—> id not in (select id from table where name like ‘%J%’)
groupBy分组 group by 字段,…例:groupBy(“id”,“name”) —> group by id,name
⚠️注意:如果不查询聚合函数,默认返回第一条数据
orderBy排序 ordery by 字段,…例:orderBy(true,true,“id”,“name”) —> order by id asc,name asc
orderByAsc升排序 order by 字段,… asc例:orderByAsc(“id”,“name”) —> order by id,name
orderByDesc降排序 order by 字段,… desc例:orderByDesc(“id”,“name”) —> order by id desc,name desc
havinghaving (sql语句)having(“sum(age) > {0}”,18) —> having sum(age) > 18
or拼接or例:eq(“id”,1).or().eq(“name”,“老王”) —> id =1 or name = ‘老王’
andand 嵌套例:and(i -> i.eq(“name”,“李白”).ne(“status”,“活着”))
—> and (name = ’李白‘ and status <> ‘活着’)
apply拼接sql**例:apply(“date_format(date_time,‘%Y-%m-%d’) = {0}”,“2002-08-08”)
—> date_fromat(date_time,‘%Y-%m-%d’) = ‘2008-08-08’
⚠️注意:动态入参对应{index}部分,直接写sql语句,有sql注入风险
last拼接到sql的最后例:last(“limit 5”)
注意事项:只能调用一次,多次调用以最后一次为准,有sql注入风险
exists拼接exists (sql语句)例:exists(“select id from table where age = 1”)
not exists拼接not exists (sql语句)例:not exists(“select id from table where age = 1”)
nested正常嵌套 不带and和or例:nested(i-> i.eq(“name”,“李华”).gt(“age”,20))
—> (name = “李华” and age > 20)

3、组装条件示例

条件的优先级

sql语句规则:and和or一起用,and优先级高

 /** 组装修改条件  将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改 **/
@Test
public void test01() {
    /*
        UPDATE t_user SET user_name=?, email=?
        age > ? AND user_name LIKE ? OR email IS NOT NULL
     */
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.gt("age", 20)
            .like("user_name", "a")
            .or()
            .isNotNull("email");
    User user = new User();
    user.setName("小明");
    user.setEmail("test@atguigu.com");
    int result = userMapper.update(user, queryWrapper);
    System.out.println("result = " + result);
}

/** 条件优先级  将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改 **/
@Test
public void test02() {
    // lambda中条件优先级
    /*
        UPDATE t_user SET user_name=?, email=?
        WHERE user_name LIKE ? AND (age > ? OR email IS NULL)
     */
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.like("user_name", "a")
            .and(i -> i.gt("age", 20).or().isNull("email"));
    User user = new User();
    user.setName("小红");
    user.setEmail("test@atguigu.com");
    int result = userMapper.update(user, queryWrapper);
    System.out.println("result = " + result);
}

Lambda表达式

@Test
public void test3() {
    /*
        SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user
        WHERE user_name LIKE ? AND age <= ?
     */
    String username = "a";
    Integer ageBegin = null;
    Integer ageEnd = 30;
    //组装set子句
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    //避免使用字符串表示字段,防止运行时错误
    queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username)
            .gt(ageBegin != null, User::getAge, ageBegin)
            .le(ageEnd != null, User::getAge, ageEnd);
    List<User> list = userMapper.selectList(queryWrapper);
    list.forEach(System.out::println);
}

@Test
public void test4() {
    /*
        UPDATE t_user SET user_name=?,email=?
        WHERE user_name LIKE ? AND (age > ? OR email IS NULL)
     */
    LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
    updateWrapper.like(User::getName, "a")
            //lambda表达式内的逻辑优先运算
            .and(i -> i.gt(User::getAge, 20).or().isNull(User::getEmail)); 
    updateWrapper.set(User::getName, "小黑").set(User::getEmail, "abc@atguigu.com");
    int result = userMapper.update(null, updateWrapper);
    System.out.println("result = " + result);
}

四、扩展功能

1、链式查询与修改

IService接口中提供

  • 链式查询:可以串着写多个条件
    • .one()结尾:查询单条数据
    • .list()结尾:查询多条数据
    • .count()结尾:查询记录数

在这里插入图片描述

 @Test
 public void test1(){
 	 // 单个查询,多个报错
     User user = userService.lambdaQuery().eq(User::getName, "Tom").one();
	 // 集合查询
     List<User> userList = userService.lambdaQuery().like(User::getName, "J").eq(User::getAge,20).list();
     // 记录数查询
     Integer count = userService.lambdaQuery().like(User::getAge, 20).select(User::getName, User::getAge).count();
  }
  • 链式修改:可以串着写多个条件
    • .update()结尾:修改set的字段(只修改set的字段,fill属性更新填充属性不会修改)
    • .update(entity)结尾:修改entity数据的字段
    • .remove()结尾:删除数据

在这里插入图片描述

  @Test
  public void test2() {
	  // set修改某些属性
      userService.lambdaUpdate().eq(User::getName, "Tom").set(User::getId, 110).set(User::getAge, 15).update();
      // 修改整个对象
      User user = new User();
      user.setId(110L);
      user.setAge(15);
      userService.lambdaUpdate().eq(User::getName, "Tom").update(user);
      // 根据名称删除
      userService.lambdaUpdate().eq(User::getName, "Jack").remove();
   }

2、静态工具类Db

Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db

在这里插入图片描述

@Test
void testDbGet() {
    User user = Db.getById(1L, User.class);
    System.out.println(user);
}@Test
void testDbList() {
    // 利用Db实现复杂条件查询
    List<User> list = Db.lambdaQuery(User.class)
            .like(User::getUsername, "o")
            .ge(User::getBalance, 1000)
            .list();
}@Test
void testDbUpdate() {
    Db.lambdaUpdate(User.class)
            .set(User::getBalance, 2000)
            .eq(User::getUsername, "Rose");
}

这样就可以在任意serviceImpl中都可以使用任意的service,而不需要依赖注入了

4、自定义sql

4.1、自定义xml分页sql

UserMapper中定义接口方法

  • page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
/**
* 根据年龄查询用户列表,分页显示
*/
Page<User> selectPageVo(@Param("page") Page<User> page,@Param("age") Integer age);

UserMapper.xml中编写SQL

<select id="selectPageVo" resultType="User">
    select id,username as name,age,email from t_user where age > #{age}
</select>

测试方法

  • xml中没有分页语句,mybatisplus自动分页
  • 前提必须有分页插件,否则没有分页效果
@Test
public void testSelectPageVo(){ //设置分页参数
    Page<User> page = new Page<>(1, 5); 
    userMapper.selectPageVo(page, 20);
    //获取分页数据
    List<User> list = page.getRecords(); 
    list.forEach(System.out::println); 
    System.out.println("当前页:"+page.getCurrent()); 
    System.out.println("每页显示的条数:"+page.getSize()); 
    System.out.println("总记录数:"+page.getTotal()); 
    System.out.println("总页数:"+page.getPages()); 
    System.out.println("是否有上一页:"+page.hasPrevious()); 
    System.out.println("是否有下一页:"+page.hasNext());
}

4.2、@Select注解自定义sql

普通sql

@Select("select * from student where age = #{age} and user_name = #{userName}")
Student getStudent( @Param("age") Integer age, @Param("userName") String userName);

带Wrapper条件sql

  • @Param("ew"):固定写法,可以参照BaseMapper接口里的方法
  • ${ew.customSqlSegment}:固定写法,在sql后面拼接条件,不需要写where关键字
  • @Param("page") Page<?> page:Wrapper条件和分页可以共用,但是分页需要写在最前面
// 单表查询
@Select("select * from student ${ew.customSqlSegment}")
Student getStudentById( @Param("ew") QueryWrapper<Student> wrapper);

// 多表查询
@Select("SELECT u.* FROM student u INNER JOIN address a ON u.id = a.student_id ${ew.customSqlSegment}")
List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);

4.3、连表left join和inner join的分页查询区别

  • left join查询通过Page<?> page参数自动分页时候,查询总条数COUNT(*)时候会将left join去掉,也就是只查主表的数据
  • 此时如果有副表的字段作为查询条件会报错:Unknown column ‘xxx’ in ‘where clause’(主表找不到xxx字段)
// 情况1:如果查询条件中有address的字段,比如模糊查询地址名称
// 情况2:如果查询条件的字段,两个表都有,这里会有问题
// 自动分页的查询count(*)时候,就会抛出以上异常
@Select("SELECT u.* FROM student u LEFT JOIN address a ON u.id = a.student_id ${ew.customSqlSegment}")
List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);
  • 解决方式:嵌套一层select * from (连表复杂sql)as result ${ew.customSqlSegment}
@Select("SELECT * FROM (SELECT u.* FROM student u LEFT JOIN address a ON u.id = a.student_id) as result ${ew.customSqlSegment}")
List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);
  • inner join查询通过Page<?> page参数自动分页时候,查询总条数COUNT(*)时候不会将inner join去掉,所以一般不需要嵌套

4.4、连表查询条件Wrapper和响应IPage的泛型

  • 查询条件Wrapper和响应IPage的泛型非表实体也行,只有符合数据库字段的驼峰命名即可(需要创建实体对象)
  • 如果查询条件同时需要多个表字段,也可以@Param("ew") Wrapper<?> queryWrapper(不需要创建实体对象)

5、IPage的泛型转换(entity转换为vo)

// 分页查询
Page<UserEntity> userPage = super.lambdaQuery().page(new Page<>(request.getCurrent(), request.getSize()));
// entity转换为vo
IPage<UserVO> infoResPage = userPage.convert(item -> Convert.convert(UserVO.class, item));

6、SimpleQuery工具类

  • Simplequery可以对selectList查询后的结果用stream流进行了一些封装,使其可以返回一些指定结果,简洁api的调用

示例

  • 获取Student对象集合的名字集合
// 方式一
List<String> nameList = SimpleQuery.list(
        new LambdaQueryWrapper<Student>().like(Student::getUserName, "张"),
        Student::getUserName
);

// 方式二
List<Student> list = studentService.list();
List<String> nameList2 = SimpleQuery.list2List(list, Student::getUserName);
  • 先将Student对象的名称前后添加**再获取名字集合
List<String> nameList = SimpleQuery.list(
        new LambdaQueryWrapper<Student>().like(Student::getUserName, "李"),
        Student::getUserName,
        new Consumer<Student>() {
            @Override
            public void accept(Student student) {
                student.setUserName("**"+student.getUserName()+"**");
            }
        }
);
  • 返回key=名字,value=年龄的map
Map<String, Integer> map = SimpleQuery.map(
        new LambdaQueryWrapper<>(), 
        Student::getUserName, 
        Student::getAge
);
  • group分组,key位名字,value相同名字的Student对象集合
Map<String, List<Student>> group = SimpleQuery.group(
        new LambdaQueryWrapper<Student>(), 
        Student::getUserName
);

7、ActiveRecord

  • ActiveRecord(活动记录,简称 AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录
  • ActiveRecord 一直广受解释型动态语言( PHP 、 Ruby 等)的喜爱,通过围绕一个数据对象进行CRUD操作
  • 仅仅需要让实体类继承Model类且实现主键指定方法
@Data
@TableName(value = "student")
public class Student extends Model<Student> {
    /**
     * 主键id
     */
    private Long id;
    /**
     * 姓名
     */
    private String userName;
    /**
     * 年龄
     */
    private Integer age;
}

@Test
void activeRecordAddQ{
	Student student = new Student();
	student.setUserName("李四");
	student.setAge(12);
	student.insert();
}

Model抽象类方法

在这里插入图片描述

注意: 必须存在对应的原始mapper并继承baseMapper并且可以使用

五、插件

1、Mybatis插件

在这里插入图片描述

MybatisPlusInterceptor分页插件

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注意使用哪种数据库
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

2、MyBatisX插件

2.1、生成逆向工程

  • 找到我们需要生成的表点击右键

在这里插入图片描述

  • 填写完信息以后下一步

在这里插入图片描述

  • 继续填写信息

在这里插入图片描述

  • 结果展示

在这里插入图片描述

2.2、快速生成CRUD

MyBaitsX可以根据我们在Mapper接口中输入的方法名【alt+Enter】快速帮我们生成对应的sql语句

在这里插入图片描述

在这里插入图片描述

mybatisplus的mapper分页查询可以通过在mapper接口中定义方法,并使用`com.baomidou.mybatisplus.core.mapper.BaseMapper`提供的分页查询方法来实现。首先,确保你已经正确配置了mybatis-plus的分页插件`PaginationInnerInterceptor`,如引用和引用所示。 然后,在mapper接口中定义一个方法,方法的返回类型为`com.baomidou.mybatisplus.core.metadata.IPage`,并使用`@Param`注解指定方法参数。在方法体中,调用`selectPage`方法,将需要分页查询的条件和分页信息作为参数传入。具体代码如下: ```java import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; public interface YourMapper extends BaseMapper<YourEntity> { IPage<YourEntity> getPageData(@Param("page") Page<YourEntity> page, @Param("yourCondition") YourCondition yourCondition); } ``` 其中,`YourEntity`为你的实体类,`YourCondition`为你的查询条件类。 在使用该接口方法进行分页查询时,需要创建`Page`对象并设置分页信息,然后将`Page`对象和查询条件作为参数传入方法中。如下所示: ```java import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class YourService { @Autowired private YourMapper yourMapper; public IPage<YourEntity> getPageData(int pageNum, int pageSize, YourCondition yourCondition) { Page<YourEntity> page = new Page<>(pageNum, pageSize); // 创建Page对象并设置分页信息 return yourMapper.getPageData(page, yourCondition); // 调用mapper接口方法进行分页查询 } } ``` 以上是使用mybatis-plus的mapper进行分页查询的方法。需要注意的是,分页查询方法中的参数名需要与mapper接口方法中的`@Param`注解值保持一致。 如果你还有其他
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬天vs不冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值