扩展功能
代码生成
在使用MybatisPlus以后,基础的Mapper、Service、PO代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成PO、Mapper、Service等相关代码。只不过代码生成器同样要编码使用,也很麻烦。
这里推荐大家使用一款MybatisPlus的插件,它可以基于图形化界面完成MybatisPlus的代码生成,非常简单。
安装插件
在Idea的plugins市场中搜索并安装MyBatisPlus插件:
然后重启你的Idea即可使用。
使用
刚好数据库中还有一张address表尚未生成对应的实体和mapper等基础代码。我们利用插件生成一下。
首先需要配置数据库地址,在Idea顶部菜单中,找到other,选择Config Database:
在弹出的窗口中填写数据库连接的基本信息:
点击OK保存。
然后再次点击Idea顶部菜单中的other,然后选择Code Generator:
在弹出的表单中填写信息:
最终,代码自动生成到指定的位置了:
静态工具
有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能:
示例:
@Test void testDbGet() { User user = Db.getById(1L, User.class); System.out.println(user); } @Test void testDbList() { // 利用Db实现复杂条件查询 List<User> list = Db.lambdaQuery(User.class) .like(User::getUsername, "o") .ge(User::getBalance, 1000) .list(); list.forEach(System.out::println); } @Test void testDbUpdate() { Db.lambdaUpdate(User.class) .set(User::getBalance, 2000) .eq(User::getUsername, "Rose"); }
需求:改造根据id用户查询的接口,查询用户的同时返回用户收货地址列表
首先,我们要添加一个收货地址的VO对象:
package com.onenewcode.mpdemo.domain.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(description = "收货地址VO") public class AddressVO{ @ApiModelProperty("id") private Long id; @ApiModelProperty("用户ID") private Long userId; @ApiModelProperty("省") private String province; @ApiModelProperty("市") private String city; @ApiModelProperty("县/区") private String town; @ApiModelProperty("手机") private String mobile; @ApiModelProperty("详细地址") private String street; @ApiModelProperty("联系人") private String contact; @ApiModelProperty("是否是默认 1默认 0否") private Boolean isDefault; @ApiModelProperty("备注") private String notes; }
然后,改造原来的UserVO,添加一个地址属性:
接下来,修改UserController中根据id查询用户的业务接口:
@GetMapping("/{id}") @ApiOperation("根据id查询用户") public UserVO queryUserById(@PathVariable("id") Long userId){ // 基于自定义service方法查询 return userService.queryUserAndAddressById(userId); }
由于查询业务复杂,所以要在service层来实现。首先在IUserService中定义方法:
package com.onenewcode.mpdemo.service; import com.baomidou.mybatisplus.extension.service.IService; import com.onenewcode.mpdemo.domain.po.User; import com.onenewcode.mpdemo.domain.vo.UserVO; public interface UserService extends IService<User> { void deduct(Long id, Integer money); UserVO queryUserAndAddressById(Long userId); }
然后,在UserServiceImpl中实现该方法:
@Override public UserVO queryUserAndAddressById(Long userId) { // 1.查询用户 User user = getById(userId); if (user == null) { return null; } // 2.查询收货地址 List<Address> addresses = Db.lambdaQuery(Address.class) .eq(Address::getUserId, userId) .list(); // 3.处理vo UserVO userVO = BeanUtil.copyProperties(user, UserVO.class); userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class)); return userVO; }
在查询地址时,我们采用了Db的静态方法,因此避免了注入AddressService,减少了循环依赖的风险。
逻辑删除
对于一些比较重要的数据,我们往往会采用逻辑删除的方案,即:
- 在表中添加一个字段标记数据是否被删除
- 当删除数据时把标记置为true
- 查询时过滤掉标记为true的数据
一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。
为了解决这个问题,MybatisPlus就添加了对逻辑删除的支持。
注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。
例如,我们给address表添加一个逻辑删除字段:
alter table address add deleted bit default b'0' null comment '逻辑删除';
然后给Address实体添加deleted字段:
MyBatis-Plus 实战教程三 拓展插件(二)https://developer.aliyun.com/article/1391874