先上依赖

项目是springboot的,用的maven管理依赖

<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>

配置实体类和mapper

搞个实体类,默认实体类名和表名是对应的(忽略大小写),如果表名和类名不对应,那么就要使用
@TableName("work")public class Work implements Serializable { 注解来声明一下对应的表名


如果列名有特殊的,无法自动下划线转驼峰的,那么可以使用
@TableField("company")private String company;


对于id字段如果要设置成数据库自增那么需要声明一下
@TableId(value = "id", type = IdType.AUTO)private Long id;


有些字段在数据库中不存在,但是业务上又需要定义的时候
@TableField(exist = false)private String thisFieldisNotExistInDb;


MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_sql


IdType的几种类型

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_MySQL 下滑线转驼峰_02

然后写mapper接口

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_数据库_03

接着启动类上面加mapperscan扫描注解

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_MySQL 下滑线转驼峰_04

开启mp的sql日志

mp默认是集成了logback日志的,所以只需要在yml里开启就行了

logging:
  level:
    root: info
    com.fchan.hashmapstudy.dao: debug

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_数据库_05

配置是否开启驼峰和下划线互转

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true #开启驼峰和下划线互转

mp的通用service

先创建一个接口,继承mpIService 然后创建这个接口的实现类,这样就可以使用一些现成的方法了

方法可以参见官方文档里核心功能菜单下CRUD接口

https://mp.baomidou.com/guide/crud-interface.html#save

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_sql_06

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_数据库_07

mp使用PaginationInterceptor进行物理分页查询

我这边是springboot项目,所以用注解引入PaginationInterceptor拦截器

传统分页组件往往是
count:

select count(1) from (select * from user order by age desc, update_time desc)

查记录:

select * from user order by age desc, update_time desc limit 0,50

count时的order by是完全可以去掉的!在复杂查询、大表、非索引字段排序等情况下查记录已经很慢了,查count又要来一次!所以查count显然希望优化为
select count(1) from (select * from user) 但是也不是所有场景都可以优化的,比如带group by的查询,所以MBP源码如下实现,没有group by且有order by的语句,就把order by去掉。

package com.fchan.hashmapstudy.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;

@Configuration
public class MybatisPageConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

}

mapper接口里定义一个分页查询方法,有多个参数的时候要给后面的condition参数通过@Params定义一个变量名,不然mybatis识别不出来

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_数据库_08


service里也创建一个方法

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring boot_09


xml里定义sql语句分页查询数据

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring boot_10

传入page参数即可

//默认会查两次第一次查询count总数,第二次limit分页
//Page<Category> categoryIPage = new Page<>(1,3);
//isSearchCount传入false的话就不会count总数,只会查一次
Page<Category> categoryIPage = new Page<>(1,3, false);
Page<Category> categoryPage = categoryMapper.selectPage(categoryIPage, categoryLambdaQueryWrapper);

return objectMapper.writeValueAsString(categoryPage);

使用pagehelper进行分页查询

先上依赖
我因为用了mybatisplus所以依赖冲突了,在引入的pagehelper依赖冲排除mybatis的依赖,用mybatis的直接引入即可

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.12</version>
    <exclusions>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </exclusion>
    </exclusions>
</dependency>

yml中配置参数,pagehelper不需要注册一个拦截器到spring

pagehelper:
  helper-dialect: mysql #配置使用哪种数据库语言,不配置的话pageHelper也会自动检测
  reasonable: true      #配置分页参数合理化功能,默认是false
  support-methods-arguments: true #支持通过Mapper接口参数来传递分页参数,默认值false

helper-dialect:

配置使用哪种数据库语言,不配置的话pageHelper也会自动检测

reasonable:

配置分页参数合理化功能,默认是false
启用合理化时,如果pageNum<1会查询第一页,如果pageNum>总页数会查询最后一页
禁用合理化时,如果pageNum<1或pageNum>总页数会返回空数据

params:

为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值; 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable 不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero

support-methods-arguments:

支持通过Mapper接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。

使用demo

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring boot_11


紧跟PageHelper.startPage后的第一个mapper的查询方法会生效

//PageHelper.startPage(1,2);
//第三个count参数传入false的话就不会count总数,只会查一次,和mp自带的page一样
PageHelper.startPage(1,2, false);
PageInfo<Category> categoryPageInfo = new PageInfo<>(categoryMapper.selectAll());

mapper直接使用lambdaWrapper构造器查询

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring boot_12

3种构造方式,我选的第三种,代码少

LambdaQueryWrapper<Category> lambda = new QueryWrapper<Category>().lambda();
//直接new LambdaQueryWrapper有深坑建议Wrappers.<Category>lambdaQuery()
LambdaQueryWrapper<Category> categoryLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = Wrappers.<Category>lambdaQuery();

//like '%22%'
categoryLambdaQueryWrapper.like(Category::getCode,"33");
List<Category> categories1 = categoryMapper.selectList(categoryLambdaQueryWrapper);

复杂查询

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring boot_13

// code like '33%' and ( name = 'after' and gmt_create is not null)
categoryLambdaQueryWrapper.likeRight(Category::getCode, "33")
						.and(clqe -> clqe.eq(Category::getName,"after").isNotNull(Category::getGmtCreate));
List<Category> categories1 = categoryMapper.selectList(categoryLambdaQueryWrapper);

使用lambdaWrapper更新

LambdaUpdateWrapper<Category> categoryLambdaUpdateWrapper = Wrappers.<Category>lambdaUpdate();
 categoryLambdaUpdateWrapper.eq(Category::getCode, "333").and(q -> q.eq(Category::getName,"after")).set(Category::getName, "pambda");


 int update = categoryMapper.update(null, categoryLambdaUpdateWrapper);
 return String.valueOf(update);
User user = new User();
user.setId(5L);
user.setName("成老实");
user.setAge(23);
User whereUser = new User();
whereUser.setName("老成实");
whereUser.setAge(30);
whereUser.setId(5L);
/**
 * 传入的实体中不为null的变量会出现在where中
 * UPDATE user SET name=?, age=? WHERE id=? AND name=? AND age=? AND (name = ? AND age = ?) 
 */
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>(whereUser);
updateWrapper.eq("name","老实成").eq("age",30);
int rows = userMapper.update(user,updateWrapper);
System.out.println("影响记录数:"+rows);
boolean update = new LambdaUpdateChainWrapper<User>(userMapper).eq(User::getName, "老实成")
            .eq(User::getAge, 24).set(User::getAge, 20).update();
System.out.println("更新是否成功:"+update);

MySQL 下滑线转驼峰 mybatis plus下划线转驼峰_spring_14