1 特点
mybatis-plus是在mybatis基础上进行二次封装的一套orm框架,对mybatis只做增强不做改变,不会对项目中原生mybatis代码产生任何影响,完全兼容mybatis;
优点:
mybatis-plus只需要做简单的配置,即可快速进行单表CRUD操作,无需编写sql语句;
mybatis-plus提供了内置插件,提供分页,逻辑删除,乐观锁等功能;
引入mp后,主要目的是为了简化==单表==的CRUD操作。
缺点:
mybatis-plus在简化开发的同时,增加了学习成本,需要单独学习mybatis-plus的注解使用
会造成团队分裂,有人使用mybatis有人使用plus
会逐渐遗忘sql语句
不适用于复杂的业务场景
2 快速配置
创建springboot项目
添加mysql驱动,Druid启动器,添加mp启动器
<!--druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--jdbc--> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> --> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency>
配置数据源
spring: application: name: javasm datasource: url: jdbc:mysql://127.0.0.1:3306/javasm?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 min-idle: 10 max-active: 100
启动类添加扫描
@MapperScan("com.javasm.dao")
3 创建类
model
@TableName("sm_user") public class UserModel extends Model<UserModel>
dao接口
public interface UserDAO extends BaseMapper<UserModel> {}
service接口
public interface IUserService extends IService<UserModel> {}
接口实现类
@Service public class UserServiceImpl extends ServiceImpl<UserDAO, UserModel> implements IUserService{}
4 常用注解
@MapperScan 、 @Mapper
@TableName
作用:表名注解。 场景:当实体类名与表名不一致时,使用此注解指定表名。如果类名与表名一致,此注解可以省略 @TableName("sys_user") public class User { }
@TableId
作用:标注实体类的主键字段。 场景1:当主键字段名称不叫id时,使用@TableId指定主键列对应的属性名。一般主键列命名为id,,且使用雪花算法id作为主键值,此注解可以省略。 场景2:对insert语句,指定id的自动生成策略。默认type=IdType.ASSIGN_ID,支持如下策略: type = IdType.ASSIGN_ID 对于insert操作,mp自动生成雪花算法id赋值到对象中。 type = IdType.AUTO 要求数据库主键自增,int类型主键支持自增 type = IdType.ASSIGN_UUID 随机uuid作为主键,一般不使用,太长。 type = IdType.INPUT mp框架不再生成id,需要开发人员在insert之前手工设置id
@TableField
作用:非主键字段注解 场景1:字段名与属性名不一致;此注解的value属性指定字段名; 场景2:实体类的属性不属于表的字段时,此注解必用;此注解exist = false指定不是数据库表字段; 场景3:用在条件查询上,condition属性指定like非等值查询,配合QueryWrapper条件构建器使用; @TableField(value="pos_name",condition = SqlCondition.LIKE) 场景4:用在条件查询上,whereStrategy属性指定非null非""属性作为查询条件,配合QueryWrapper条件构建器使用; <if test="name != null and name != ''"> and name = #{name} </if> @TableField(whereStrategy = FieldStrategy.NOT_EMPTY)
select 是否查询
jdbcType 数据库字段类型
update
@TableField(update = "%s + 10")
insertStrategy
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
updateStrategy
@TableField(updateStrategy = FieldStrategy.DEFAULT)
@Version
作用:乐观锁注解,配合mp的乐观锁插件使用 场景:当要更新一条记录的时候,希望这条记录没有被别人更新 乐观锁原始实现方式: 数据库添加version字段,默认值1,int类型; 取出记录时,获取当前 version = 2 更新时,带上这个 version set version = 3 where version = 2 执行更新时, set version = newVersion where version = oldVersion 如果 version 不对,就更新失败 mp提供了乐观锁插件,对update语句进行重写,再mp中使用乐观锁分为两步: 1.全局配置乐观锁插件:OptimisticLockerInnerInterceptor到SqlSessionFactory 2.实体类的version属性上添加@Version注解。
@TableLogic
作用:逻辑删除注解。 项目开发中,重要数据会提供逻辑删除功能,但同时也一定会提供物理删除功能。 mp中的逻辑删除不要用,因为会造成所有select都会带上flag=0条件,无法查询逻辑删除后的数据。 value = "" 默认的原值 delval = "" 删除后的值 @TableLogic(value="原值",delval="改值") #物理删除 真删除 执行 delete语句 DELETE FROM sm_user WHERE uid = 24; #逻辑删除 假删除 执行 UPDATE语句 UPDATE sm_user SET isvalid = 0 WHERE uid = 26
5 条件构建器
条件构建器是mp提供的用于进行复杂条件查询与复杂修改数据的方法。
QueryWrapper一般用来做数据查询,继承自AbstractWrapper,新增了select方法;
UpdateWrapper一般用来做数据修改,继承自AbstractWrapper,新增了set方法;
AbstractWrapper是两者的父类,定义了各种条件定义方法。
AbstractWrapper eq = ne 不等于<> ge 大于等于>= gt 大于 > le 小于等于 <= lt 小于 < between between 条件语句 like 模糊查询 like notLike 模糊查询 not Like in in 查询 notIn not in 查询 isNull null 值查询 isNotNull is Not Null 查询 orderBy 排序查询 groupBy 分组查询 having 分组后筛选 QueryWrapper select UpdateWrapper set
6 QueryWrapper
//接收实体对象参数来构造查询条件,默认对非null属性做等值查询; QueryWrapper wrapper = new QueryWrapper(对象);
测试:
实体类对象查询
模糊查询
@TableField(whereStrategy = FieldStrategy.NOT_EMPTY)空值查询
使用条件构造方法
select方法指定查询列
7 UpdateWrapper
dao.update(实体类对象, updateWrapper对象);
根据实体对象非null属性指定update字段
SysUser u = new SysUser();
u.setUpwd("123");
UpdateWrapper w = new UpdateWrapper();
w.eq("uname","admin");
//eq方法:where uname='admin'
//根据Sysuser对象进行set修改,对非null属性进行set;update sys_user set upwd='123'
set方法指定update字段
UpdateWrapper w = new UpdateWrapper();
w.set("upwd","123");
w.eq("uname","admin");
//set方法: update sys_user set upwd='123'
//eq方法:where uname='admin'
8 内置插件
乐观锁插件
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加乐观锁插件,配合@Version注解指定实体类的乐观锁字段
//在调用mybatis-plus的update方法时,自动进行乐观锁实现
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
public class SysUser {
@Version
private Integer version;//乐观锁字段
}
分页插件
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加乐观锁插件,配合@Version注解指定实体类的乐观锁字段
//在调用mybatis-plus的update方法时,自动进行乐观锁实现
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//条件mp分页插件
//在调用mybaits-plus的分页查询方法时,自动拼接limit分页语句
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
@Test
public void page(){
IPage page = new Page(1,10);
page= ud.selectPage(page, null);
long total = page.getTotal();//总记录数
long pageNum = page.getCurrent();//页码
long pageSize = page.getSize();//每页记录数
List records = page.getRecords();//数据集
}
注意:一般比较少使用分页插件,需要把Page对象从Controller传递service,传递dao,属于侵入式设计。
团队是选择用MyBatis-plus的分页插件还是PageHelper分页,都可以,但是要统一。
9 常用CRUD方法
mp要求dao接口从BaseMapper父接口派生,因此我们要熟练掌握此父接口中的CRUD方法。
查询方法:
selectById(Serializable id);
selectBtachIds(Collection ids);
selectOne(Wrapper w);
selectList(Wrapper w);
selectCount(Wrapper w);
添加方法:
insert(T t);
修改方法:
updateById(T t);
update(T t,Wrapper w);
删除方法:
deleteById(Serializable id);
deleteBtachIds(Collection ids);
delete(Wrapper w);
10 IService与ServiceImpl
mp提供了service层的IService父接口,把单表操作常用的CRUD方法封装,我们也需要树莲掌握IService接口中的方法。同时提供了IService接口的实现类ServiceImpl对方法进行实现。
public interface IUserService extends IService<SysUser> {
}
@Service
public class UserService extends ServiceImpl<UserDao, SysUser> implements IUserService {
}
添加方法:
save(T t);
saveBatch(Collection<T> list);
删除方法:
removeById(Serializable id);
removeByIds(Collection ids);
修改方法:
updateById(T t);
update(Wrapper<T> updateWrapper);
update(T entity, Wrapper<T> updateWrapper);
updateBatchById(Collection<T> entityList);
查询方法:
T getById(Serializable id);
T getOne(Wrapper<T> queryWrapper);
int count(Wrapper<T> queryWrapper);
List<T> list(Wrapper<T> queryWrapper);
List<T> listByIds(Collection<? extends Serializable> idList)
11 全局配置
yml
mybatis-plus:
global-config:
db-config:
select-strategy: not_empty
mapper-locations: classpath:mapper/*/*.xml
12 逆向工程
使用easycode代码生成插件,不用mp提供的代码生成工具。