MyBatis-Plus 是一个基于 MyBatis 的增强工具,旨在简化开发,提高效率。它在 MyBatis 的基础上进行扩展,只做增强不做改变,不会对现有的 MyBatis 构架产生任何影响。
特性和优势
无侵入性:MyBatis-Plus 在 MyBatis 的基础上进行扩展,只做增强不做改变,引入 MyBatis-Plus 不会对现有的 MyBatis 构架产生任何影响。
依赖少:仅仅依赖 MyBatis 以及 MyBatis-Spring。
性能损耗小:启动即会自动注入基本 CRUD,性能基本无损耗。
通用 CRUD 操作:内置通用 Mapper、通用 Service,仅需少量配置即可实现单表大部分 CRUD 操作。
多种主键策略:支持多达 4 种主键策略(内含分布式唯一 ID 生成器),可自由配置。
支持 ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作。
代码生成:采用代码或者 Maven 插件可快速生成 Mapper、Model、Service、Controller 层代码。
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作。
内置性能分析插件:可输出 SQL 语句及其执行时间,建议开发测试时启用。
内置全局拦截插件:提供全表 delete、update 操作智能分析阻断,预防误操作。
1.创建spingboot工程导入依赖
com.baomidou mybatis-plus-spring-boot3-starter 3.5.10.1
2.修改配置文件
#数据源 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/day1216 spring.datasource.username=root spring.datasource.password=123456 #日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3.创建实体类
@Data @TableName(value = "user")//如果类名与表名不同,使用该主机表示对应的表名 public class User { @TableId(value = "id")//该属性为主键列 private Integer id; @TableField(value = "name")//普通属性与列名不一致时 private String name; private Integer age; private String email; }
创建mapper接口
@Mapper//为该接口生成代理对象 public interface UserMapper extends BaseMapper{ }
测试
@SpringBootTest class DemoMp01ApplicationTests { @Autowired private UserMapper userMapper; @Test void contextLoads() { User user = userMapper.selectById(1); System.out.println(user); } }
@TableId(value = "id",type = IdType.ASSIGN_ID)
IdType.AUTO
:使用数据库自增 ID 作为主键。IdType.NONE
:无特定生成策略,如果全局配置中有 IdType 相关的配置,则会跟随全局配置。IdType.INPUT
:在插入数据前,由用户自行设置主键值。IdType.ASSIGN_ID(默认)
:自动分配ID
,适用于Long
、Integer
、String
类型的主键。默认使用雪花算法通过IdentifierGenerator
的nextId
实现。@since 3.3.0
- 分布式集群项目
IdType.ASSIGN_UUID
:自动分配UUID
,适用于String
类型的主键。默认实现为IdentifierGenerator
的nextUUID
方法。@since 3.3.0
- 分布式 要求id必须是varchar类型
雪花算法(Snowflake Algorithm)是一种在分布式系统中生成唯一ID的方法
雪花算法的优点包括:
在高并发的分布式系统中,能够保证ID的唯一性。
基于时间戳,ID基本上是有序递增的。
不依赖于第三方库或中间件,减少了系统复杂性。
生成ID的效率非常高。
update user set deleted=1 where id = 1 and deleted=0
select id,name,deleted from user where deleted=0
1.在数据库中增加一列逻辑列
2.创建实体类时,增加该列属性
3.在属性上加@TableLogic,表示是逻辑删除列
//批量删除 Listids=new ArrayList<>(); ids.add(1); ids.add(2); ids.add(3); ids.add(4); userMapper.deleteBatchIds(ids);
1.在数据库里添加 修改时间列update_time,添加时间列create_time
2.修改实体类
@TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; @TableLogic//逻辑删除列 @TableField(fill = FieldFill.INSERT) private Integer deleted;
3.实现MetaObjectHandler
@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); this.strictInsertFill(metaObject, "deleted", Integer.class,0); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } }
@Test public void testFind(){ //Wrapper:mp把添加封装成该接口 查询条件 QueryWrapperqueryWrapper=new QueryWrapper<>(); queryWrapper.like("name", "小"); //or,不使用默认and queryWrapper.or(); //>= queryWrapper.ge("age",19); List list = userMapper.selectList(queryWrapper); System.out.println(list); }
分页配置类
import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { /** * 添加分页插件 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加 // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType return interceptor; } }
加依赖,版本与mybatis-plus对应
com.baomidou mybatis-plus-jsqlparser 3.5.10.1
测试
@Test public void testPage(){ // P page,分页对象 // @Param("ew") WrapperqueryWrapper 条件对象 IPage page=new Page<>(2,3); userMapper.selectPage(page,null); System.out.println("总条数"+page.getTotal()); System.out.println("总页码"+page.getPages()); System.out.println("当前页的记录"+page.getRecords()); }
private Integer did; //部门对象,如果属性在数据库中不存在应该忽略该属性 @TableField(exist = false) private Dept dept;
@Data @TableName(value = "tbl_dept") @AllArgsConstructor @NoArgsConstructor public class Dept { @TableId private Integer id; @TableField(value = "dept_name") private String deptName; @TableField(value = "dept_loc") private String loc; }
public PagefindAll(Page page, @Param("ew") Wrapper queryWrapper);
UserMapper.xml
测试
@Test public void testPage2(){ Pagepage=new Page<>(2,3); QueryWrapper queryWrapper=new QueryWrapper<>(); // queryWrapper.ge("age",20); userMapper.findAll(page,queryWrapper); System.out.println("总条数"+page.getTotal()); System.out.println("总页数"+page.getPages()); System.out.println("当前页的记录"+page.getRecords()); }