MyBatisPlus-BaseMapper&IService

MyBatisPlus-BaseMapper

MyBatisPlus提供了BaseMapper这个父类,让mapper接口实现此父类可直接生成单表的增删改查

public interface UserMapper extends BaseMapper<User> {
}

在调用时直接调用提供的方法即可

userMapper.selectList(null);

注:这里继承的BaseMapper类的泛型使用表名,也就是实体类名,自动生成单表crud的必要条件就是这两个名字是一样的


BaseMapper提供的方法如下:

Insert

方法名类型参数名描述
insertTentity实体对象

Delete

方法名类型参数名描述
deleteWrapperwrapper实体对象封装操作类(可以为 null)
deleteBatchIdsCollection<? extends Serializable>idList主键 ID 列表(不能为 null 以及 empty)
deleteByIdSerializableid主键 ID
deleteByMapMap<String, Object>columnMap表字段 map 对象

Update

当执行updateById进行更新的时候,根据实体类的字段进行判断是否更新列

如果采用基本类型包装类,则默认列为null,如果采用基本类型,比如int,默认值为0,就会将原有的数值改成0

结论:实体类需要使用包装类型

方法名类型参数名描述
updateByIdTentity实体对象 (set 条件值,可为 null)
updateWrapperupdateWrapper实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

Select

方法名类型参数名描述
selectByIdSerializableid主键 ID
selectOne、selectList、selectMaps、selectObjs、selectCountWrapperqueryWrapper实体对象封装操作类(可以为 null)
selectBatchIdsCollection<? extends Serializable>idList主键 ID 列表(不能为 null 以及 empty)
selectByMapMap<String, Object>columnMap表字段 map 对象
selectPage、selectMapsPageIPagepage分页查询条件(可以为 RowBounds.DEFAULT)

MyBatisPlus-IService

通过 Service CRUD 封装IService 接口,进一步封装 CRUD

采用 get 查询单行、remove 删除、list 查询集合、page 分页的前缀命名方式区分 Mapper 层避免混淆

对比Mapper接口CRUD区别:

  • service添加了批量方法
  • service层的方法自动添加事务

这种解决问题的思维方式就是,简单问题Service解决,复杂业务逻辑再交给Mapper层解决


Service接口

Service接口需要继承Iservice<实体类>的接口,其原理跟mapper接口是一样的

MyBatis帮助我们在Service层就实现了一部分单表的crud功能

但这个接口没有实现全部功能,其中有一些抽象方法等着被实现

public interface UserService extends IService<User> {

}

Service实现类

实现类正常继承该接口,再通过实现ServiceImpl实现类的方式补全剩下的抽象方法实现

这个ServiceImpl有两个泛型

  • mapper接口:用户自身编写继承自BaseMapper的接口,因为crud底层还是通过mapper实现
  • 实体类:用以生成crud功能的实体类名,也就是表名
public class UserService extends ServiceImpl<UserMapper, User> implements com.xiaobai.service.UserService {
    
}

Crud方法

持久层接口 | MyBatis-Plus (baomidou.com)


分页查询的实现

MyBatisPlus的分页实现不再是基于PageHelper插件,而是PaginationInnerInterceptor

MyBaitsPlus提供了一个插件集合,将所需插件添加到插件集合中,再将插件集合注入到IoC容器中即可

使用启动类@Bean注入(启动类也是配置类)

@SpringBootApplication
@MapperScan("com.xiaobai.mapper")
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }

    // 配置MyBatisPlus分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 配置数据库类型为MySQL
        return interceptor;
    }
}

IPage接口和Page实现类

使用Page对象+mapper层(service层)封装好的分页查询方法

替换掉MyBatis原来的startPage+PageInfo在Sql后拼接Limit的方法,使用更简单

@Test
public void test(){
    // 实例化IPage接口的实现类Page对象,设置分页参数
    Page<User> page = new Page<>(1, 10);
    // 调用Mapper层的分页查询方法,将page对象作为参数传递
    Page<User> userPage = userMapper.selectPage(page, null);

    // Page对象也会被封装结果,其中也提供了分页五大件的获取方法
    page.getCurrent(); // currentPage
    page.getSize(); // PageSize
    page.getTotal(); // total
    page.getRecords(); // pageInfo.getList()
}

自定义Mapper方法中使用分页

在mappe接口中自定义方法,返回值为IPage接口类型,传入一个IPage类型的参数page

IPage<UserVo> selectPageVo(IPage<?> page, Integer state);
mapper接口
public interface UserMapper extends BaseMapper<User> {
    IPage<User> selectUserPage(Page<User> page, @Param("age") Integer age);
}
mapper.xml映射文件

在MyBatis中,mapper.xml文件默认存放路径就是classpath:/mapper

所以在配置文件中无需配置mapper-locations字段

private String[] mapperLocations = new String[]{"classpath*:/mapper/**/*.xml"};

<mapper namespace="com.xiaobai.mapper.UserMapper">
    <!--此处resultType仍然使用泛型的类型-->
    <select id="selectUserPage" resultType="user">
        select *
        from user
        where age > #{age}
        <!--这里仍然不可以使用limit结尾,因为使用分页插件-->
    </select>
</mapper>
调用
@Test
public void test() {
    // 使用匿名内部类实例化Page对象传入,查找age>18的数据
    IPage<User> userIPage = userMapper.selectUserPage(new Page<User>(1, 10), 18);

    System.out.println(userIPage.getCurrent());
    System.out.println(userIPage.getSize());
    System.out.println(userIPage.getTotal());
    userIPage.getRecords().forEach(System.out::println);
}