Mybatis-Plus使用
一.引入依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.10.1</version>
</dependency>
二.继承接口
先创建一个UserInfo类,其对应数据库的user_info表
@Data
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
Mybatis-Plus提供了一个基础的BaseMapper接口,里面已经实现了单表的CRUD
我们创建一个UserInfoMapper类,让它实现BaseMapper接口,里面的泛型T就是对应表名属性的类
@Mapper
public interface UserInfoMapper extends BaseMapper<Userinfo> {}
在该类里面可以重写父类方法也可以添加新的方法,如果什么都不写那就是全部使用父类方法
然后就可以直接使用Mybatis-Plus写好的CRUD方法
SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insert(){Userinfo userInfo = new Userinfo();userInfo.setUsername("admin");userInfo.setPassword("123456");userInfo.setAge(15);userInfo.setPhone("45667788");userInfoMapper.insert(userInfo);}@Testvoid delete(){userInfoMapper.deleteById(5);}@Testvoid update(){Userinfo userInfo = new Userinfo();userInfo.setId(4);userInfo.setUsername("admin444");userInfo.setPassword("admin444");userInfo.setAge(4);userInfoMapper.updateById(userInfo);}@Testvoid select(){Userinfo userInfo = userInfoMapper.selectById(4);System.out.println(userInfo);}
其中之所以能完美匹配到,是因为我们使用了标准命名格式,即
类名驼峰表示法会被识别到表名蛇形表示法,如UserInfo——>user_info
属性名也是一样,deleteFlag——>delete_flag
而默认主键为id
所以如果我们命名不规范,那么就会无法匹配,这时候可以使用注解来指定对应关系
@TableName
如果实体类UserInfo修改为Userinfo,那么就无法匹配到数据表user_info了
这时就可以用@TableName来指定对应关系,参数里面是该实体类对应的表名
@Data
@TableName("user_info")
public class Userinfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
@TableField
如果属性名对不上,那就在属性名上加@TableField,参数是该实体类中属性对应数据表中的属性
@Data
@TableName("user_info")
public class Userinfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;@TableField("delete_flag")private Integer deleteflag;private Date createTime;private Date updateTime;
}
@TableId
指定主键,如果实体类的属性不为id,而叫userId,那么就不知道哪个属性是主键,就会报错,叫绑定异常,因此此时就可以用@TableId,参数为数据库表中的主键属性名
@Data
@TableName("user_info")
public class Userinfo {@TableId(type = IdType.AUTO)private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;@TableField("delete_flag")private Integer deleteflag;private Date createTime;private Date updateTime;
}
IdType.AUTO为按照数据库自增,即当插入数据时id没有值,则会自动生成,且数据表中的主键必须也设置了自增,否则报错
三.条件构造器
除了基础的操作,还有复杂的操作,而复杂的操作就需要条件构造器实现
其中主要的条件构造器(Wrapper类)有:
AbstractWrapper:所有Wrapper类的基类
QueryWrapper:构造查询条件
UpdateWrapper:构造更新条件
LambdaQueryWrapper:基于lambda表达式的构造查询条件
LambdaUpdateWrapper:基于lambda表达式的构造更新条件
1.QueryWrapper
如果要实现
select id, username, password, age, delete_flag from user_info where age=15 and username like "%min%"
这个sql语句
那么就可以用QueryWrapper
@Testvoid selectByCondition(){QueryWrapper<Userinfo> queryWrapper = new QueryWrapper<>();queryWrapper.select("id, username, password, age, delete_flag").eq("age", 15).like("username", "min");userInfoMapper.selectList(queryWrapper).forEach(System.out::println);}
其中先创建了一个条件构造器queryWrapper,然后通过方法进行构造
常见的方法有:
lt:小于
le:小于等于
gl:大于
ge:大于等于
eq:等于
ne:不等于
分别是对应英语单词的缩写
其中like方法默认左右都会加%实现全模糊,即"min"="%min%"
如果要实现左模糊或者右模糊,那么就可以使用likeLeft或者likeRight方法
更多方法在官方文档有,如有需要可以去官网查询
然后selectList是BaseMapper的方法,参数可以是构造器
然后System.out::println也是一个lambda表达式,等同于x-> System.out.println(x)
其中QueryWrapper不止可以实现查询,而且更新,删除也可以
@Testvoid deleteByCondition(){QueryWrapper<Userinfo> queryWrapper = new QueryWrapper<>();queryWrapper.eq("age", 4);userInfoMapper.delete(queryWrapper);}
2.UpdateWrapper
比QueryWrapper多了set方法
如果还是用QueryWrapper的话,就是如下这样
@Testvoid updateByCondition(){Userinfo userinfo = new Userinfo();userinfo.setDeleteflag(1);//where age<20QueryWrapper<Userinfo> queryWrapper = new QueryWrapper<>();queryWrapper.lt("age", 20);userInfoMapper.update(userinfo, queryWrapper);}
要创建一个类并作为修改的类
@Testvoid updateByCondition2(){UpdateWrapper<Userinfo> updateWrapper = new UpdateWrapper<>();updateWrapper.set("delete_flag", 0).lt("age", 20);userInfoMapper.update(updateWrapper);}
而UpdateWrapper则可以一步到位
而如果set条件比较复杂,比如age=age+10这样的,则可以直接用setSql方法
@Testvoid updateByCondition4(){UpdateWrapper<Userinfo> updateWrapper = new UpdateWrapper<>();updateWrapper.setSql("age = age+10").in("id", List.of(1, 2, 3));userInfoMapper.update(updateWrapper);}
3.LambdaQueryWrapper
上面两个的缺点是如果字段名写死了,后面如果发生更改,就有可能会出现没有完整改完遗漏,这时编译器也不会检查出来,就有可能发生错误,因此就出现了LambdaQueryWrapper和LambdaUpdateWrapper两个类
@Testvoid selectByCondition2(){QueryWrapper<Userinfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().select(Userinfo::getId, Userinfo::getUsername, Userinfo::getPassword,Userinfo::getAge, Userinfo::getDeleteflag).eq(Userinfo::getAge, 15).like(Userinfo::getUsername, "min");userInfoMapper.selectList(queryWrapper).forEach(System.out::println);}
其中可以通过querywrapper的lambda方法自动转换成LambdaQueryWrapper这个类型,也可以通过 new LambdaQueryWrapper()来创建
后面全部跟的是lambda表达式,将原来写死的字段名换成get方法,此时如果get方法写错了,那么编译器就可以检查出来,可以直接找到错误
4.LambdaUpdateWrapper
用法跟LambdaQueryWrapper类似
@Testvoid updateByCondition5(){UpdateWrapper<Userinfo> updateWrapper = new UpdateWrapper<>();updateWrapper.lambda().set(Userinfo::getDeleteflag, 0).lt(Userinfo::getAge, 20);userInfoMapper.update(updateWrapper);}
四.自定义SQL
如果mybatis-plus想要使用自定义SQL并结合条件构造器,则版本不能低于3.0.7
@Select("select id, username, password, age from user_info ${ew.customSqlSegment}")List<Userinfo> selectUserInfoByCondition(@Param(Constants.WRAPPER) Wrapper<Userinfo> queyWrapper);
其中在SQL语句中进行占位必须使用${ew.customSqlSegment}
而方法参数中的构造器要么参数名为ew,要么在前面使用注解@Param(Constants.WRAPPER),而其中参数名为ew也可以等同于@Param("ew")实现
@Update("update user_info set age = age + #{addAge} ${ew.customSqlSegment}")Integer updateById2(Integer addAge, @Param(Constants.WRAPPER) Wrapper<Userinfo> queyWrapper);
也可以结合之前的动态sql实现多个参数进行构造sql语句