概述MyBatis-Plus
MyBatis-Plus简称 MP是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开
发、提高效率而生
官方文档:https://baomidou.com/
Hello MP
添加依赖
<!-- 如果没有整合SpringBoot,则需要引入这个依赖,通过注解进行开发,并手工添加所需要的配置
-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.3.1</version>
</dependency>
使用MP可以有对应的映射文件,也可以没有映射文件
- 如果需要对sql语句进行优化,则可以添加映射元文件;如果没有需要sql语句优化,则省略
mapper.xml文件 -
- 在 MyBatis 的基础上只做增强不做改变。过去MyBatis的用法在MP中仍旧有效
- 具体执行的sql语句可以由MP生成
定义实体类 - @TableName添加在实体类上,用于标识实体类所对应的表名注解,标识实体类对应的表
- @TableId是主键注解,用于在属性上标识对应的注解
-
- value用于指定对应的主键字段名,如果不指定,则和属性名称一致
-
- type是IdType枚举类型,用于指定主键生成策略
-
-
- AUTO数据库ID自增
-
-
-
- NONE意思是无状态,该类型为未设置主键类型。注解里等于跟随全局,全局里约等于
INPUT
- NONE意思是无状态,该类型为未设置主键类型。注解里等于跟随全局,全局里约等于
-
-
-
- INPUT是在执行insert操作之前自行 set 主键值
-
-
-
- ASSIGN_ID采用雪花算法生成主键值,应该是string类型
-
-
-
- ASSIGN_UUID采用UUID生成字符串值充当主键
-
-
- 不建议使用的三种算法:ID_WORKER分布式全局唯一 ID 长整型类型、UUID是32位UUID字
符串、ID_WORKER_STR是分布式全局唯一 ID 字符串类型
- 不建议使用的三种算法:ID_WORKER分布式全局唯一 ID 长整型类型、UUID是32位UUID字
- @TableField属性上的针对字段的注解,用于非主键类型的属性
-
- value用于定义当前属性对应的数据库字段名
-
- exist标识该属性是否为数据库表字段,因为如果不加配置则默认属性都是有同名的对应字段
-
- jdbcType用于声明对应的JDBC 类型,该默认值不代表会按照该值生效
-
- numericScale用于指定小数点后保留的位数
@Data
@TableName("tb_users")
public class User implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
@TableField(exist = false)
private String repassword;
private String email;
}
添加mapper接口,注意使用MP时mapper.xml可有可无
- MP提供了一个父接口BaseMapper,其中包含了常见的CRUD的方法
public interface UserMapper extends BaseMapper<User> {
}
使用自动扫描进行mapper接口的注册,在主类上添加自动扫描注解即可
@MapperScan("com.yan.dao")
@SpringBootApplication
public class DemoApplication
MP针对业务层提供了IService接口,和对应的实现类ServiceImpl,在具体开发中可以通过继承IService
接口来定义业务接口
public interface IUserServ extends IService<User> {
}
定义业务实现类
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
@Service
public class UserServImpl extends ServiceImpl<UserMapper, User> implements
IUserServ {
}
在控制台上打印输入所执行的sql语句
mybatis-plus.configuration.logimpl=org.apache.ibatis.logging.stdout.StdOutImpl
IService业务接口
一般使用步骤:
定义特定接口,这个接口用于定义特殊的方法,一般通用方法从MP提供的IService接口种继承
public interface UserService extends IService<User> {
}
定义具体的业务实现类,通用方法的定义是MP提供的父类ServiceImpl,泛型1是当前业务类需要使用的
Mapper接口,泛型2是对应的实体类
public class UserServiceImpl extends ServiceImpl ServiceImpl<UserMapper,
User> implements UserService{
}
接口定义
public interface IService<T> {
//插入一条记录(选择字段,策略插入),非空属性参与生成sql语句,否则不出现。default才
能生效
default boolean save(T entity) {
return SqlHelper.retBool(getBaseMapper().insert(entity));
}
//插入批量,一次性提供1000条sql语句,使用注解设置所有的异常都执行回滚
@Transactional(rollbackFor = Exception.class)
default boolean saveBatch(Collection<T> entityList) {
return saveBatch(entityList, DEFAULT_BATCH_SIZE);
}
//根据ID列执行删除 DELETE FROM tb_users WHERE id=?
default boolean removeById(Serializable id) {
return SqlHelper.retBool(getBaseMapper().deleteById(id));
}
//根据实体的ID删除,其他的属性无效 DELETE FROM tb_users WHERE id=?
default boolean removeById(T entity) {
return SqlHelper.retBool(getBaseMapper().deleteById(entity));
}
//根据columnMap条件执行删除记录,其中的key为列名称,value标识条件为列名称=value
值,所有的key/value对是and连接 DELETE FROM tb_users WHERE role_id = ? AND sex
= ? AND id = ?
default boolean removeByMap(Map<String, Object> columnMap) {
Assert.notEmpty(columnMap, "error: columnMap must not be empty");
return SqlHelper.retBool(getBaseMapper().deleteByMap(columnMap));
}
//根据实体对象的查询条件执行删除记录,删除条件封装在QueryWrapper对象中
default boolean remove(Wrapper<T> queryWrapper) {
return SqlHelper.retBool(getBaseMapper().delete(queryWrapper));
}
基本用法:
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.eq("sex",true).between("id",10,30).or().like("username","zhang");
boolean removed = userService.remove(wrapper);
System.out.println(removed);
所执行的sql语句:
==> Preparing: DELETE FROM tb_users WHERE (sex = ? AND id BETWEEN ? AND ?
OR username LIKE ?)
==> Parameters: true(Boolean), 10(Integer), 30(Integer), %zhang%(String)
<== Updates: 0
//批量删除,参数是要删除数据的id所构成的集合
default boolean removeByIds(Collection<?> list) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
}
//根据ID选择修改实体类中的所有非空属性,如果属性为空则不参与修改,值仍旧为原来的数据
default boolean updateById(T entity) {
return SqlHelper.retBool(getBaseMapper().updateById(entity));
}
基础用法:
User tmp=new User();
tmp.setId(2L);
tmp.setUsername("王胡子");
boolean res = userService.updateById(tmp);
所执行的sql语句:
==> Preparing: UPDATE tb_users SET username=? WHERE id=?
==> Parameters: 王胡子(String), 2(Long)
<== Updates: 1
//具体的修改是通过UpdateWrapper对象进行封装,更新记录,需要设置sqlset
*
* @param updateWrapper 实体对象封装操作类 {
@link
com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
*/
default boolean update(Wrapper<T> updateWrapper) {
return update(null, updateWrapper);
}
基础用法:
User tmp=new User();
tmp.setId(2L);
tmp.setUsername("王胡子");
boolean res = userService.updateById(tmp);
所执行的sql语句:
==> Preparing: UPDATE tb_users SET username=? WHERE id=?
==> Parameters: 王胡子(String), 2(Long)
<== Updates: 1
基础用法:
UpdateWrapper<User> wrapper=new UpdateWrapper<>();
//set用于定义需要修改的列和对应的新值
wrapper.set("username","贺老总");
wrapper.set("password","666666");
//和QueryWrapper一样定义对应的修改条件
wrapper.between("id",10,20);
boolean res = userService.update(wrapper);
所执行的sql语句:
==> Preparing: UPDATE tb_users SET username=?,password=? WHERE (id BETWEEN
? AND ?)
==> Parameters: 贺老总(String), 666666(String), 10(Integer), 20(Integer)
<== Updates: 0
//一组实体对象的集合根据每个对象的ID批量更新
@Transactional(rollbackFor = Exception.class)
default boolean updateBatchById(Collection<T> entityList) {
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
}
//根据参数entity的id属性值判断执行save或者update操作。TableId 注解存在更新记录,
否插入一条记录
boolean saveOrUpdate(T entity