学习Mybatis-Plus的记录

发布时间 2023-09-17 09:16:37作者: 黄小葱

1. 常用注解

  • @TableName 用于在数据库表名和实体对象上,当数据库表明和实体对象不一致,可以用该注解声明
  • @TableId 用于标识数据库的主键Id,当字段名不是固定的名为id时,需要用该字段进行标识
  • @TableField 当数据库的字段名称和实体对象的名称不一致时,可以用该标识进行映射。也可以采用该注解中的exist=false,标识该字段在数据库中没有,但是在实体对象中存在使用。

2. 条件查询

  • 使用普通的QueryWrapper查询,例如:
// 需求是:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "小") ;

2.1. 各种方式的查询

在Wrapper中使用函数、子查询、括号(前置括号、后置连接括号)、随机返回一条语句的用例方式

  • 使用函数的方式,apply 如:
queryWrapper.apply("date_format(create_time, '%Y-%m-%d')={0})", "2023-08-13");
  • 子查询的方式,使用inSql,如:
queryWrapper.inSql("manager_id", "select id from user where name like '王%'");
//相当于:select * from user where manager_id in(select id from user where name like '王%');
  • 括号(前置和后置)的方式
//前置括号
queryWrapper.nested(qw -> qw.like("name", "王").or().between("age", 22, 33)).isNotNull("email");
//后置括号,使用or(wq-> qw.xx) 或者 and(qw -> qw.xxx)
  • 随机返回一条语句的方式,使用last(limit 1) 注意,使用last存在sql注入的风险
  • 实体作为条件构造器构造方法的参数
        User whereUser = new User();
        whereUser.setName("张雨琪");

        // 注意泛型中的whereUser 作为传参
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(whereUser);
        queryWrapper.like("name", "雨");
        List<User> users = userMapper.selectList(queryWrapper);

2.2. AllEq用法

allEq(Map<R, V> params),其中 key作为数据库字段名,value为字段值

    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("name", "张雨琪");
    paramMap.put("age", null);

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//当allEq中的第二个参数为false是,会忽略值为null的字段,如上面的age
    queryWrapper.allEq(paramMap, false);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);

2.3 selectOne方法

当查找到多条数据时,该方法会报错

2.4 lambda条件构造器

使用lambda表达式的好处是,可以在查询条件中使用实体对象,能够检查错误
  LambdaQueryWrapper<User> queryWrapper = new QueryWrapper<User>().lambda();
  queryWrapper.likeRight(User::getName, "王")
          .and(lqw -> lqw.lt(User::getAge, 40).or().isNotNull(User::getEmail));

  List<User> users = userMapper.selectList(queryWrapper);
  users.forEach(System.out::println);

2.5 select 不查出所有的字段

    LambdaQueryWrapper<User> queryWrapper = new QueryWrapper<User>().lambda();
    queryWrapper.select(User::getName, User::getAge).isNotNull(User::getEmail);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);

2.6 通用Mapper

实体作为条件构造器构造方法的参数

	User user = new User();
	user.setAge(22);
	user.setName("雨");

	QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
	List<User> users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);

2.7 自定义sql

    @Select("select * from mp_user ${ew.customSqlSegment}")
    List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);

  //其中ew为@Param参数中Constants.WRAPPER的值

通过xml的方式自定义sql

  1. 在resource文件下,新增.xml的映射文件。如下图所示:

// 2. 在application.xml配置文件中,新增扫描xml文件的路径
mybatis-plus.mapper-locations=classpath:mapper/*
// 3. 在xml文件中,编写对应的方法
    <select id="selectAll" resultType="com.hxc.mpex.entity.User" >
        select * from mp_user ${ew.customSqlSegment}
    </select>

3. 分页查询

  1. 需要添加分页插件。新增一个配置类
@Configuration
public class MybatisConfig {

    @Bean
    public MybatisPlusInterceptor paginationInnerInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor();
        interceptor.addInnerInterceptor(innerInterceptor);
        return interceptor;
    }
}
  1. 分页方法主要有两种,一种是 selectPage,一种是 selectMapsPage,返回的数据格式不一样,但是都差不多,看自己需要。如果不想查询分页,可以在Page对象中加入false,如:IPage iPage = new Page<>(1, 2, false);
        LambdaQueryWrapper<User> queryWrapper = new QueryWrapper<User>().lambda();
        IPage<User> iPage = new Page<>(1, 2);
        IPage<User> resultPage = userMapper.selectPage(iPage, queryWrapper);
        System.out.println("总页数:" + resultPage.getPages());
        System.out.println("总记录:" + resultPage.getTotal());
        List<User> records = resultPage.getRecords();
        records.forEach(System.out::println);

4. 更新

  1. 方法 update(@Param("et") T entity, @Param("ew") Wrapper updateWrapper); 中,第一个参数的entity用于在更新语句的set中,第二个参数用于在where的条件中

5. AR(ActiveRecord)模式

  1. 首先在entity类中,需要继承Model类
public class User extends Model<User> {}
  1. Mapper接口必须继承BaseMapper接口,即:
public interface UserMapper extends BaseMapper<User>{}
  1. 直接用user这个对象进行操作就可以了。测试如下
    @Test
    public void selectByIdTest() {
        User user = new User();
        user.setId(12L);
        User userResult = user.selectById();
        log.info("result:{}", userResult);
    }

6. 主键策略

注:修改数据库的字段为自增的sql:(其中在id前面多一个id)
alter table mp_user change column id id bigint(20) auto_increment;
MP默认的主键策略是,采用雪花算法生成。策略的种类,具体可以查看mybatisplus中的 IdType 枚举类。
使用方式如下:

    // 用TableId标识主键,并声明采用的策略
    @TableId(type = IdType.AUTO)
    private Long id;

如果想在全局设置主键的策略,可以在配置文件中定义:

#配置全局策略(局部策略优于全局策略)
mybatis-plus.global-config.db-config.id-type=auto

7.Mp的配置

  1. fieldStrategy
    该策略约定了如何产出注入的sql,涉及到insert、update以及wapper内部生成where条件。也就是未设置值(即为null)的话,不会加入到上面的几种类型中
  2. table-prefix
    指定表名的前缀