springboot中使用mybatis-plus入门级教程

MyBatis-Plus的使用

  • MyBatis-Plus简介
  • 使用 SpringBoot 快速使用 MyBatis-Plus
    • 准备工作
    • Mybatis-Plus常用注解
    • Mybatis-Plus代码生成器
    • MyBatis-Plus 分页插件的使用
    • Mybatis-Plus CRUD操作

MyBatis-Plus简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方文档中的定义,更多的介绍和使用可参考 官方文档。

使用 SpringBoot 快速使用 MyBatis-Plus

准备工作

1. 可以使用 IDEA 安装MybatisX——一款全免费且强大的 IDEA 插件,支持跳转,自动补全生成 SQL,代码生成 。
springboot中使用mybatis-plus入门级教程_第1张图片

  1. 添加 MyBatis-Plus 依赖
	<dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.0-RC3</version>
    </dependency>
  1. 为了简化开发,引入lombok依赖(可自动生成setter/getter、equals、canEqual、hashCode、toString方法)
	<dependency>
    	<groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
  1. 在 application.yml 文件中配置 mysql 数据源信息
	spring:
  		#使用druid连接池来连接数据库
  		datasource:
    		#数据库连接路径
    		url: jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf-8&serverTimezone=UTC
    		#数据库驱动类
    		driver-class-name: com.mysql.cj.jdbc.Driver
    		#数据库用户名
    		username: root
    		#数据库密码
    		password: 123456
  1. 编写实体类
    springboot中使用mybatis-plus入门级教程_第2张图片
  2. 编写操作实体类的 Mapper 类。直接继承 BaseMapper,可以省去xml的编写当然也可以在xml中自定义sql查询语句。
    springboot中使用mybatis-plus入门级教程_第3张图片
  3. 在启动类里扫描Mapper类,即项目主入口添加@MapperScan注解
    springboot中使用mybatis-plus入门级教程_第4张图片
  4. 若遇到@Autowired标记的变量出现红色下划线时,但不影响正常运行,实在看着别扭可以进入 Settings,找到 Inspection,并选择其中的 Spring Core -> Code -> Autowiring for Bean Class,将 Error 改为 Warning,即可
    springboot中使用mybatis-plus入门级教程_第5张图片

Mybatis-Plus常用注解

【@TableName 】
    @TableName               用于定义表名
注:
    常用属性:
    value                用于定义表名

【@TableId】
    @TableId                 用于定义表的主键
注:
    常用属性:
    value           用于定义主键字段名
    type            用于定义主键类型(主键策略 IdType)

   主键策略:
      IdType.AUTO          主键自增,系统分配,不需要手动输入
      IdType.NONE          未设置主键
      IdType.INPUT         需要自己输入 主键值。
      IdType.ASSIGN_ID     系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。
      IdType.ASSIGN_UUID   系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。

【@TableField】  
    @TableField            用于定义表的非主键字段。
注:
    常用属性:
        value                用于定义非主键字段名
        exist                用于指明是否为数据表的字段, true 表示是,false 为不是。
        fill                 用于指定字段填充策略(FieldFill)。
        
    字段填充策略:(一般用于填充 创建时间、修改时间等字段)
        FieldFill.DEFAULT         默认不填充
        FieldFill.INSERT          插入时填充
        FieldFill.UPDATE          更新时填充
        FieldFill.INSERT_UPDATE   插入、更新时填充。

【@TableLogic】
    @TableLogic           用于定义表的字段进行逻辑删除(非物理删除)
注:
    常用属性:
        value            用于定义未删除时字段的值
        delval           用于定义删除时字段的值
        
【@Version】
    @Version             用于字段实现乐观锁

Mybatis-Plus代码生成器


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;

public class TestAutoGenerate {
    @Test
    public void autoGenerate() {
        // Step1:代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // Step2:全局配置
        GlobalConfig gc = new GlobalConfig();
        // 填写代码生成的目录(需要修改)
        String projectPath = "E:\\myProject\\test\\test_mybatis_plus";
        // 拼接出代码最终输出的目录
        gc.setOutputDir(projectPath + "/src/main/java");
        // 配置开发者信息(可选)(需要修改)
        gc.setAuthor("lyh");
        // 配置是否打开目录,false 为不打开(可选)
        gc.setOpen(false);
        // 实体属性 Swagger2 注解,添加 Swagger 依赖,开启 Swagger2 模式(可选)
        //gc.setSwagger2(true);
        // 重新生成文件时是否覆盖,false 表示不覆盖(可选)
        gc.setFileOverride(false);
        // 配置主键生成策略,此处为 ASSIGN_ID(可选)
        gc.setIdType(IdType.ASSIGN_ID);
        // 配置日期类型,此处为 ONLY_DATE(可选)
        gc.setDateType(DateType.ONLY_DATE);
        // 默认生成的 service 会有 I 前缀
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // Step3:数据源配置(需要修改)
        DataSourceConfig dsc = new DataSourceConfig();
        // 配置数据库 url 地址
        dsc.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8");
        // dsc.setSchemaName("testMyBatisPlus"); // 可以直接在 url 中指定数据库名
        // 配置数据库驱动
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        // 配置数据库连接用户名
        dsc.setUsername("root");
        // 配置数据库连接密码
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // Step:4:包配置
        PackageConfig pc = new PackageConfig();
        // 配置父包名(需要修改)
        pc.setParent("com.lyh.test");
        // 配置模块名(需要修改)
        pc.setModuleName("test_mybatis_plus");
        // 配置 entity 包名
        pc.setEntity("entity");
        // 配置 mapper 包名
        pc.setMapper("mapper");
        // 配置 service 包名
        pc.setService("service");
        // 配置 controller 包名
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        // Step5:策略配置(数据库表配置)
        StrategyConfig strategy = new StrategyConfig();
        // 指定表名(可以同时操作多个表,使用 , 隔开)(需要修改)
        strategy.setInclude("test_mybatis_plus_user");
        // 配置数据表与实体类名之间映射的策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 配置数据表的字段与实体类的属性名之间映射的策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 配置 lombok 模式
        strategy.setEntityLombokModel(true);
        // 配置 rest 风格的控制器(@RestController)
        strategy.setRestControllerStyle(true);
        // 配置驼峰转连字符
        strategy.setControllerMappingHyphenStyle(true);
        // 配置表前缀,生成实体时去除表前缀
        // 此处的表名为 test_mybatis_plus_user,模块名为 test_mybatis_plus,去除前缀后剩下为 user。
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);

        // Step6:执行代码生成操作
        mpg.execute();
    }
}

MyBatis-Plus 分页插件的使用

  1. 首先,mybatis-plus分页插件需要先进行配置
@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}
  1. 编写分页代码,直接 new 一个 Page 对象,对象需要传递两个参数(当前页,每页显示的条数)。调用 mybatis-plus 提供的分页查询方法,其会将 分页查询的数据封装到 Page 对象中。
@Test
public void testPage() {
    // Step1:创建一个 Page 对象
    Page<User> page = new Page<>();
    // Page page = new Page<>(2, 5);
    // Step2:调用 mybatis-plus 提供的分页查询方法
    userService.page(page, null);
    // Step3:获取分页数据
    System.out.println(page.getCurrent()); // 获取当前页
    System.out.println(page.getTotal()); // 获取总记录数
    System.out.println(page.getSize()); // 获取每页的条数
    System.out.println(page.getRecords()); // 获取每页数据的集合
    System.out.println(page.getPages()); // 获取总页数
    System.out.println(page.hasNext()); // 是否存在下一页
    System.out.println(page.hasPrevious()); // 是否存在上一页
}

Mybatis-Plus CRUD操作

  1. Service 接口方法
    使用 代码生成器 生成的 service 接口中,其继承了 IService 接口。IService 内部进一步封装了 BaseMapper 接口的方法
    使用时,可以通过 生成的 mapper 类进行 CRUD 操作,也可以通过 生成的 service 的实现类进行 CRUD 操作。(当然,自定义代码执行也可)此处简单介绍一下 IService 中封装的常用方法。
    springboot中使用mybatis-plus入门级教程_第6张图片
    springboot中使用mybatis-plus入门级教程_第7张图片
    方法介绍:
【添加数据:(增)】
    default boolean save(T entity); // 调用 BaseMapper 的 insert 方法,用于添加一条数据。
    boolean saveBatch(Collection entityList, int batchSize); // 批量插入数据
注:
    entityList 表示实体对象集合 
    batchSize 表示一次批量插入的数据量,默认为 1000

【添加或修改数据:(增或改)】
    boolean saveOrUpdate(T entity); // id 若存在,则修改, id 不存在则新增数据
   default boolean saveOrUpdate(T entity, Wrapper updateWrapper); // 先根据条件尝试更新,然后再执行 saveOrUpdate 操作
   boolean saveOrUpdateBatch(Collection entityList, int batchSize); // 批量插入并修改数据 

【删除数据:(删)】
    default boolean removeById(Serializable id); // 调用 BaseMapper 的 deleteById 方法,根据 id 删除数据。
    default boolean removeByMap(Map columnMap); // 调用 BaseMapper 的 deleteByMap 方法,根据 map 定义字段的条件删除
    default boolean remove(Wrapper queryWrapper); // 调用 BaseMapper 的 delete 方法,根据实体类定义的 条件删除对象。
    default boolean removeByIds(Collection idList); // 用 BaseMapper 的 deleteBatchIds 方法, 进行批量删除。
    
【修改数据:(改)】
    default boolean updateById(T entity); // 调用 BaseMapper 的 updateById 方法,根据 ID 选择修改。
    default boolean update(T entity, Wrapper updateWrapper); // 调用 BaseMapper 的 update 方法,根据 updateWrapper 条件修改实体对象。
    boolean updateBatchById(Collection entityList, int batchSize); // 批量更新数据

【查找数据:(查)】
    default T getById(Serializable id); // 调用 BaseMapper 的 selectById 方法,根据 主键 ID 返回数据。
    default List listByIds(Collection idList); // 调用 BaseMapper 的 selectBatchIds 方法,批量查询数据。
    default List listByMap(Map columnMap); // 调用 BaseMapper 的 selectByMap 方法,根据表字段条件查询
    default T getOne(Wrapper queryWrapper); // 返回一条记录(实体类保存)。
    Map getMap(Wrapper queryWrapper); // 返回一条记录(map 保存)。
    default int count(Wrapper queryWrapper); // 根据条件返回 记录数。
    default List list(); // 返回所有数据。
    default List list(Wrapper queryWrapper); // 调用 BaseMapper 的 selectList 方法,查询所有记录(返回 entity 集合)。
    default List> listMaps(Wrapper queryWrapper); // 调用 BaseMapper 的 selectMaps 方法,查询所有记录(返回 map 集合)。
    default List listObjs(); // 返回全部记录,但只返回第一个字段的值。
    default > E page(E page, Wrapper queryWrapper); // 调用 BaseMapper 的 selectPage 方法,分页查询
    default >> E pageMaps(E page, Wrapper queryWrapper); // 调用 BaseMapper 的 selectMapsPage 方法,分页查询
注:
    get 用于返回一条记录。
    list 用于返回多条记录。
    count 用于返回记录总数。
    page 用于分页查询。
    
【链式调用:】
    default QueryChainWrapper query(); // 普通链式查询
    default LambdaQueryChainWrapper lambdaQuery(); // 支持 Lambda 表达式的修改
    default UpdateChainWrapper update(); // 普通链式修改
    default LambdaUpdateChainWrapper lambdaUpdate(); // 支持 Lambda 表达式的修改
注:
    query 表示查询
    update 表示修改
    Lambda 表示内部支持 Lambda 写法。
形如:
    query().eq("column", value).one();
    lambdaQuery().eq(Entity::getId, value).list();
    update().eq("column", value).remove();
    lambdaUpdate().eq(Entity::getId, value).update(entity);
 
  
  1. 条件构造器(Wrapper )用来定义where条件
    上面介绍的接口方法中,会出现各种wrapper,wrapper的作用就是用来定义各种各样的查询条件(where条件)常用条件有:
【通用条件:】
【比较大小: ( =, <>, >, >=, <, <= )】
    eq(R column, Object val); // 等价于 =,例: eq("name", "老王") ---> name = '老王'
    ne(R column, Object val); // 等价于 <>,例: ne("name", "老王") ---> name <> '老王'
    gt(R column, Object val); // 等价于 >,例: gt("name", "老王") ---> name > '老王'
    ge(R column, Object val); // 等价于 >=,例: ge("name", "老王") ---> name >= '老王'
    lt(R column, Object val); // 等价于 <,例: lt("name", "老王") ---> name < '老王'
    le(R column, Object val); // 等价于 <=,例: le("name", "老王") ---> name <= '老王'
    
【范围:(between、not between、in、not in)】
   between(R column, Object val1, Object val2); // 等价于 between a and b, 例: between("age", 18, 30) ---> age between 18 and 30
   notBetween(R column, Object val1, Object val2); // 等价于 not between a and b, 例: notBetween("age", 18, 30) ---> age not between 18 and 30
   in(R column, Object... values); // 等价于 字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3)
   notIn(R column, Object... values); // 等价于 字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3)
   inSql(R column, Object... values); // 等价于 字段 IN (sql 语句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3)
   notInSql(R column, Object... values); // 等价于 字段 NOT IN (sql 语句)
   
【模糊匹配:(like)】
    like(R column, Object val); // 等价于 LIKE '%值%',例: like("name", "王") ---> name like '%王%'
    notLike(R column, Object val); // 等价于 NOT LIKE '%值%',例: notLike("name", "王") ---> name not like '%王%'
    likeLeft(R column, Object val); // 等价于 LIKE '%值',例: likeLeft("name", "王") ---> name like '%王'
    likeRight(R column, Object val); // 等价于 LIKE '值%',例: likeRight("name", "王") ---> name like '王%'
    
【空值比较:(isNull、isNotNull)】
    isNull(R column); // 等价于 IS NULL,例: isNull("name") ---> name is null
    isNotNull(R column); // 等价于 IS NOT NULL,例: isNotNull("name") ---> name is not null

【分组、排序:(group、having、order)】
    groupBy(R... columns); // 等价于 GROUP BY 字段, ..., 例: groupBy("id", "name") ---> group by id,name
    orderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC, 例: orderByAsc("id", "name") ---> order by id ASC,name ASC
    orderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC, 例: orderByDesc("id", "name") ---> order by id DESC,name DESC
    having(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 ), 例: having("sum(age) > {0}", 11) ---> having sum(age) > 11

【拼接、嵌套 sql:(or、and、nested、apply)】
   or(); // 等价于 a or b, 例:eq("id",1).or().eq("name","老王") ---> id = 1 or name = '老王'
   or(Consumer consumer); // 等价于 or(a or/and b),or 嵌套。例: or(i -> i.eq("name", "李白").ne("status", "活着")) ---> or (name = '李白' and status <> '活着')
   and(Consumer consumer); // 等价于 and(a or/and b),and 嵌套。例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
   nested(Consumer consumer); // 等价于 (a or/and b),普通嵌套。例: nested(i -> i.eq("name", "李白").ne("status", "活着")) ---> (name = '李白' and status <> '活着')
   apply(String applySql, Object... params); // 拼接sql(若不使用 params 参数,可能存在 sql 注入),例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08") ---> date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
   last(String lastSql); // 无视优化规则直接拼接到 sql 的最后,可能存若在 sql 注入。
   exists(String existsSql); // 拼接 exists 语句。例: exists("select id from table where age = 1") ---> exists (select id from table where age = 1)
   
【QueryWrapper 条件:】
    select(String... sqlSelect); // 用于定义需要返回的字段。例: select("id", "name", "age") ---> select id, name, age
    select(Predicate predicate); // Lambda 表达式,过滤需要的字段。
    lambda(); // 返回一个 LambdaQueryWrapper
    
【UpdateWrapper 条件:】
    set(String column, Object val); // 用于设置 set 字段值。例: set("name", null) ---> set name = null
    etSql(String sql); // 用于设置 set 字段值。例: setSql("name = '老李头'") ---> set name = '老李头'
    lambda(); // 返回一个 LambdaUpdateWrapper

你可能感兴趣的:(java,spring,boot,java,mybatis)