文章目录
- 1. 简单使用
- 2. 条件构造器 —— 针对于复杂查询
- 3. 自定义SQL
- 4. IService
- 4.1 基本接口方法
- 4.1.1 新增
- 4.1.2 删除
- 4.1.3 修改
- 4.1.4 查找
- 4.2 开发基础业务接口
- 4.3 开发复杂业务接口
- 4.4 Lambda方法
- 4.5 批量新增
- 5. 代码生成
- 6. 分页功能
- 6.1 分页插件基本使用
- 6.1 通用分页实体
1. 简单使用
public interface UserMapper extends BaseMapper<User> {}class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();user.setUsername("xiaowang");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteUser() {userMapper.deleteById(5L);}
}
2. 条件构造器 —— 针对于复杂查询
@Test
public void testQueryWrapper(){// select id, username, info, balance from user where username like %o% and balance = 1000;QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}@Test
public void testUpdateByQueryWrapper(){// update user set balance = 2000 where username = "jack";User user = new User();user.setBalance(2000);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");userMapper.update(user, wrapper);
}@Test
public void testUpdateWrapper(){// update user set balance = balance - 200 where id in (1,2,4);List<Long> ids = Arrays.asList(1L, 2L, 4L);UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id", ids);userMapper.update(null, wrapper);
}
lambdaQueryWrapper解决上述testQueryWrapper硬编码问题
@Test
public void testLambdaQueryWrapper(){// select id, username, info, balance from user where username like %o% and balance = 1000;LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
条件构造器的用法:
- QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的where条件部分
- UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
- 尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码
3. 自定义SQL
4. IService
4.1 基本接口方法
IService底层操作数据库,用的还是mapper
4.1.1 新增
4.1.2 删除
4.1.3 修改
4.1.4 查找
4.2 开发基础业务接口
IUserService.java
public interface IUserService extends IService<User> {
}
UserServiceImpl.java
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
@SpringBootTest
public class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSaveUser() {User user = new User();user.setUsername("LiLei");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}@Testvoid testQueryByIds() {List<User> users = userService.listByIds(Arrays.asList(1L, 2L, 3L, 4L));users.forEach(System.out::println);}
}
@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {// final配合@RequiredArgsConstructor,可以通过构造函数注入private final IUserService userService;@ApiOperation("用户新增接口")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){// 使用BeanUtil,将UserFormDTO对象的属性拷贝到User.classUser user = BeanUtil.copyProperties(userDTO, User.class);userService.save(user);}@ApiOperation("删除用户接口")@DeleteMapping("{id}")// @PathVariable用于RESTFUL风格,从路径中获取参数public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("根据id查询用户接口")@GetMapping("{id}")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){User user = userService.getById(id);return BeanUtil.copyProperties(user, UserVO.class);}@ApiOperation("根据id批量查询用户接口")@GetMapping// @RequestParam用于从路径中获取参数,比如ids=1,2,4public List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){List<User> users = userService.listByIds(ids);// List<PO> -> List<VO>return BeanUtil.copyToList(users, UserVO.class);}
}
4.3 开发复杂业务接口
Controller
@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {@ApiOperation("扣减用户余额接口")@PutMapping("/{id}/deduction/{money}")public void deductMoneyById(@ApiParam("用户id") @PathVariable("id") Long id,@ApiParam("用户money") @PathVariable("money") Integer money){userService.deductBalance(id, money);}
}
service
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {private final UserMapper userMapper;@Overridepublic void deductBalance(Long id, Long money) {User user = getById(id);if(user == null || user.getStatus() == 2){throw new RuntimeException("用户状态异常!");}if(user.getBalance() < money){throw new RuntimeException("用户余额不足!");}userMapper.deductBalance(id, money);}
}
mapper
public interface UserMapper extends BaseMapper<User> {void updateBalanceByIds(@Param(Constants.WRAPPER) UpdateWrapper<User> wrapper, @Param("amount") int amount);@Update("UPDATE user SET balance = balance - #{money} WHERE id = #{id}")void deductBalance(@Param("id") Long id, @Param("money") Long money);}
4.4 Lambda方法
controller
@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {// final配合@RequiredArgsConstructor,可以通过构造函数注入private final IUserService userService;@ApiOperation("根据复杂条件查询用户接口")@GetMapping("/list")public List<UserVO> queryUsers(UserQuery query){List<User> users = userService.queryUsers(query.getName(), query.getStatus(), query.getMinBalance(), query.getMaxBalance());return BeanUtil.copyToList(users, UserVO.class);}
}
service
public interface IUserService extends IService<User> {List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {// select * from user where name = ? ans status = ? and balance >= minBalance and balance <= maxBalance;return lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).gt(minBalance != null, User::getBalance, minBalance).lt(maxBalance != null, User::getBalance, maxBalance).list();}
}
4.5 批量新增
5. 代码生成
MyBatisPlus使用的过程如下:
这些代码都比较固定,只是类名不同,我们可以用插件自动生成这些比较固定的代码
配置数据库信息
配置代码生成信息
6. 分页功能
6.1 分页插件基本使用
MyBatisPlus内置的分页插件如下:
首先,需要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件
@Configuration
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 1 初始化核心插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 2 添加分页插件PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);pageInterceptor.setMaxLimit(1000L); // 设置分页上限interceptor.addInnerInterceptor(pageInterceptor);return interceptor;}
}
分页对象
引入依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>3.5.3.1</version>
</dependency>
@Test
public void testPageQuery(){// 创建Page对象,设置分页参数int pageNo = 2, pageSize = 2;Page<User> page = Page.of(pageNo, pageSize);// 排序条件page.addOrder(new OrderItem("balance", true));page.addOrder(new OrderItem("id", true));// 分页查询Page<User> p = userService.page(page);long total = p.getTotal(); // 数据总条数long pages = p.getPages(); // 总页数List<User> users = p.getRecords(); // 第pageNo页数据,pageSize条users.forEach(System.out::println);
}
6.1 通用分页实体
统一的分页查询条件,包括页码、页大小、排序方式、是否升序
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {private Integer pageNo;private Integer pageSize;private String sortBy;private Boolean isAsc;
}
用户条件查询实体
@Data
@ApiModel(description = "用户条件查询实体")
public class UserQuery extends PageQuery{@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}
返回实体PageDTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<V> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("结果集合")private List<V> list;
}
controller
@ApiOperation("根据复杂条件分页查询用户接口")
@GetMapping("/page")
public PageDTO<UserVO> queryUsersPage(UserQuery query){return userService.queryUsersPage(query);
}
service
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {private final UserMapper userMapper;@Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();// 分页参数Page<User> page = Page.of(query.getPageNo(), query.getPageSize());// 排序条件if(StrUtil.isNotBlank(query.getSortBy())){page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));}else{// 排序条件为空,按更新时间排序page.addOrder(new OrderItem("update_time", false));}Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);PageDTO<UserVO> dto = new PageDTO<>();dto.setTotal(p.getTotal());dto.setPages(p.getPages());List<User> records = p.getRecords();// 查询结果为空,PageDTO的结果设置为空集合if(CollUtil.isEmpty(records)){dto.setList(Collections.emptyList());return dto;}// 工具包直接将List<User>转为List<UserVO>dto.setList(BeanUtil.copyToList(records, UserVO.class));return dto;}
}