MyBatis Plus 快速入门

2022-11-15 13:34:52 浏览数 (1)

1 MyBatis Plus 介绍

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

(1)提供Mapper基类接口, 可以自动完成简单的CRUD操作;

(2)提供QueryWrapper包装器,它支持类似Hibernate的Criteria的多于条件查询和排序;

(3)提供MyBatis拦截器,能自动实现分页。

官网:Redirect

       官方推荐学习视频:https://www.imooc.com/learn/1130

2 搭建Spring boot 的 Mybatis Plus 支持

(1)添加依赖

代码语言:javascript复制
        <dependency>

            <groupId>com.baomidou</groupId>

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

            <version>3.2.0</version>

        </dependency>

(2)配置应用 application.yml

代码语言:javascript复制
spring:

  datasource:

    url: jdbc:mysql://localhost:3306/mycinema?serverTimezone=GMT+8

    username: root

    password: 1234

mybatis-plus:

  # 如果是放在resource目录 classpath:/mapper/*Mapper.xml

  mapper-locations: classpath:mapper/*Mapper.xml

  #实体扫描,多个package用逗号或者分号分隔

  typeAliasesPackage: mycinema.entity

  configuration:

    #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)

    map-underscore-to-camel-case: false

(3)数据实体 Category.java

代码语言:javascript复制
@Data

@AllArgsConstructor

@NoArgsConstructor

public class Category {

    @TableId(type = IdType.AUTO)    //数据库主键自增,保存后带回自增值

    private int id;

    private String name;

}

(4)mapper接口

代码语言:javascript复制
// 继承的 mapper 接口

public interface CategoryMapper extends BaseMapper<Category> { 

}

// spring boot 启动类,加入 @MapperScan

@MapperScan("mycinema.mapper")

@SpringBootApplication

public class MycinemaMpApplication {

    public static void main(String[] args) {

        SpringApplication.run(MycinemaMpApplication.class, args);

    }

}

(5)测试接口中的CRUD操作

代码语言:javascript复制
@SpringBootTest

public class CategoryMapperTest {

    @Autowired

    private CategoryMapper target;

    @Test

    public void testSelectById() { assertEquals("战争", target.selectById(2).getName()); }

    @Test

    public void testInsert() {

        Category c = new Category(0, "测试1");

        target.insert(c);

        assertTrue(c.getId()>0);

    }

    @Test

    public void testUpdateById() {

        Category c = new Category(3, "言情");

        target.updateById(c);

        assertEquals("言情", target.selectById(3).getName());

    }

    @Test

    public void testDeleteById() { target.deleteById(5); }

}

3 多条件查询

MyBatis Plus 提供了 QueryWrapper 对象,它有点类似 Hibernate 的 Criteria,可以灵活的为查询添加条件。 

编写一个Movie实体类:

代码语言:javascript复制
@Data

public class Movie {

    @TableId(type = IdType.AUTO)

    private int id;

    private String title;

    private String movieCode;

    private String director;

    private Date dateReleased;

    private int categoryId;

}

使用 QueryWrapper 实现灵活的多条件查询:

代码语言:javascript复制
@Service

public class MovieBizImpl implements MovieBiz {

    @Autowired

    private MovieMapper movieDb;

    @Override

    public List<Movie> findMovies(int cid, String title) {

        QueryWrapper<Movie> queryWrapper = new QueryWrapper<Movie>();

        if(cid>0)

            queryWrapper.eq("categoryId", cid);

        if(title!=null && !title.isBlank())

            queryWrapper.like("title", "%" title "%");

        return movieDb.selectList(queryWrapper);

    }

}

4 排序

QueryWrapper 对象还提供了 “orderByDesc” 和 “orderByAsc” 等方法,可以简单实现排序

queryWrapper.orderByDesc("dateReleased");

5 分页

(1)配置分页拦截器:

在配置类(也可以是SpringBoot启动类)中声明分页拦截器Bean

代码语言:javascript复制
 @Bean

    public PaginationInterceptor paginationInterceptor() {

        return new PaginationInterceptor();

    }

(2)使用分页对象 IPage<T> 控制当前页码和每页大小

代码语言:javascript复制
    public IPage<Movie> findMoviesPage(..., int pageNum, int pageSize){

        QueryWrapper<Movie> query = new QueryWrapper<Movie>();

        ......

        Page<Movie> page = new Page<Movie>(pageNum, pageSize);  //设置分页对象

        return movieDb.selectPage(page, query);

    }

IPage<T> 返回对象中可以获取当前页数据实体集合 getRecords(),总行数 getTotal(),总页数 getPages(),当前页 getCurrent(),每页大小 getSize() 等数据

6 一种简单的外键对象加载策略

(1)在实体类中先配置外键对象(Category)不是数据库的字段(@TableField(exist=false))

代码语言:javascript复制
@Data

public class Movie {

    @TableId(type = IdType.AUTO)

    private int id;

    private String title;

    private String movieCode;

    private String director;

    private Date dateReleased;

    private int categoryId;

    @TableField(exist = false)

    private Category category;

}

(2)在加载时使用单独查询外键的方式加载

代码语言:javascript复制
@Service

@Transactional

public class MovieServiceImpl {

    @Autowired

    private MovieMapper movieDb;

    @Autowired

    private CategoryMapper categoryDb;

   

    @Transactional(readOnly=true)   //亲测:如果没有事务管理,二次查询Categoy就没有一级缓存了

    public IPage<Movie> findMoviesWithCategoryPage(Integer cateId, String title, String orderByColumn, Boolean orderByAsc, int pageNum, int pageSize){

        QueryWrapper<Movie> query = new QueryWrapper<Movie>();

        ......

        IPage<Movie> page = movieDb.selectPage(new Page<Movie>(pageNum, pageSize), query);

        //循环添加Category对象

        page.getRecords().forEach(x->x.setCategory(categoryDb.selectById(x.getCategoryId())));

        return page;

    }

}

0 人点赞