SpringBoot集成Mybatis-Plus

一、mybatis配置

1.maven依赖

<!--mybatis-plus的springboot支持(集成mybatis-plus要把mybatis、mybatis-spring去掉,避免冲突)-->
<dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.4.3.1</version>
 </dependency>
 <!--mysql驱动-->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <scope>runtime</scope>
 </dependency>

2.yaml配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/haha?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
    map-underscore-to-camel-case: true # 该配置就是将带有下划线的表字段映射为驼峰格式的实体类属性
    mapper-locations: classpath:mapper/*.xml #配置xml地址

3.实体类

@Data
@ApiModel
@TableName(value = "user") //mybatis-plus注解
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1903236519513043621L;

    @ApiModelProperty("id")
    private Long id;
    
    @ApiModelProperty("名称")
    private String name;

    @ApiModelProperty("性别")
    private Integer sex;

    @ApiModelProperty("日期")
    private Date date;

}

4.DAO
dao接口需要继承BaseMapper,泛型为实体类

public interface UserDao extends BaseMapper<UserEntity> {
}

5.service
service接口需要继承IService,泛型为实体类

public interface UserService extends IService<UserEntity> {
}

6.serviceImpl
serviceImpl实现service接口,并继承ServiceImpl类,泛型为DAO接口和实体类

@Service
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements PersonService {
}

7.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.CacheTestDao">
</mapper>

注:记得在启动类加上@MapperScan(basePackages = “com.example.dao”)注解,或者在每个dao加上@Mapper

二、Wrapper 包装类

如图 BaseMapper 类中的一些查询、修改、删除接口会用到 Wrapper 包装类,那么这个 Wrapper 包装类应该怎么使用呢

在这里插入图片描述

1、Mybatis 中提供了哪些 Wrapper 包装类?

Mybatis-Plus 提供了多种 Wrapper 类型,具体使用哪种 Wrapper 类型取决于开发者的需求和个人习惯。以下是 Mybatis-Plus 常用的 Wrapper 类型和适用场景:

QueryWrapper

  • QueryWrapper 是 Mybatis-Plus 最常用的 Wrapper 类型之一,用于构建查询条件。可以使用
    QueryWrapper 进行等值查询、模糊查询、范围查询、排序等操作。使用 QueryWrapper
    进行查询时,需要指定查询的实体类,Wrapper 会根据实体类的属性自动生成查询条件。适用于大部分查询场景。

UpdateWrapper

  • UpdateWrapper 是用于构建更新条件的 Wrapper 类型,可以使用 UpdateWrapper
    进行等值更新、自增更新、条件更新等操作。使用 UpdateWrapper 进行更新时,需要指定更新的实体类和更新条件,Wrapper
    会根据实体类的属性自动生成更新条件。适用于大部分更新场景。

LambdaQueryWrapper

  • LambdaQueryWrapper 是使用 Lambda 表达式构建查询条件的 Wrapper 类型,可以使用
    LambdaQueryWrapper 进行等值查询、模糊查询、范围查询、排序等操作。LambdaQueryWrapper 可以使用
    Java 8 的 Lambda 表达式进行条件构建,代码更加简洁易读。适用于需要使用 Lambda 表达式进行条件构建的查询场景。

LambdaUpdateWrapper

  • LambdaUpdateWrapper 是使用 Lambda 表达式构建更新条件的 Wrapper 类型,可以使用
    LambdaUpdateWrapper 进行等值更新、自增更新、条件更新等操作。LambdaUpdateWrapper 可以使用 Java
    8 的 Lambda 表达式进行条件构建,代码更加简洁易读。适用于需要使用 Lambda 表达式进行条件构建的更新场景。

总之,Mybatis-Plus 提供了多种 Wrapper 类型,开发者可以根据具体需求选择合适的 Wrapper 类型进行操作。需要注意的是,每种 Wrapper 类型都有其适用场景和局限性,开发者需要根据实际情况进行选择。

2、QueryWrapper 常用方法

Mybatis-Plus 的 QueryWrapper 提供了多个方法,可以用于构建查询条件。以下是 QueryWrapper 中常用的方法及其用法示例:

// 1.等值查询,用于匹配指定字段等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");

// 2.不等于查询,用于匹配指定字段不等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ne("age", 18);

// 3.大于查询,用于匹配指定字段大于指定值的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18);

// 4.大于等于查询,用于匹配指定字段大于等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age", 18);

// 5.小于查询,用于匹配指定字段小于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lt("age", 18);

// 6.小于等于查询,用于匹配指定字段小于等于指定值的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.le("age", 18);

// 7.范围查询,用于匹配指定字段在指定范围内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 18, 25);

// 8.模糊查询,用于匹配指定字段包含指定字符串的记录。可以使用 % 通配符表示任意字符,使用 _ 通配符表示任意单个字符。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "张%");

// 9.不包含查询,用于匹配指定字段不包含指定字符串的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.notLike("name", "%三");

// 10.IN 查询,用于匹配指定字段在指定集合内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
List<Integer> ages = Arrays.asList(18, 20, 22);
wrapper.in("age", ages);

// 11.NOT IN 查询,用于匹配指定字段不在指定集合内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
List<Integer> ages = Arrays.asList(18, 20, 22);
wrapper.notIn("age", ages);

// 12.NULL 查询,用于匹配指定字段为 NULL 的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNull("email");

// 13.NOT NULL 查询,用于匹配指定字段不为 NULL 的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("email");

// 14.升序排序,用于按照指定字段升序排列查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age", "name");

// 15.降序排序,用于按照指定字段降序排列查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("age", "name");

// 16.分组查询,用于按照指定字段进行分组查询。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "count(*)").groupBy("age");

// 17.HAVING 子句查询,用于筛选分组查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "count(*)").groupBy("age").having("age > {0} and count(*) > 1", 18);
List<User> userList = userMapper.selectList(wrapper); //  {0} 占位符表示参数 18,表示筛选出 age 大于 18 的记录。

3、QueryWrapper 复杂方法

// 1. nested(Consumer<QueryWrapper<T>> consumer)
嵌套查询,用于构建复杂的查询条件。可以使用多个 nested 方法嵌套多个查询条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.nested(qw -> qw.eq("name", "张三").or().eq("name", "李四"))
       .and(qw -> qw.gt("age", 18).lt("age", 30));

// 2.  apply(String applySql, Object... params)
自定义 SQL 查询,用于直接使用 SQL 语句查询数据。可以使用 {0}{1} 等占位符表示参数。
嵌套查询,用于构建复杂的查询条件。可以使用多个 nested 方法嵌套多个查询条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.apply("name like {0} or age > {1}", "%张%", 18);

 // 3. last(String lastSql)SQL 语句的最后添加额外的条件,用于构建复杂的查询条件。可以使用多个 last 方法添加多个额外的条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18).last("limit 10");

 // 4. select(String... columns)
指定查询的字段,用于查询指定的字段而非全部字段。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("name", "age");

 // 5.allEq(Map<String, Object> params, boolean null2IsNull)
使用 Map 对象作为查询条件,进行等值匹配查询。可以通过第二个参数指定是否将 null 值转换为 is null 条件。

QueryWrapper<User> wrapper = new QueryWrapper<>();
Map<String, Object> params = new HashMap<>();
params.put("name", "张三");
params.put("age", 18);
wrapper.allEq(params, false);

4、LambdaQueryWrapper 常用方法

lambdaQueryWrapper.eq(User::getId, 1L); // 等价于 where id = 1

lambdaQueryWrapper.ne(User::getStatus, "DISABLED"); // 等价于 where status <> 'DISABLED'

lambdaQueryWrapper.gt(User::getAge, 18); // 等价于 where age > 18

lambdaQueryWrapper.ge(User::getCreateTime, LocalDateTime.now().minusDays(30)); // 等价于 where create_time >= ?

lambdaQueryWrapper.lt(User::getAge, 30); // 等价于 where age < 30

lambdaQueryWrapper.le(User::getUpdateTime, LocalDateTime.now()); // 等价于 where update_time <= ?

lambdaQueryWrapper.like(User::getName, "Tom"); // 等价于 where name like '%Tom%'

lambdaQueryWrapper.notLike(User::getName, "admin"); // 等价于 where name not like '%admin%'

List<Integer> ids = Arrays.asList(1, 2, 3);
lambdaQueryWrapper.in(User::getId, ids); // 等价于 where id in (1, 2, 3)

List<Integer> ids = Arrays.asList(1, 2, 3);
lambdaQueryWrapper.notIn(User::getId, ids); // 等价于 where id not in (1, 2, 3)

lambdaQueryWrapper.isNull(User::getEmail); // 等价于 where email is null

lambdaQueryWrapper.isNotNull(User::getPhone); // 等价于 where phone is not null

lambdaQueryWrapper.orderByAsc(User::getAge); // 等价于 order by age asc

lambdaQueryWrapper.orderByDesc(User::getCreateTime); // 等价于 order by create_time desc

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

5、LambdaQueryWrapper 复杂方法

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.nested(wrapper -> wrapper.eq(User::getAge, 20).or().eq(User::getAge, 30));
// 等价于 where (age = 20 or age = 30)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.exists("select 1 from user_role where user_role.user_id = user.id and user_role.role_id = 1");
// 等价于 where exists (select 1 from user_role where user_role.user_id = user.id and user_role.role_id = 1)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.inSql(User::getId, "select user_id from user_role where role_id = 1");
// 等价于 where id in (select user_id from user_role where role_id = 1)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.and(wrapper -> wrapper.eq(User::getAge, 20).eq(User::getStatus, "ENABLED"));
// 等价于 where age = 20 and status = 'ENABLED'

lambdaQueryWrapper.or(wrapper -> wrapper.eq(User::getAge, 30).eq(User::getStatus, "DISABLED"));
// 等价于 where age = 30 or status = 'DISABLED'

5、总结

  1. 表达式方式不同: LambdaQueryWrapper 使用 Lambda 表达式来编写查询条件,而 QueryWrapper
    使用字符串方式编写查询条件。
  2. 查询条件的类型: LambdaQueryWrapper 适用于实体类属性较多的情况,可以灵活的使用 Lambda
    表达式来构建查询条件。而 QueryWrapper 则适用于实体类属性较少,查询条件比较简单的情况。
  3. 语法错误提示:LambdaQueryWrapper 在编写查询条件时,编译器会对 Lambda
    表达式进行语法检查,如果出现错误则会提示,而 QueryWrapper 则需要在运行时才能发现语法错误。
  4. 可读性:LambdaQueryWrapper 的查询条件使用 Lambda 表达式编写,可读性较高,可以直观的看出查询条件的含义;而
    QueryWrapper 则使用字符串方式编写查询条件,可读性相对较差。

总的来说,LambdaQueryWrapper 和 QueryWrapper 都有各自的优势,不过个人推荐使用 LambdaQueryWrapper

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值