mybatis-plus整合spring boot极速入门

使用mybatis-plus整合spring boot,接下来我来操作一番。

一,创建spring boot工程

勾选下面的选项

紧接着,还有springboot和依赖我们需要选。

这样我们就创建好了我们的spring boot,项目。

简化目录结构:

我们发现,这些零碎文件很多,占时用不到的,就先删除。

看看简化后的,项目目录结构。

修改boot项目版本:

启动项目:

找到启动来,把我们的项目跑起来。

可以看到项目是正常启动的

二,添加依赖

添加mybatis-plus依赖:

<!--mybatis-plus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.5</version>
        </dependency>
添加mysql依赖:

        <!-- mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
yml文件的配置:

把一properties结尾的文件,改成yml结尾的格式

 改后的效果:

我添加了下面的配置:

#项目的端口
server:
  port: 8080

#mysql配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp_db?serverTimezone=UTC
    username: root
    password: root


#mabatis-plus的配置
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql日志
    map-underscore-to-camel-case: true  # 是否开启驼峰命名转换
运行项目:

项目还是正常启动的

三,创建各种业务层

我们把mapper,service,controller,utils都创建好,看看目录结构。

Emp实体类

代码:

@Data
public class Emp {
    private Long id; // 员工ID
    private String name; // 员工姓名
    private String password; // 密码
    private Integer age; // 年龄
    private String tel; // 电话号码

}

mapper接口:

代码:

@Mapper
public interface EmpMapper extends BaseMapper<Emp> {
}

EmpService接口:

代码:

public interface EmpSerevice extends IService<Emp> {
}
 EmpServiceImpl:实现类

代码:

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpSerevice{

}
 EmpController类:

代码:

@RestController
@RequestMapping("/emps")
public class EmpController {

}
新建一个测试类:

代码:

@Slf4j
@SpringBootTest
public class TestMp {

}

四,测试mybatis-plus的service层接口:

测试查询:
mp的service提供的查询方法:

getById   通常用于表示根据ID获取数据的方法 。

getOne  通常用于查询符合条件的单条记录。

getMap  根据wrapper条件,可以查询多条数据。

查询常用的拼接关系条件:

通常是写 wrapper里面的:

就比如 >, >=, < ,<= ,=   

  • gt:大于
  • ge:大于等于
  • lt:小于
  • le:小于等于
  • eq:等于

还有一些模糊查询用到的:

like 模糊查询类似于 like '%XXX%'

likeLeft 左边模糊查询 like '%XXX'

likeRight 右边模糊查询 类似于 like 'XXX%'

notLike   返回的模糊查询条件中,都不包含某条件。 no like '%XXX%'

notLikeLeft  返回的模糊查询条件中,左边不包含某条件。not like '%XXX'

notLikeRight 返回的模糊查询条件中,右边不包含某条件。not like 'XXX%'

查询条件的排序:

orderBy 根据什么字段排序,自己决定升序还是降序 

orderByAsc    根据条件成立的字段,升序

orderByDesc   根据条件成立的字段,降序

单个无条件查询:

代码:

    @Test
    @DisplayName("简单的测试")
    void testSimple() {

        //调用empservice的根据id查询的方法
        Emp emp = empSerevice.getById(1);
        //输出结果
        System.out.println(emp);
    }

查看结果: 

单个拼接条件查询:

代码:

    @Test
    @DisplayName("单个测试")
    void testGetOne(){
        //1,构造查询条件
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("id",1);

        //2,调用接口查询
        Emp emp = empSerevice.getOne(wrapper);

        //打印数据
        System.out.println(emp);
    }

 查看结果:

多条件拼接查询:
 

代码:

    @Test
    @DisplayName("多条件拼接查询")
    void testMoreQuery(){
        //1,创建查询条件
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.ge("age",8);
        wrapper.like("name","张");

        //2,调用方法查询
        Map map = empSerevice.getMap(wrapper);

        //3,打印结果
        System.out.println(map);
    }

查询不包含某个条件返回多条数据:

 

代码:

    @Test
    @DisplayName("测试不包含条件的模糊查询")
    void testWrapper(){
        //1,创建查询条件
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.notLike("name","张");  //结果中不能包含 张

        //2,调用service接口
        Map map = empSerevice.getMap(wrapper);

        //3,打印结果
        System.out.println(map);

    }

结果:

测试in包含的条件:

代码:

    @Test
    @DisplayName("测试in包含带的条件")
    void testExiste(){
        //1,创建查询条件
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.in("id",1,2,3);

        //2,调用接口查询
        Map map = empSerevice.getMap(wrapper);

        //3,打印结果
        System.out.println(map);
    }

结果:

 

排序查询:

代码:

    @Test
    @DisplayName("测试")
    void test(){
        //1,创建查询条件
        QueryWrapper wrapper = new QueryWrapper();
        //第一个参数,条件是否成立,第二个参数,是否升序,第三个参数,排序字段
        wrapper.orderBy(true,false,"age");

        //2,调用接口查询
        Map map = empSerevice.getMap(wrapper);

        //3,打印结果
        System.out.println(map);
    }

结果:

 测试lamdba方式的查询:

为什么要使用lamdba的这中方式呢,因为这样就可以避免我们写死,要插叙条件的字段了。要是后面修改,实体类的属性,就能避免很多麻烦。

单个查询:

代码:

    @Test
    @DisplayName("单个查询")
    void getById(){
        //1,调用接口查询
        Emp emp = empSerevice.getById(3L);

        //2,打印结果
        System.out.println(emp);
    }

结果:

简单条件查询:

代码:

    @Test
    @DisplayName("lamdba的简单查询")
    void testLamdba(){
        //1,创建查询条件
        LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();
        lambdaQuery.eq(Emp::getId,1);

        //2,调用接口
        Emp emp = empSerevice.getOne(lambdaQuery);

        //3,打印结果
        System.out.println(emp);
    }

结果:

复杂条件查询(一): 

 

代码:

    @Test
    @DisplayName("复杂条件查询")
    void testMoreQuery(){
        //1,创建查询条件
        LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();

        //查询姓名包含张,年龄大于等于8,小于等于30
        lambdaQuery.like(Emp::getName,"张");
        lambdaQuery.ge(Emp::getAge,8);
        lambdaQuery.le(Emp::getAge,30);

        //2,调用接口
        Map<String, Object> map = empSerevice.getMap(lambdaQuery);
        //3,打印结果
        System.out.println(map);
    }

结果:

 

复杂查询(二)

代码:

    @Test
    @DisplayName("复杂条件查询")
    void testMoreQuery2(){
        //1,创建查询条件
        LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();

        //查询密码包含6并且,名字中包含j,年龄大于8岁,小于20岁
        lambdaQuery.like(Emp::getPassword,"6");
        lambdaQuery.like(Emp::getName,"j");
        lambdaQuery.ge(Emp::getAge,8);
        lambdaQuery.le(Emp::getAge,20);
        //2,,调用接口
        Map<String, Object> map = empSerevice.getMap(lambdaQuery);
        //3,打印结果
        System.out.println(map);
    }

结果:

 

测试删除:

mybatis-plus也给我们提供了很多的,删除的方法。

remove 根据条件删除

removeBatchByIds  批量删除 

removeById 根据id单个删除

测试单个删除:

代码:

    @Test
    @DisplayName("测试单个删除")
    void TestById(){
        //1,调用接口
        boolean b = empSerevice.removeById(1L);

        //打印结果
       if (b){
           System.out.println("删除成功");
       }
    }

结果:

根据条件删除:

代码:

    @Test
    @DisplayName("根据条件删除")
    void testByWrapper(){
        //1,创建条件
       LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();
       //删除名字为单的员工
        lambdaWrapper.like(Emp::getName,"单");

        //2,调用接口
        boolean b = empSerevice.remove(lambdaWrapper);

        //3,打印结果
        if (b){
            System.out.println("删除成功");
        }
    }

结果:

 

 根据复杂条件批量删除:

代码:

    @Test
    @DisplayName("根据复杂条件批量删除")
    void TestByWrapperBatch(){
        //1,创建条件
        LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();
        //删除年龄22岁,密码包含6,且名字中是姓张的
        lambdaWrapper.eq(Emp::getAge,22)
                .like(Emp::getPassword,"6")
                .like(Emp::getName,"张");
        //2,调用接口
        boolean b = empSerevice.remove(lambdaWrapper);
        //3,打印结果
        if (b){
            System.out.println("删除成功");
        }
    }

结果:

根据ID批量删除:

代码:

    @Test
    @DisplayName("根据id批量删除")
    void testBatchById(){
        //1,调用接口
        boolean b = empSerevice.removeBatchByIds(List.of(2L, 3L, 4L));

        //打印结果
        if (b){
            System.out.println("删除成功");
        }
    }

结果:

 测试新增(添加):

mubatis-plus也为我们提供了很多现成的,新增方法。

save  就是一个简单的新增方法

saveBatch   批量新增         

saveOrUpdate   存在就修改,不存在就新增

简单的新增:

代码:

    @Test
    @DisplayName("测试新增")
    void testAdd(){
        //1,创建实体类
        Emp emp = new Emp(null, "sde", "123456789", 18, "66666666666");

        //2,调用接口
        boolean b = empSerevice.save(emp);

        //3,返回结果
        if (b){
            System.out.println("新增成功");
        }
    }

 结果:

批量新增:
 

代码:

    @Test
    @DisplayName("批量添加")
    void testAddBatch(){
        //1,创建新增的实体集合
        List<Emp> empList = new ArrayList<Emp>();
        //2,创建多个实体对象
        Emp emp1 = new Emp(null, "sde1", "123456789", 18, "66666666666");
        Emp emp2 = new Emp(null, "sde2", "123456789", 18, "66666666666");
        Emp emp3 = new Emp(null, "sde3", "123456789", 18, "66666666666");
        Emp emp4 = new Emp(null, "sde4", "123456789", 18, "66666666666");
      //3,添加到集合中
        empList.add(emp1);
        empList.add(emp2);
        empList.add(emp3);
        empList.add(emp4);
      //4,调用接口
        boolean b = empSerevice.saveBatch(empList);
      //5,返回结果
        if (b){
            System.out.println("批量新增成功");
        }
    }

结果:

 新增或者修改:

代码:

    @Test
    @DisplayName("新增或者修改")
    void saveOrUpdate(){
        //1,创建实体
        Emp emp = new Emp(5L, "snake存在就修改", "123456789", 18, "66666666666");

        //2,调用接口
        boolean b = empSerevice.saveOrUpdate(emp);

        //3,返回结果
        if (b){
            System.out.println("新增或者修改成功");
        }
    }

结果:

我们看看数据库是修改还是新增了

很明显是新增了

测试修改:
 

mybatis-plus也给我们提供了很多修改的方法:

 updateById  根据id修改

update    根据条件修改,第一个参数是实体类,第二个参数是wrapper

根据ID修改:

代码:

    @Test
    @DisplayName("简单的修改")
    void testUpdate(){
        //1,创建要修改的实体类
        Emp emp = new Emp(7L, "张三", "123456", 20, "12345678901");

        //2,调用接口
        boolean b = empSerevice.updateById(emp);

        //3,打印结果
        if (b){
            System.out.println("修改成功");
        }
    }

结果:

 根据条件修改:

 代码:

    @Test
    @DisplayName("根据条件修改")
    void testByWrapper(){
        //1,创建修改的条件
        LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();

        //修改名字为张三,iqe密码是123456的
        lambdaWrapper.eq(Emp::getPassword, "123456")
                .eq(Emp::getName, "张三");

        //2,创建实体类
        Emp emp = new Emp(888L, "a张三", "123456", 20, "12345678901");

        //3,调用接口
        boolean b = empSerevice.update(emp, lambdaWrapper);

        //4,打印结果
        if (b){
            System.out.println("修改成功");
        }
    }

结果:

 注意不会修改·id

 修改或者新增:

代码:

    @Test
    @DisplayName("新增或者修改")
    void updateOrAdd(){
        //1,创建实体类
        Emp emp = new Emp(9L, "a张三", "54545454", 20, "12345678901");
        //2,调用接口
        boolean b = empSerevice.saveOrUpdate(emp);
        //3,打印结果
        if (b){
            System.out.println("修改成功");
        }

    }

结果:

五,测试mybatis-plus的mapper层接口:

测试查询:
单个查询:

代码:

    @Test
    @DisplayName("单个查询")
    void testSelect() {
        //1,创建查询条件
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Emp::getId, 7);

        //2,调用接口
        Emp emp = empMapper.selectOne(queryWrapper);

        //3,打印结果
        System.out.println(emp);
    }

结果:

 

批量查询:

代码:

    @Test
    @DisplayName("批量查询")
    void testSelectList(){
        //1,创建查询条件
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Emp::getId, 6,7,8,9);

        //2,调用接口
        List<Emp> empList = empMapper.selectList(queryWrapper);

        //3,打印结果
        System.out.println(empList);
    }

 结果:

查询数据个数:
    @Test
    @DisplayName("简单查询")
    void testSimple() {

        //1,创建查询条件
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Emp::getName, "张");

        //2,调用接口
        Long count = empMapper.selectCount(queryWrapper);

        //3,打印结果
        System.out.println(count);
    }

结果:

 

 测试删除:
单个删除:

代码:

    @Test
    @DisplayName("单个删除")
    void testById(){
        //1,调用接口
        int count = empMapper.deleteById(7L);

        //2,打印结果
        System.out.println(count);
    }

结果:

 

批量删除:
 

代码:

    @Test
    @DisplayName("批量删除")
    void testDelByIds(){
        //1,创建一个集合
        List<Integer> ids = List.of(6,7,8,9,10);

        //2,调用接口
        int count = empMapper.deleteBatchIds(ids);

        //3,打印结果
        System.out.println(count);
    }

结果:

 

 测试新增:
单个添加:

代码:

    @Test
    @DisplayName("测试新增")
    void testInsert(){
        //1,创建实体类
        Emp emp = new Emp(null, "六十的", "123456", 22, "1232321");

        //调用接口
        int count = empMapper.insert(emp);

        //输出结果
        System.out.println(count);
    }

结果:

 

测试修改:
 

代码:

    @Test
    @DisplayName("测试修改")
    void update(){

        //1,创建条件
       LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<Emp>();
       //名字中包含张的都修改
       queryWrapper.like(Emp::getName, "张");
       //2,创建实体类
        Emp emp = new Emp(null, "张三", "43434343434", 34, "1222222");

        //3,调用结果
        int count = empMapper.update(emp,queryWrapper);

        //4,输出返回值
        System.out.println(count);
    }

结果:

 根据id修改:

    @Test
    @DisplayName("修改")
    void testUpdate(){
        //1,创建实体类
        Emp emp = new Emp(5L, "大苏打", "1234567890", 18, "1234567890");

        //2,调用接口
        int count = empMapper.updateById(emp);

        //3,打印结果
        System.out.println(count);
    }

结果:

 

 六,常见注解:

@TableName注解:
  • 描述:表名注解,标识实体类对于的表

  • 使用位置:实体类类名上面

 示例:

@TableName("user")
public class User {
    private Long id;
    private String name;
}
 @TableId注解:
  • 描述:主键注解;用于标记实体类中的主键字段

  • 使用位置:实体类中属性之上

示例:

@TableName("user")
public class User {
    @TableId
    private Long id;
    private String name;
}
 TableId注解有两个属性:
属性类型必须指定默认值描述
valueString""表名
typeEnumIdType.NONE指定主键类型
 IdType支持的类型:
描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert 前自行 set 主键值
ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
 比较常用的也就是下面这三个:
  • AUTO:利用数据库的id自增长

  • INPUT:手动生成id

  • ASSIGN_ID:雪花算法生成Long类型的全局唯一id,这是默认的ID策略

 测试IdType的AUTO:

emp实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    @TableId(value = "id", type = IdType.AUTO)  //利用数据库的id自增长
    private Long id; // 员工ID
    private String name; // 员工姓名
    private String password; // 密码
    private Integer age; // 年龄
    private String tel; // 电话号码

}

看看数据库的数据:

 测试效果:

代码:

    @Test
    @DisplayName("TableId类型的测试")
    void testAddEmp(){
        //1,创建实体类
        Emp emp = new Emp(null, "测试TableId", "123456", 22, "1232321");
        //2,调用mapper接口
        int count = empMapper.insert(emp);
        //3,打印结果
        System.out.println(count);
    }

 数据库的变化:

id从7,到8了。

 测试IdType的INPUT:
 

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    @TableId(value = "id", type = IdType.INPUT)  //自己设置主键id
    private Long id; // 员工ID
    private String name; // 员工姓名
    private String password; // 密码
    private Integer age; // 年龄
    private String tel; // 电话号码

}

 测试:

代码:

    @Test
    @DisplayName("TableId类型的测试")
    void testAddEmp(){
        //1,创建实体类
        Emp emp = new Emp(10L, "测试TableId", "123456", 22, "1232321");
        //2,调用mapper接口
        int count = empMapper.insert(emp);
        //3,打印结果
        System.out.println(count);
    }

 看看数据库:

主键ID已经变成了我们自己输入的10

 测试IdType的ASSIGN_ID:

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    @TableId(value = "id", type = IdType.ASSIGN_ID)  //基于雪花算法生成id
    private Long id; // 员工ID
    private String name; // 员工姓名
    private String password; // 密码
    private Integer age; // 年龄
    private String tel; // 电话号码

}

 测试:

代码:

    @Test
    @DisplayName("TableId类型的测试")
    void testAddEmp(){
        //1,创建实体类
        Emp emp = new Emp(null, "测试TableId", "123456", 22, "1232321");
        //2,调用mapper接口
        int count = empMapper.insert(emp);
        //3,打印结果
        System.out.println(count);
    }

效果:

 七,常见配置:

mybatis-plus也支持基于yaml文件的自定义配置,详见官方文档:使用配置 | MyBatis-Plus 

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

  • 实体类的别名扫描包

  • 全局id类型

mybatis-plus:
  type-aliases-package: com.sde.mp.domain.po
  global-config:
    db-config:
      id-type: auto # 全局id类型为自增长

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置:

mybatis-plus:
  mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。

八,分页插件:

在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IServiceBaseMapper中的分页方法都无法正常起效。 所以,我们必须配置分页插件。

配置分页插件:

在我们的包下,新建一个config包,然后编写一个MybatisConfig的配置类

代码:

public class MybatisConfig {
}
 配置Mybatis-plus的分页拦截器:

代码:

//在类上添加这个注解
@Configuration
public class MybatisConfig {

    //配置Mybatisplus的分页拦截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}
 测试分页:
简单测试:

在查询之间我们先看一下,我数据库的数据情况。

编写测试代码:

代码:

    @Test
    @DisplayName("测试简单的分页")
    void testPage(){
        //定义当前页码:
        int pageNum = 1;
        //定义每页显示的记录数:
        int pageSize = 2;
        //设置分页参数
        Page<Emp> page = new Page<>(pageNum, pageSize);
        //进行查询
        Page<Emp> empPage = empSerevice.page(page);

        //获取总记录数
        System.out.println("总记录数:" + empPage.getTotal());
        //获取页数
        System.out.println("总页数:" + empPage.getPages());
        //打印结果
        empPage.getRecords().forEach(System.out::println);
    }

结果:

 

简化写法:

代码:

    @Test
    @DisplayName("简化写法")
    void testPage2(){
        //分页查询
        Page<Emp> empPage = empSerevice.page(new Page<Emp>(2, 2));
        //获取总记录数
        System.out.println("总记录数:" + empPage.getTotal());
        //遍历出数据
        empPage.getRecords().forEach(System.out::println);
    }

结果:

自定义条件分页查询:
编写查询参数实体类:

empQueryDto类

代码:

@Data
public class EmpQueryDto {
    private String name; // 员工姓名
    private Integer age; // 年龄
    private String tel; // 电话号码
    private Integer pageNum;// 当前页码
    private Integer pageSize;// 每页显示条数
}
编写EmpController

条件分页查询的getEmpPage方法:

现在EmpService还没有写,empPage这个方法。报错先不用管

代码:

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpSerevice empService;

    @GetMapping("/page")
    public Result getEmpPage(EmpQueryDto query){
        log.info("接收到的参数;"+query);
        Page<Emp> empPage = empService.empPage(query);
        return Result.success(empPage);
    
    }
    
}
编写EmpService接口

 代码:

public interface EmpSerevice extends IService<Emp> {

    /**
     * 条件分页查询用户信息
     * @param query
     * @return
     */
    Page<Emp> empPage(EmpQueryDto query);
}
EmpServiceImpl实现类:
 

代码:

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpSerevice{

    @Autowired
    private EmpMapper empMapper;
    
    /**
     * 条件分页查询用户信息
     * @param query
     * @return
     */
    @Override
    public Page<Emp> empPage(EmpQueryDto query) {
        
        return null;
    }
}
 实现ServiceImpl层的方法:

代码:

    @Override
    public Page<Emp> empPage(EmpQueryDto query) {
        //1,设置分页参数
        Page<Emp> page = new Page<>(query.getPageNum(), query.getPageSize());

        //2,设置分页查询条件
        LambdaQueryWrapper<Emp> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(query.getName() != null, Emp::getName, query.getName())
                .eq(query.getAge() != null, Emp::getAge, query.getAge())
                .eq(query.getTel() != null, Emp::getTel, query.getTel());

        //3,查询
        List<Emp> empList = empMapper.selectList(page, wrapper);

        //4,设置返回参数
        page.setRecords(empList);
        page.setTotal(empList.size());

        return page;
    }
 测试结果:

在ApiFox里面设置查询的参数

看看怎么执行的:

在ApiFox里面看看返回的数据:

{
    "code": 1,
    "msg": null,
    "data": {
        "records": [
            {
                "id": 8,
                "name": "测试TableId",
                "password": "123456",
                "age": 22,
                "tel": "1232321"
            },
            {
                "id": 10,
                "name": "测试TableId",
                "password": "123456",
                "age": 22,
                "tel": "1232321"
            },
            {
                "id": 1766100080533725186,
                "name": "测试TableId",
                "password": "123456",
                "age": 22,
                "tel": "1232321"
            }
        ],
        "total": 3,
        "size": 10,
        "current": 1,
        "pages": 1
    }
}

 九,代码生成器:

在使用MybatisPlus以后,基础的MapperServicePO代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成POMapperService等相关代码。

安装插件:

方式一:在Idea的plugins市场中搜索并安装MyBatisPlus插件(插件不太稳定,建议按照官网方式):

 点击Settings,找到plugins,搜索mybatisplus这个插件

然后重启Idea就可以了

方式二:上述的图形界面插件,存在不稳定因素;所以建议使用代码方式生成。官网安装说明。在项目中 pom.xml 添加依赖如下:

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.32</version>
            <scope>test</scope>
        </dependency>

使用:

使用图形界面方式的直接打开设置数据信息和填写其它界面中需要的内容即可。

在新版IDEA中;入口在 others这个里面: 

使用图形工具生成: 
 
设置连接数据库的配置信息:
 

点击测试连接:

可以看到 test successful连接成功了

 

使用介绍:

成功标志:

 目录结构

使用代码生成:

1,添加依赖:

2,写一个测试类,名字为MybatisPlusGenTest的类

代码:

public class MybatisPlusGenTest {

}

 3,添加生成的配置信息:

代码:

 public static void main(String[] args) {
        String url = "jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
        FastAutoGenerator.create(url , "root", "root")
                .globalConfig(builder -> {
                    builder.author("sde") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .outputDir("D:\\cloud-java\\allcode2\\gen"); // 指定输出目录
                })
                .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                    int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                    if (typeCode == Types.SMALLINT) {
                        // 自定义类型转换
                        return DbColumnType.INTEGER;
                    }
                    return typeRegistry.getColumnType(metaInfo);

                }))
                .packageConfig(builder -> {
                    builder.parent("com.sdep") // 设置父包名
                            .controller("controller")
                            .entity("domain.po") // 设置实体类包名
                            .service("service") // 设置service包名
                            .serviceImpl("service.impl") // 设置service实现类包名
                            .mapper("mapper") // 设置mapper包名
                            //.moduleName("address") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\cloud-java\\allcode2\\gen\\mapper")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("address") // 设置需要生成的表名
                            .addTablePrefix("t_", "c_") // 设置过滤表前缀
                            .controllerBuilder().enableRestStyle() // 开启restful风格控制器
                            .enableFileOverride() // 覆盖已生成文件
                            .entityBuilder().enableLombok(); // 开启lombok模型,默认是false
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }

 将生成的实体、Mapper、Service、Controller等对应的类放置到项目中。即可

4,点击运行:

5,查看生成的目录:

 

完整版的代码生成器,代码:

public class MybatisPlusGeneratorTest {

    public static void main(String[] args) {
        String url = "jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
        FastAutoGenerator.create(url , "root", "root")
                .globalConfig(builder -> {
                    builder.author("JBL") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .outputDir("D:\\itcast\\generatedCode"); // 指定输出目录
                })
                .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                    int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                    if (typeCode == Types.SMALLINT) {
                        // 自定义类型转换
                        return DbColumnType.INTEGER;
                    }
                    return typeRegistry.getColumnType(metaInfo);

                }))
                .packageConfig(builder -> {
                    builder.parent("com.itheima.mp") // 设置父包名
                            .controller("controller")
                            .entity("domain.po") // 设置实体类包名
                           .service("service") // 设置service包名
                           .serviceImpl("service.impl") // 设置service实现类包名
                           .mapper("mapper") // 设置mapper包名
                            //.moduleName("address") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\itcast\\generatedCode\\mapper")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("address") // 设置需要生成的表名
                            .addTablePrefix("t_", "c_") // 设置过滤表前缀
                            .controllerBuilder().enableRestStyle() // 开启restful风格控制器
                            .enableFileOverride() // 覆盖已生成文件
                            .entityBuilder().enableLombok(); // 开启lombok模型,默认是false
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }
}

 十,静态工具类:

使用Db实现如下需求:

1、根据id查询用户;

2、查询名字中包含o且年龄大于8岁的;

3、更新用户名为tom的年龄为18

测试根据ID查询:
 

代码:

@SpringBootTest
public class DbTest {

    @Test
    @DisplayName("根据id查询用户")
    public void testById(){
        Emp emp = Db.getById(1L, Emp.class);
        System.out.println(emp);
    }
}

结果:

 

测试查询名字中包含j且年龄大于8岁的
 

代码:

    @Test
    @DisplayName("测试查询名字中包含j且年龄大于8岁的")
    void testWrapper(){
        //查询参数设置
        List<Emp> empList = Db.lambdaQuery(Emp.class).like(Emp::getName, "j")
                .ge(Emp::getAge, 8)
                .list();
        //遍历
        empList.forEach(emp -> System.out.println(emp));

    }

结果:

 

 更新用户名为tom的年龄为18

代码:

    @Test
    @DisplayName("更新用户名为tom的年龄为18")
    void testUpdate(){
       Db.lambdaUpdate(Emp.class)
               .set(Emp::getAge, 18)
               .eq(Emp::getName, "tom")
                .update();
    }

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445203.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java中移位<< >> <<< |数据类型转换

移位 x64转换二进制&#xff1a;100 0000 左移2位 &#xff1a; 1000 0000 0 对应十进制 i 256 >>右移 <<左移 >>无符号位右移 关于右移一位相当于整除2 数据类型及其转换 基本数据类型&#xff0c;数据类型范围 byte(-128~127)&#xff08;-2^7~2…

unity学习(54)——选择角色界面--解析赋值服务器返回的信息1

1.decode这种照猫画虎的工作 把逆向出来UserHandler.cs中的内容&#xff0c;融到自建客户端的MessageManager.cs中&#xff1a; 2.此时登录账号&#xff0c;马上显示当前账号下已有三名角色&#xff1a; 此时返回数据包中的command的值是1&#xff1a; 3.当注册玩家数超过三名…

pytorch的理解

工具的查看与使用帮助 1. dir import torch torch.cuda.is_available()dir(torch) dir(torch.cuda) #可以看到有"is_available" 2. help help(torch.cuda.is_available)

python基础——条件判断和循环【if,while,for,range】

&#x1f4dd;前言&#xff1a; 这篇文章主要讲解一下条件判断语句if和循环语句while&#xff0c;for在python中需要注意的地方。 建议已有一定了解&#xff08;对语句的执行逻辑清楚&#xff09;的读者观看&#xff0c;如果对条件判断和循环的执行逻辑不太清楚&#xff0c;也可…

react实战——react旅游网

慕课网react实战 搭建项目问题1.按照官网在index.tsx中引入antd出错&#xff1f;2.typescript中如何使用react-router3.react-router3.1 V63.2 V53.3V6实现私有路由 4.函数式组件接收props参数时定义数据接口&#xff1f;5.使用TypeScript开发react项目&#xff1a;6.要使一个组…

【C++第四课-类和对象下】初始化列表、静态成员函数、静态成员变量、explicit关键字(隐式类型转换)、友元函数、友元类、内部类、编译器的常见优化

目录 再谈构造函数初始化列表初始化列表解决的问题&#xff1a;静态成员函数、成员变量explicit关键字 友元友元函数友元类 内部类编译器的常见优化&#xff08;了解&#xff09;优化1 再谈构造函数 初始化列表 有一些成员变量是无法在函数体内初始化的&#xff0c;eg&#x…

基于javaweb+springboot开发的城市地名地址信息管理系统设计和实现

基于javaweb(springboot)城市地名地址信息管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…

CPE-CLIP

input embeddings follow the form [ g 1 , g 2 , . . . , g L g_1,g_2,...,g_L g1​,g2​,...,gL​,w] 辅助信息 作者未提供代码

el-select下拉框无法显示 elementplus踩坑日常

在使用el-select的时候参考了官方文档&#xff0c;但下拉框无法显示 解决办法1&#xff1a;检查是否没有按需引入eloption只引入了elselect 解决办法2&#xff1a;在el-select里面加入:popper-append-to-body"false" <el-select:popper-append-to-body"fa…

基于亚马逊云EC2+Docker搭建nextcloud私有化云盘

亚马逊EC2云服务器&#xff08;Elastic Compute Cloud&#xff09;是亚马逊AWS&#xff08;Amazon Web Services&#xff09;提供的一种云计算服务。EC2代表弹性计算云&#xff0c;它允许用户租用虚拟计算资源&#xff0c;包括CPU、内存、存储和网络带宽&#xff0c;以满足计算…

Intellij IDEA 中 git 操作的快捷键

1.添加新建的文件 即add 操作 shift alt a 2.提交操作 即 commit操作 ctrl k 在窗口中可以用feature来声明此次更新的内容 3.提交操作 即push操作 ctrl shift k 4.拉去远程分支操作 即pull操作 ctrl t

C语言 --- 指针(5)

目录 一.sizeof和strlen对比 1.sizeof 2.strlen 3.strlen 和sizeof的对比 二.数组和指针笔试题目详解 回顾&#xff1a;数组名的理解 1.一维数组 2.字符数组 代码1&#xff1a; 代码2&#xff1a; 代码3&#xff1a; 代码4&#xff1a; 代码5&#xff1a; 代码6&am…

进程伪装详解

前言 当我们获取到一台主机的权限过后&#xff0c;拿到了自己想要搜集的信息&#xff0c;这时候我们就会留一个后门进行权限维持&#xff0c;权限维持的学问其实很深&#xff0c;今天就主要介绍其中一种比较简单的权限维持的方法 -- 进程伪装。 我们知道在windows里面有很多系…

Jetpack Navigation

1.Navigation的诞生与优势 这个留到Compose去学

探索机器学习的无限可能性:从初学者到专家的旅程

探索机器学习的无限可能性&#xff1a;从初学者到专家的旅程 在当今数字时代&#xff0c;机器学习无疑是最引人注目的技术之一。它已经深入到我们生活的方方面面&#xff0c;从个性化推荐到自动驾驶汽车&#xff0c;再到医疗诊断和金融预测。但是&#xff0c;即使我们已经见证…

时间复杂度之大O表示法

一、概念 O表示法&#xff1a; 设T( n)和 g( n)是正整数集到正实数集上的函数。 称T( n) O( g( n)) &#xff0c;当且仅当存在一个正常数 C 和 n0&#xff0c;使得对任意 的 n ≥ n0&#xff0c;有T( n) ≤ C g( n)。 其中&#xff1a;n 是算法输入的规模&#xff0c;如数组的…

【ghost】制作一个DOS启动盘用于备份/恢复系统

常用的DOS启动盘制作工具有USBoot、Ghost及FlashBoot等&#xff0c;本次DOS启动盘使用Ghost工具制作。 制作前准备 装有win10(或win7)系统的PC机&#xff0c;1台&#xff1b;U盘&#xff0c;1个&#xff1b;&#xff08;建议用户选择兼容性较高的金士顿U盘&#xff1b;此次演…

JAVA实战开源项目:快递管理系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

Linux系统架构----LNMP平台部署中部署wordpress

Linux系统架构----LNMP平台部署中部署wordpress 一、LNMP的概述 LNMP为Linux平台&#xff0c;Nginx web服务软件&#xff0c;mysql数据库软件&#xff0c;PHP编辑语言LNMP系统架构相对于LAMP的优点是LNMP比较节省内存&#xff0c;主要支持静态请求&#xff0c;但在访问量大的…