MyBatis-Plus为我们提供了BaseMapper,我们只需要继承BaseMapper就可以直接使用简单的增删改查功能。
数据库的主键对应实体中属性需要使用@TableId注解标注,并指明主键id的生成策略,常用的有AUTO(数据库自增)、ASSIGN_ID(雪花算法),当插入成功后会将主键id值回显给实体对象,一般情况下id生成策略都使用ATUO,只有在有分表需求的时候才使用ASSIGN_ID(雪花算法)。
注意:最新版本的mybatis-plus中的雪花算法好像不需要配置数据中心ID和机器ID,它们都是自动计算出来的:
mybatis-plus.global-config.datacenter-id 根据服务器的Mac地址来计算mybatis-plus.global-config.worker-id 根据datacenter-id和java虚拟中的bean数量来计算。使用@TableId(type = IdType.AUTO)这种将注解标注在主键id属性上属于局部主键策略,我们也可以在application.yml中配置全局主键策略,当配置了全局id生成策略并且主键为“id”此时不用显式的使用@TableId注解,如果同时配置了全局策略和局部策略,那么局部策略优于全局策略。
# 配置mybatis plus 全局的id生成策略 mybatis-plus.global-config.db-config.id-type=auto注意:修改时如果属性为null也是不会加入到SQL语句中来的。
@Test public void testUpdate(){ User user = new User(); user.setAge(35); user.setRemark("重庆军统王牌特工,表面残酷狠辣的军统特务“鬼子六”"); QueryWrapper<User> queryWrapper = new QueryWrapper(); queryWrapper.eq("username", "sixbrother").gt("age", 20); // UPDATE tbl_user SET age=?, remark=? WHERE (username = ? AND age > ?) int affectRows = userMapper.update(user, queryWrapper); System.out.println(affectRows); } @Test void testMyBatisPlus() { // UPDATE tbl_user SET age=?, status=? WHERE (id = ?) User user = new User(); user.setId(1L); user.setAge(50); user.setStatus(2); QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("id", 100L); int affectRows = userMapper.update(user, queryWrapper); System.out.println(affectRows); }UpdateWrapper可以通过set方法来设置字段的值。
@Test void testMyBatisPlus() { // UPDATE tbl_user SET age=?,status=? WHERE (id = ?) UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>() .set("age", 30) .set("status", 2) .eq("id", 100L); int affectRows = userMapper.update(null, updateWrapper); System.out.println(affectRows); }UpdateWrapper可以通过setSql() 采用SQL语法来设置值。
@Test void testMyBatisPlus() { // UPDATE tbl_user SET age=?,status = 2 WHERE (id = ?) LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<User>() .set(User::getAge, 30) .setSql("status = 2") .eq(User::getId, 100L); int affectRows = userMapper.update(null, updateWrapper); System.out.println(affectRows); }注意:
QueryWrapper:用于构造where条件的,SQL中的条件在QueryWrapper中都有对应的方法。QueryWrapper默认是使用and 并且来连接各个条件的。UpdateWrapper:用于构造update语句,比QueryWrapper多了一个set()方法用于修改值,也可以使用QueryWrapper中的方法来构造where条件。selectMaps()通常用于统计查询,因为一般统计的结果字段都不在实体类中。
@Test void testMyBatisPlus() { // SELECT gender,count(*) as count,avg(age) as avg_age FROM tbl_user GROUP BY gender QueryWrapper<User> queryWrapper = Wrappers.<User>query() .select("gender", "count(*) as count", "avg(age) as avg_age").groupBy("gender"); List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper); System.out.println(maps); }自定义SQL就是又想自己写SQL语句又想使用MyBatis-Plus中的条件构造器Wrapper,MyBatis-Plus中可以支持此方式,通过使用@Param注解即可引用条件构造器。
BaseMapper中的很多方法参数都使用了@Param注解进行标注了,这就意味着我们可以在原生的MyBatis中使用这个参数(可以在MyBatis注解中也可以在xml文件中),例如使用@Param(Constants.WRAPPER) 定义参数名,在MyBatis中使用固定的写法${ew.customSqlSegment}来引用MyBatis-Plus中的条件构造器。
@Test void testMyBatisPlus() { // delete from tbl_user WHERE (id = ? OR age > ?) QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("id", 100).or().gt("age", 30); userMapper.myDelete(wrapper); } public interface UserMapper extends BaseMapper<User> { // 注意SQL语句不需要加where关键字 @Delete("delete from tbl_user ${ew.customSqlSegment}") void myDelete(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper); }@TableField用于指定字段的一些属性,常用的场景有:
对象中的属性名和字段名不一致的问题,如表中使用user_id作为主键,而实体中使用id作为属性名,此时需要配置两者的映射关系。 @TableName("tbl_user") public class User implements Serializable { /** * 主键 */ @TableId(type = IdType.AUTO) @TableField(value = "user_id") private Long id; } 对象中的属性字段在表中不存在的问题。 @TableName("tbl_user") public class User implements Serializable { /** 数据库中不存在的字段 */ @TableField(exist = false) private String mock; } 查询时不查询指定的字段,如有些字段只是服务器在使用,没必要暴露出去 @TableName("tbl_user") public class User implements Serializable { /** * 版本号 */ @TableField(select = false) private String version; /** * 是否删除(0: 未删除,1:已删除) */ @TableField(select = false) private Integer deleted; }