Mybatis-Plus CRUD
一、引入依赖
<!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1</version></dependency>
二、在application.properties 添加对MySQL数据库相关配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8spring.datasource.username=rootspring.datasource.password=root
三、启动类上添加@MapperScan注解,对Mapper文件夹扫描
@SpringBootApplication@MapperScan("com.XXX.mapper")public class XXXApplication { public static void main(String[] args) { SpringApplication.run(XXXApplication.class, args); }}
四、在entity包下创建实体类
@Data@TableName("user") //表名public class User { @TableId(value="id",type=IdType.AUTO) private Long id; @TableField("name") //字段名 private String name; @TableField("age") private Integer age; @TableField("email") private String email;}
Mabatis-Plus主键策略
①ASSIGN_ID 雪花算法
@TableId(type = IdType.ASSIGN_ID)
private String id;
②AUTO 自增策略
@TableId(type = IdType.AUTO)
private Long id;
五、创建mapper包并创建UserMapper接口
@Repositorypublic interface UserMapper extends BaseMapper<User> {}
Mybatis Plus的Mapper需要继承BaseMapper,接口的泛型为要操作的实体类
MybatisPlus的Service需要继承IService接口,接口的泛型为要操作的实体类
MybatisPlus的ServiceImpl需要继承ServiceImpl类,接口的泛型为对应的Mapper和实体类
六、CRUD操作
Insert 插入操作
User user = new User(); user.setName("lucy"); user.setAge(20); user.setEmail("[email protected]"); int insert = userMapper.insert(user);}
Update 更新操作
User user = new User(); user.setId(1340868235401764865L); user.setName("lucymary"); int count = userMapper.updateById(user); System.out.println(count);
Select 查询操作
通过多个id批量查询 List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); 简单的条件查询,通过map封装查询条件 注意:map中的key对应数据库中的列名。如:数据库user_id,实体类userId,这时map的key需填写user_id Map<String, Object> columnMap = new HashMap<>(); columnMap.put("name","Jack"); columnMap.put("age",20); List<User> users = userMapper.selectByMap(columnMap);
Delete 删除操作
根据id删除int result = userMapper.deleteById(5L);批量删除int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));简单的条件删除HashMap<String, Object> map = new HashMap<>();map.put("name", "Helen");map.put("age", 18);int result = userMapper.deleteByMap(map);
七、扩展功能
自动填充
①、实体上增加字段并添加自动填充注解
@TableField(fill = FieldFill.INSERT)private Date createTime; //create_time@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime; //update_time
②、实现元对象处理器接口
@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler { //mp执行添加操作,这个方法执行 @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } //mp执行修改操作,这个方法执行 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); }}
添加乐观锁
①实体类添加@version注解
@Versionprivate Integer version;
②创建MP配置文件
创建包config,创建MybatisPlusConfig.java
@Configuration@MapperScan("com.XXX.mapper") //此时可以删除主类中的 @MapperScan 扫描注解public class MybatisPlusConfig { /** * 乐观锁插件 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }}
分页查询
①在MybatisPlusConfig配置类中添加Mybatis Plus的分页插件
@Beanpublic PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor();}
②selectPage分页
Page<User> page = new Page(1,3); Page<User> userPage = userMapper.selectPage(page, null); //返回对象得到分页所有数据 long pages = userPage.getPages(); //总页数 long current = userPage.getCurrent(); //当前页 List<User> records = userPage.getRecords(); //查询数据集合 long total = userPage.getTotal(); //总记录数 boolean hasNext = userPage.hasNext(); //下一页 boolean hasPrevious = userPage.hasPrevious(); //上一页 System.out.println(pages); System.out.println(current); System.out.println(records); System.out.println(total); System.out.println(hasNext); System.out.println(hasPrevious);
③selectMapsPage分页
//Page不需要泛型Page<Map<String, Object>> page = newPage<>(1, 5);Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null);List<Map<String, Object>> records = pageParam.getRecords();records.forEach(System.out::println);System.out.println(pageParam.getCurrent());System.out.println(pageParam.getPages());System.out.println(pageParam.getSize());System.out.println(pageParam.getTotal());System.out.println(pageParam.hasNext());System.out.println(pageParam.hasPrevious());
实现逻辑删除
①数据库添加deleted字段
ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false
②实体类添加逻辑删除字段deleted并加上@TableLogic注解
@TableLogicprivate Integer deleted;
③application.properties默认配置,可修改可不修改,默认1被删除,0未被删除
mybatis-plus.global-config.db-config.logic-delete-value=1mybatis-plus.global-config.db-config.logic-not-delete-value=0
④配置完成之后再进行删除操作,被视为对deleted字段的update操作,并且查询操作会自动添加逻辑删除字段的判断
条件构造器
Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件 QueryWrapper : 查询条件封装 UpdateWrapper : Update 条件封装 AbstractLambdaWrapper : 使用Lambda 语法 LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper LambdaUpdateWrapper : Lambda 更新封装Wrapper
①ge、gt、le、lt、isNull、isNotNull
QueryWrapper<User> queryWrapper = newQueryWrapper<>();queryWrapper .isNull("name") .ge("age", 12) .isNotNull("email"); int result = userMapper.delete(queryWrapper);
②eq、ne
//注:selectOne只能返回一条实体记录,多了会抛出异常QueryWrapper<User> queryWrapper = newQueryWrapper<>();queryWrapper.eq("name", "Tom");Useruser = userMapper.selectOne(queryWrapper);
③between、notBetween(包含大小边界)
QueryWrapper<User> queryWrapper = newQueryWrapper<>();queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper); //返回数据数量
④like、notLike、likeLeft、likeRight
QueryWrapper<User> queryWrapper = newQueryWrapper<>();queryWrapper .select("name", "age") .like("name", "e") .likeRight("email", "5");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表maps.forEach(System.out::println);
⑤orderBy、orderByDesc、orderByAsc
QueryWrapper<User>queryWrapper = newQueryWrapper<>();queryWrapper.orderByDesc("age", "id");List<User>users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
备注:
GE:Greater or Equal 大于等于;
GT:Greater Than 大于
LE: Less or Equal 小于等于
LT: Less Than 小于
EQ:Equal 等于
NQ:Not Equal 不等于
注:users.forEach(System.out::println);等价于users.forEach(x -> { System.out.println(x); });
//selectMaps的返回结果只显示wrapper里包含的字段,不显示其他字段,并且可以返回实体类和数据库里//不存在的字段,例如avg_salary userqueryWrapper .select("department_id","AVG(salary) AS avg_salary","avg(age) avg_age") .groupBy("department_id") .having("sum(age) < {0}" , 60); List<Map<String , Object>> mapList =userMapper.selectMaps(userQueryWrapper);
常用注解
【@TableName 】 @TableName 用于定义表名注: 常用属性: value 用于定义表名【@TableId】 @TableId 用于定义表的主键注: 常用属性: value 用于定义主键字段名 type 用于定义主键类型(主键策略 IdType) 主键策略: IdType.AUTO 主键自增,系统分配,不需要手动输入 IdType.NONE 未设置主键 IdType.INPUT 需要自己输入 主键值。 IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。 IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。【@TableField】 @TableField 用于定义表的非主键字段。注: 常用属性: value 用于定义非主键字段名 exist 用于指明是否为数据表的字段, true 表示是,false 为不是。 fill 用于指定字段填充策略(FieldFill)。 字段填充策略:(一般用于填充 创建时间、修改时间等字段) FieldFill.DEFAULT 默认不填充 FieldFill.INSERT 插入时填充 FieldFill.UPDATE 更新时填充 FieldFill.INSERT_UPDATE 插入、更新时填充。【@TableLogic】 @TableLogic 用于定义表的字段进行逻辑删除(非物理删除)注: 常用属性: value 用于定义未删除时字段的值 delval 用于定义删除时字段的值 【@Version】 @Version 用于字段实现乐观锁
参考资料 尚硅谷–尚医通项目–Day01Mybatis-Plus.doc
还有一篇博客https://www.cnblogs.com/l-y-h/p/12859477.html