MyBatisPlus基础(2)
MyBatisPlus的CRUD 接口
插入操作
-
@RunWith(SpringRunner.class) @SpringBootTest public class CRUDTests { @Autowired private UserMapper userMapper; @Test public void testInsert(){ User user = new User(); user.setName("Helen"); user.setAge(18); user.setEmail("55317332@qq.com"); int result = userMapper.insert(user); System.out.println(result); //影响的行数 System.out.println(user); //id自动回填 } }
-
数据库插入id值默认为:全局唯一id
主键策略
ID_WORKER
- MyBatis-Plus默认的主键策略是:ID_WORKER 全局唯一ID
- **分布式系统唯一ID生成方案汇总:**https://www.cnblogs.com/haoxinyue/p/5208136.html
自增策略
-
要想主键自增需要配置如下主键策略
-
- 需要在创建数据表的时候设置主键自增
- 实体字段中配置 @TableId(type = IdType.AUTO)
-
@TableId(type = IdType.AUTO) private Long id;
-
要想影响所有实体的配置,可以设置全局主键配置
-
#全局设置主键生成策略 mybatis-plus.global-config.db-config.id-type=auto
-
其它主键策略:分析 IdType 源码可知
-
@Getter public enum IdType { /** * 数据库ID自增 */ AUTO(0), /** * 该类型为未设置主键类型 */ NONE(1), /** * 用户输入ID * 该类型可以通过自己注册自动填充插件进行填充 */ INPUT(2), /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */ /** * 全局唯一ID (idWorker) */ ID_WORKER(3), /** * 全局唯一ID (UUID) */ UUID(4), /** * 字符串全局唯一ID (idWorker 的字符串表示) */ ID_WORKER_STR(5); private int key; IdType(int key) { this.key = key; } }
update
-
根据Id更新操作
-
update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?
-
@Test public void testUpdateById(){ User user = new User(); user.setId(1L); user.setAge(28); int result = userMapper.updateById(user); System.out.println(result); }
自动填充
-
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等
-
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:
-
数据库表中添加自动填充字段
-
在User表中添加datetime类型的新的字段 create_time、update_time
-
实体上添加注解
-
@Data public class User { ...... @TableField(fill = FieldFill.INSERT) private Date createTime; //@TableField(fill = FieldFill.UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
-
实现元对象处理器接口
-
package com.atguigu.mybatisplus.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class); @Override public void insertFill(MetaObject metaObject) { LOGGER.info("start insert fill ...."); this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { LOGGER.info("start update fill ...."); this.setFieldValByName("updateTime", new Date(), metaObject); } }
select
-
根据id查询记录
-
@Test public void testSelectById(){ User user = userMapper.selectById(1L); System.out.println(user); }
-
通过多个id批量查询
-
@Test public void testSelectBatchIds(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); }
-
简单的条件查询
-
@Test public void testSelectByMap(){ HashMap<String, Object> map = new HashMap<>(); map.put("name", "Helen"); map.put("age", 18); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
分页
-
创建配置类
-
/** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
-
测试selectPage分页
-
@Test public void testSelectPage() { Page<User> page = new Page<>(1,5); userMapper.selectPage(page, null); page.getRecords().forEach(System.out::println); System.out.println(page.getCurrent()); System.out.println(page.getPages()); System.out.println(page.getSize()); System.out.println(page.getTotal()); System.out.println(page.hasNext()); System.out.println(page.hasPrevious()); }
-
测试selectMapsPage分页:结果集是Map
-
@Test public void testSelectMapsPage() { Page<User> page = new Page<>(1, 5); IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null); //注意:此行必须使用 mapIPage 获取记录列表,否则会有数据类型转换错误 mapIPage.getRecords().forEach(System.out::println); System.out.println(page.getCurrent()); System.out.println(page.getPages()); System.out.println(page.getSize()); System.out.println(page.getTotal()); System.out.println(page.hasNext()); System.out.println(page.hasPrevious()); }
delete
-
根据id删除记录
-
@Test public void testDeleteById(){ int result = userMapper.deleteById(8L); System.out.println(result); }
-
批量删除
-
@Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); System.out.println(result); }
-
简单的条件查询删除
-
@Test public void testDeleteByMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name", "Helen"); map.put("age", 18); int result = userMapper.deleteByMap(map); System.out.println(result); }
逻辑删除
-
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
-
逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
-
数据库中添加 deleted字段
-
ALTER TABLE `user` ADD COLUMN `deleted` boolean
-
实体类添加deleted *字段*
-
@TableLogic @TableField(fill = FieldFill.INSERT) private Integer deleted;
-
元对象处理器接口添加deleted的insert默认值
-
@Override public void insertFill(MetaObject metaObject) { ...... this.setFieldValByName("deleted", 0, metaObject); }
-
application.properties 加入配置
-
mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
-
在 MybatisPlusConfig 中注册 Bean
-
@Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
-
测试逻辑删除
-
/** * 测试 逻辑删除 */ @Test public void testLogicDelete() { int result = userMapper.deleteById(1L); System.out.println(result); }
-
测试逻辑删除后的查询
-
/** * 测试 逻辑删除后的查询: * 不包括被逻辑删除的记录 */ @Test public void testLogicDeleteSelect() { User user = new User(); List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }