Mybatis-plus:快速入门级常见操作,建议收藏作为手册

428 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

开始正文之前,先奉上一份:MyBatis-Plus 3.x 文档手册

1.常见注解

@TableName

注解在类上,指定类和数据库表的映射关系。

实体类的类名(转成小写后)和数据库表名相同时,可以不指定该注解。

有时候库中的表很多,需要根据表的前缀或者后缀对表进行业务划分时,利用此注解可以很方便的实现映射,但是在编写代码时可以不考虑前缀或后缀。

使用示例:

@TableName("mp_goods")

@TableId

注解在实体类的某一字段上,表示这个字段对应数据库表的主键。当主键名为id时(表中列名为id,实体类中字段名为id),无需使用该注解显式指定主键,mp会自动关联。若类的字段名和表的列名不一致,可用value属性指定表的列名。另,这个注解有个重要的属性type,用于指定主键策略。

使用示例:

@TableId(
    value = "id",              //主键对应的列为id
    type = IdType.ASSIGN_ID    //雪花算法
)

@TableField

(1)排除非表字段

若Java实体类中某个字段,不对应表中的任何列,它只是用于保存一些额外的,或组装后的数据,则可以设置exist属性为false(默认为true)

@TableField(exist = false)

这样在执行操作数据库的接口时,都会忽略这个字段。也可使用@Transient实现。

(2)字段验证策略

通过insertStrategy,updateStrategy,whereStrategy属性进行配置,可以控制在实体对象进行插入,更新,或作为WHERE条件时,对象中的字段要如何组装到SQL语句中。如果在查询时,不允许该字段为null,注解如下:

@TableField(whereStrategy = FieldStrategy.NOT_NULL)

(3)字段填充策略

通过fill属性指定,字段为空时会进行自动填充,功能类似于设置一个默认值

@TableField(value = "0",fill = FieldFill.INSERT)

value缺省时默认值是"",这个注解的意思是在插入时,如果字段为空,则填充”0“。

@Version

对需要加乐观锁的字段加上该注解,在每次修改该条数据时,会判断锁。执行更新时, set version = newVersion where version = oldVersion,

如果oldVersion与数据库中的version不一致,就更新失败。

@TableLogic

逻辑删除

2.条件构造器

selectMaps

当某个表的列特别多,而SELECT的时候只需要选取个别列,查询出的结果也没必要封装成Java实体类对象时(只查部分列时,封装成实体后,实体对象中的很多属性会是null),则可以用selectMaps,获取到指定的列后,再自行进行处理即可

比如

@Test  
   public void test3() {  
    QueryWrapper<User> wrapper = new QueryWrapper<>();  
    wrapper.select("id","name","email").likeRight("name","黄");  
    List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);  
    maps.forEach(System.out::println);  
   }

selectObjs

只会返回某些字段的值,其他字段会被舍弃

比如

@Test  
 public void test() {  
  QueryWrapper<User> wrapper = new QueryWrapper<>();  
  wrapper.select("id", "name").like("name", "黄");  
  List<Object> objects = userMapper.selectObjs(wrapper);  
  objects.forEach(System.out::println);  
 }

得到的结果,只封装了第一列的id

selectCount

查询满足条件的总数,注意,使用这个方法,不能调用QueryWrapper的select方法设置要查询的列了。

这个方法会自动添加select count(1)

比如

@Test  
 public void test() {  
  QueryWrapper<User> wrapper = new QueryWrapper<>();  
  wrapper.like("name", "黄");  
  
  Integer count = userMapper.selectCount(wrapper);  
  System.out.println(count);  
 }

Condition

条件构造器的诸多方法中,均可以指定一个boolean类型的参数condition,用来决定该条件是否加入最后生成的WHERE语句中,比如

String name = "黄"; // 假设name变量是一个外部传入的参数  
QueryWrapper<User> wrapper = new QueryWrapper<>();  
wrapper.like(StringUtils.hasText(name), "name", name);  

实体对象作为条件

调用构造函数创建一个Wrapper对象时,可以传入一个实体对象。后续使用这个Wrapper时,会以实体对象中的非空属性,构建WHERE条件(默认构建等值匹配的WHERE条件,这个行为可以通过实体类里各个字段上的@TableField注解中的condition属性进行改变)

示例如下

@Test  
 public void test3() {  
  User user = new User();  
  user.setName("黄主管");  
  user.setAge(28);  
  QueryWrapper<User> wrapper = new QueryWrapper<>(user);  
  List<User> users = userMapper.selectList(wrapper);  
  users.forEach(System.out::println);  
 }

lambda条件构造器

lambda条件构造器,支持lambda表达式,可以不必像普通条件构造器一样,以字符串形式指定列名,它可以直接以实体类的方法引用来指定列。示例如下

@Test  
 public void testLambda() {  
  LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();  
  wrapper.like(User::getName, "黄").lt(User::getAge, 30);  
  List<User> users = userMapper.selectList(wrapper);  
  users.forEach(System.out::println);  
 }

像普通的条件构造器,列名是用字符串的形式指定,无法在编译期进行列名合法性的检查,这就不如lambda条件构造器来的优雅。

另外,还有个链式lambda条件构造器,使用示例如下

@Test  
 public void testLambda() {  
  LambdaQueryChainWrapper<User> chainWrapper = new LambdaQueryChainWrapper<>(userMapper);  
  List<User> users = chainWrapper.like(User::getName, "黄").gt(User::getAge, 30).list();  
  users.forEach(System.out::println);  
 }
 

IService链式调用

代码写起来非常简洁

查询示例

@Test
public void testChain() {
List list = userService.lambdaQuery()
.gt(User::getAge, 39)
.likeRight(User::getName, "王")
.list();
list.forEach(System.out::println);
}

更新示例

@Test
public void testChain() {
userService.lambdaUpdate()
.gt(User::getAge, 39)
.likeRight(User::getName, "王")
.set(User::getEmail, "w39@baomidou.com")
.update();
}

删除示例

@Test
public void testChain() {
userService.lambdaUpdate()
.like(User::getName, "青蛙")
.remove();
}