MyBatis Plus,作为对MyBatis的进一步增强,大大简化了我们的开发流程,提高了开发速度
配置 由于Mybatis Plus是建立在Mybatis之上的,所以其已经依赖了Mybatis,故我们无需在项目中显式地重复添加Mybatis依赖。直接在POM文件中Mybatis Plus依赖即可
1 2 3 4 5 6 <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.4.1</version > </dependency >
Mapper CRUD操作 在Mybatis下,需要我们自行编写Mapper接口文件、提供sql的的xml文件。众所周知,这些CRUD的接口写起来不仅繁琐还容易出错,为此在Mybatis Plus中提供了内置的Mapper。高效实现CRUD操作
1 2 3 4 5 6 7 create table t_people_info ( id int not null auto_increment comment 'ID' , name varchar (255 ) null comment '姓名' , sex varchar (255 ) null comment '性别' , primary key (id) ) comment '信息表' ;
POJO类定义如下,这里展示了@TableName、@TableField注解的用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;@Data @Builder @AllArgsConstructor @NoArgsConstructor @TableName("t_people_info") public class People { private int id; @TableField("name") private String username; private String sex; @TableField(exist = false) private String job; }
而Mapper接口文件只需继承BaseMapper即可获得Mybatis Plus提供的基本的CRUD功能,无需我们定义接口及相关的SQL。当然如果需要复杂的操作直接在PeopleMapper接口中继续添加即可
1 2 3 4 5 import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface PeopleMapper extends BaseMapper <People> {}
增 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class ProperService { @Autowired private PeopleMapper peopleMapper; public void testInsert () { List<People> list = new LinkedList <>(); list.add( People.builder().username("小明" ).build() ); list.add( People.builder().id(10 ).username("老王" ).sex("男" ).build() ); list.add( People.builder().id(11 ).username("老张" ).sex("女" ).build() ); list.add( People.builder().id(12 ).sex("女" ).build() ); for (People people : list) { peopleMapper.insert(people); } } }
删 根据ID删除及批量操作,方式如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void testDeleteById () { peopleMapper.deleteById(10 ); } public void testDeleteByIds () { List ids = new LinkedList (); ids.add(11 ); ids.add(12 ); peopleMapper.deleteBatchIds( ids ); }
与此同时,也支持基于条件的删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public void testDeleteByParam1 () { Map map = new HashMap (); map.put("name" , "匿名用户" ); map.put("sex" , "男" ); int num = peopleMapper.deleteByMap(map); System.out.println("delete num : " + num); } public void testDeleteByParam2 () { People people = People.builder() .username("翠花" ) .sex("女" ) .build(); QueryWrapper<People> wrapper = new QueryWrapper <>(people); int num = peopleMapper.delete( wrapper ); System.out.println("delete num : " + num); }
改 同理对于更新操作,支持基于ID的操作方式
1 2 3 4 5 6 7 8 9 10 11 public void testUpdateById () { People people = People.builder() .id(3 ) .username("孙尚香" ) .build(); peopleMapper.updateById(people); }
上述更新语句执行后会发现,id为3的记录,对于name字段确实被更新为 “孙尚香” 了,但是如果sex字段并不会被更新为 NULL。这是因为@TableField注解的updateStrategy属性默认为NOT_NULL所导致的。该属性常用的值及释义如下所示
NOT_NULL :要求新值非NULL
NOT_EMPTY :要求新值非NULL、非空字符串
IGNORED :新值可以为NULL、空字符串
故我们在sex属性上使用@TableField注解,并把updateStrategy设置为FieldStrategy.IGNORED后,上述测试代码对sex字段的更新才会生效
1 2 3 4 5 @TableField(updateStrategy = FieldStrategy.IGNORED) private String sex;
与此同时,也支持基于条件的更新。而且可以看到在基于ID的更新方式中,需要修改@TableField注解的updateStrategy属性,来保证可以更新为NULL、空字符串。显然非常麻烦,而且容易出错。而通过updateWrapper的set方法来设置新值,显式地设置NULL值就非常直观了,不容易出错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void testUpdateByParam () { UpdateWrapper<People> updateWrapper = new UpdateWrapper <>(); updateWrapper.gt("id" ,50 ); updateWrapper.set("sex" ,"男" ); updateWrapper.set("name" ,"null" ); peopleMapper.update(null , updateWrapper); }
查 根据ID查询及批量操作,方式如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void testSelectById () { People people = peopleMapper.selectById(1 ); System.out.println("people: " + people); } public void testSelectByIds () { List list = new LinkedList (); list.add(1 ); list.add(2 ); list.add(3 ); List<People> peopleList = peopleMapper.selectBatchIds(list); peopleList.forEach(System.out::println); }
与此同时,也支持基于条件的查询。其中查询条件为空,则查询全部
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public void testSelectAll () { List<People> list = peopleMapper.selectList(null ); list.forEach( System.out::println ); } public void testSelectByParam1 () { QueryWrapper<People> queryWrapper = new QueryWrapper <>(); queryWrapper.eq("sex" , "男" ); queryWrapper.le("id" , 50 ); List<People> list = peopleMapper.selectList(queryWrapper); list.forEach(System.out::println); } public void testSelectByParam2 () { Map<String, Object> map = new HashMap <>(); map.put("sex" , "女" ); map.put("name" , "佳丽" ); List<People> list = peopleMapper.selectByMap(map); list.forEach(System.out::println); }
有时候我们还需要进行分页查询,在Mybatis Plus下也是非常方便的,只需配置下分页插件即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor innerInterceptor () { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor (); interceptor.addInnerInterceptor(new PaginationInnerInterceptor (DbType.MYSQL)); return interceptor; } }
关于分页查询的操作方式如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public void testSelectByPage () { QueryWrapper<People> queryWrapper = new QueryWrapper <>(); queryWrapper.gt("id" , 2 ); queryWrapper.likeRight("name" , "张" ); Page<People> page = new Page <>(2 ,10 ); Page<People> result = peopleMapper.selectPage(page2, queryWrapper); System.out.println("people List: " + result.getRecords() ); }
逻辑删除 对于内置Mapper,Mybatis Plus可以自动支持逻辑删除的功能。通过@TableLogic注解指定逻辑删除字段即可
1 2 3 4 5 @TableLogic private String flag;
而对于逻辑未删除的值、已删除的值即可直接通过注解配置,亦可进行全局配置
1 2 3 4 mybatis-plus.global-config.db-config.logic-delete-value =invalid mybatis-plus.global-config.db-config.logic-not-delete-value =valid
为了实现逻辑删除,内置Mapper在自动注入SQL时也会发生一些变化。具体地:
插入:无变化
查找:一方面会追加where条件以过滤掉已删除的记录,另一方面,通过wrapper指定条件也会忽略逻辑删除字段的条件
更新:一方面会追加where条件防止对已删除的记录进行更新,另一方面,通过wrapper指定条件也会忽略逻辑删除字段的条件
删除:转变为更新语句,将 逻辑删除字段 设置为 逻辑已删除值
Note 对于主键,Mybatis Plus还支持在未指定主键的时候自动生成ID或UUID。具体地,其支持对某个表的单独设置、全局设置。前者可通过在主键属性上设置@TableId注解的type属性为IdType.ASSIGN_ID、IdType.ASSIGN_UUID实现;后者则可通过在配置文件中设置配置项 mybatis-plus.global-config.db-config.id-type 为 assign_id、assign_uuid 实现