mybatis-plus在实际开发中的应用

文章目录

  • 前言
  • 一、实体类的注解
  • 二、Req查询条件
  • 三、Controller接口
  • 四、Service接口
  • 五、Service接口实现类
  • 六、Mapper接口
  • 七、枚举的使用
  • 总结


前言

最近的项目是使用mybatis-plus作为持久层框架,前面也记录过mybatis-plus的基本使用,此次记录一下本次项目中的一些使用要点


一、实体类的注解

基本的导入依赖和代码自动生成器,可以去看以前的文章,本次不再赘述。
以项目中的一个实体类为例

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;import java.util.Date;import com.baomidou.mybatisplus.annotation.TableId;import java.io.Serializable;
import java.util.List;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;@Data
@EqualsAndHashCode(callSuper = false)
@TableName("co_activity")
@ApiModel(value = "Activity对象", description = "绿色活动")
public class Activity implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;@ApiModelProperty(value = "关联EMP活动ID")private String empId;@ApiModelProperty(value = "活动小图")private String image;@ApiModelProperty(value = "活动名称")private String name;@ApiModelProperty(value = "活动副标题")private String subTitle;@ApiModelProperty(value = "活动日期")@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")private Date activityDate;@ApiModelProperty(value = "活动城市")private String city;@ApiModelProperty(value = "排序")private Integer sort;@ApiModelProperty(value = "签到奖励能量")private Integer sigInEnergy;@ApiModelProperty(value = "预约奖励能量")private Integer reservationEnergy;@ApiModelProperty(value = "关联绿色场景")private String sceneRuleId;@ApiModelProperty(value = "推荐(1:是,0:否)")private Integer recommend;@ApiModelProperty(value = "删除标记")private Integer delFlag;}

实体类上mybatis-plus的注解有两个,

  • @TableName(“co_activity”)指定表名
  • @TableId(value = “id”, type = IdType.ASSIGN_ID) 指定主键

实体类还应该实现序列化接口,方便后续对数据进行流操作
其余的注解是lombok注解和swagger文档注解

二、Req查询条件

req查询条件是mybatis-plus封装自己为我们封装的查询条件,需要我们继承一个BaseRequest< T >类(其中T是我们的实体类),也支持我们对其进行自定义修改加入我们需要的查询条件,默认的查询条件如下:
在这里插入图片描述
在这里插入图片描述
mybatis-plus帮我们自动实现了分页的查询条件,当然在实际的开发中只有一个分页条件是远远不够的,下边是我的自定义查询条件:
在这里插入图片描述

三、Controller接口

这里我以一个条件查询的方法演示

@Api(tags = "绿色活动")
@RestController
@RequestMapping("/activity")
@Slf4j
public class ActivityController {@Resourceprivate IActivityService iActivityService;@ApiOperation("分页查询")@PostMapping("/admin/page")public Result page(@RequestBody ActivityReq req) {log.info("分页查询活动列表:{}", JSON.toJSONString(req));Map<String, Object> page = iActivityService.pageQuery(req);log.info("分页查询活动列表到的数据:{}", JSON.toJSONString(page));return Result.ok(page);}
}    

也就是说,我们后端接口接收的查询条件就是req,它以json的数据格式进行传输
传入的数据格式如下

{"id":"","empId":"","activityName":"","city":"","sceneRuleId":""
}

四、Service接口

service接口需要我们去实现一个mybatis-plus的接口IService< T >

public interface IActivityService extends IService<Activity> {/*** 分页查询** @param req 查询条件* @return map*/Map<String, Object> pageQuery(ActivityReq req);
}

其中实现了一些基础的CRUD方法,如果只是简单不带业务逻辑的基本功能,mybatis-plus都给我们进行了封装,拿来即用,此处不再展示

五、Service接口实现类

这里除了我们需要去实现一个我们自定义的接口外,还需要我们去继承一个mybatis-plus的类ServiceImpl<Mapper, Model> 代码如下:

@Service
@Slf4j
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> 
implements IActivityService {@Autowiredprivate ActivityMapper activityMapper;@Overridepublic Map<String, Object> pageQuery(ActivityReq req) {log.info("分页查询活动列表到的数据:{}", JSON.toJSONString(req));List<SceneRule> sceneRules = sceneRuleMapper.selectList(new QueryWrapper<>());Map<String, String> sceneRuleMap = new HashMap<>(sceneRules.size());for (SceneRule sceneRule : sceneRules) {sceneRuleMap.put(sceneRule.getId(), sceneRule.getName());}QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();/*活动id模糊查询*/queryWrapper.like(StringUtils.isNotBlank(req.getId()), "id", req.getId());/*emp活动id模糊查询*/queryWrapper.like(StringUtils.isNotBlank(req.getEmpId()), "emp_id", req.getEmpId());/*活动名称模糊查询*/queryWrapper.like(StringUtils.isNotBlank(req.getActivityName()), "name", req.getActivityName());/*城市*/CityEnum eumByCode = CityEnum.getEumByCode(req.getCityCode());if (eumByCode != null) {String city = eumByCode.getDesc();queryWrapper.eq("city", city);}/*未删除的*/queryWrapper.eq("del_flag", DelFlagEnum.NO_DEL.getCode());/*不查全国的*/queryWrapper.ne("city", CityEnum.QUANGUO.getDesc());/*场景*/queryWrapper.eq(StringUtils.isNotBlank(req.getSceneRuleId()), "scene_rule_id", req.getSceneRuleId());/*日期降序*/queryWrapper.orderByDesc("activity_date");IPage<Activity> page = baseMapper.selectPage(req.getPage(), queryWrapper);List<Activity> activityList = page.getRecords();List<String> empIds = new ArrayList<>(activityList.size());for (Activity activity : activityList) {if (StringUtils.isNotBlank(activity.getEmpId()) && !empIds.contains(activity.getEmpId())) {empIds.add(activity.getEmpId());}}List<EmpVo> empVoList = empVoList(empIds);Map<String, EmpVo> empVoMap = new HashMap<>(empVoList.size());for (EmpVo empVo : empVoList) {empVoMap.put(empVo.getEventId(), empVo);}/*将结果封装为VO返回前端*/List<ActivityVo> list = page.getRecords().stream().map(activity -> {ActivityVo vo = new ActivityVo();BeanUtils.copyProperties(activity, vo);if (sceneRuleMap.get(activity.getSceneRuleId()) == null) {vo.setSceneRuleName("无");} else {vo.setSceneRuleName(sceneRuleMap.get(activity.getSceneRuleId()));}EmpVo empVo = empVoMap.get(activity.getEmpId());if (empVo != null) {String image = null;vo.setName(empVo.getTitle());vo.setSubTitle(empVo.getType());vo.setActivityDate(empVo.getHoldingEndTime());vo.setCityName(empVo.getCity());if ("0".equals(empVo.getEventScene())) {image = empVo.getAppCoverImage();} else if ("1".equals(empVo.getEventScene())) {List<String> eventImageList = empVo.getEventImageList();if (CollectionUtils.isNotEmpty(eventImageList)) {image = eventImageList.get(0);}}vo.setImage(image);}log.info("vo封装结束");return vo;}).collect(Collectors.toList());Map<String, Object> map = new HashMap<>(3);map.put("total", page.getTotal());map.put("list", list);map.put("page", page.getCurrent());return map;}
}

此处需要注意的是,我们需要使用一个StringUtils.isNotBlank(查询条件) 方法去判断我们的查询条件是否为空,不为空再进行拼接,其次这里还使用了一个stream流去处理查询出来的结果,因为mybatis-plus只支持单表查询,但是对于复杂的显示来说,我们不得不去另外一张表中取数据,所以,这里对查询结果使用stream流进行数据处理,将我们需要的数据进行处理,然后返回

六、Mapper接口

有些时候我们自带的查询方法,极有可能不满足我们的业务需求,所以我们需要使用mybatis的xml映射文件去编写sql,和mybatis基本一致,需要注意的是我们的mapper也要继承一个类BaseMapper< T > 其中封装了一些基本的持久层的CRUD方法供我们使用

@Repository
public interface ActivityMapper extends BaseMapper<Activity> {/*** 获取已经关联的empId* @return*/List<String> getEmpIds();
}

七、枚举的使用

开发规范中,不允许魔法值的出现,所以在真实的开发中需要我们使用枚举去完成一些类目的判断,下面以城市为例:

@Getter
@AllArgsConstructor
public enum CityEnum {BEIJING("110000", "北京市"),SHANGHAI("310000", "上海市"),GUANGZHOU("440100", "广州市"),SHENZHEN("440300", "深圳市"),HANGZHOU("330100", "杭州市"),FOSHAN("440600", "佛山市"),QUANGUO("000000", "全国");private String code;private String desc;public static CityEnum getEumByCode(String code) {if (code == null) {return null;}for (CityEnum type : CityEnum.values()) {if (type.getCode().equals(code)) {return type;}}return null;}
}

以上就是一个城市的枚举类

在使用的时候如下:

/*城市*/CityEnum eumByCode = CityEnum.getEumByCode(req.getCityCode());if (eumByCode != null) {String city = eumByCode.getDesc();queryWrapper.eq("city", city);}

这样就避免的魔法值的出现
常用的枚举还有逻辑删除

@Getter
@AllArgsConstructor
public enum DelFlagEnum {NO_DEL(0, "未删除"),DEL(1, "已删除");private Integer code;private String desc;
}

我们也可以在VO类中添加枚举处理,例如我们需要在活动VO中获取城市名,(假设model中是没有城市名的,只存了一个code码)

    public String setCityName() {String name = "";CityEnum eumByCode = CityEnum.getEumByCode(this.city);if (eumByCode != null) {name = eumByCode.getDesc();}return name;}

可以在VO中添加上边的代码,


总结

以上就是最近在使用mybatis-plus的一些总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/402.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git使用命令技巧

文章目录 前言查看提交用户名更改提交用户名查看文件的diff查看提交记录Git 本地分支管理查看、切换、创建和删除分支 前言 我们在使用git的时候&#xff0c;提交后会看到如下记录&#xff1a; 经常会遇到提交后&#xff0c;这个作者的名字和自己设置的名字不一致&#xff0…

Linux之CentOS 7.9部署Oracle 11g r2_p13390677_112040最终版简易安装实测验证(桌面模式)

前言&#xff1a; Linux之CentOS 7.9部署Oracle 11g r2最终版安装实测验证&#xff08;桌面模式&#xff09; 介于前段时间的Windows以及linux无桌面模式环境&#xff0c;之前的linux oracl源包因缺失会存在报错现象&#xff0c;这次主要以oracle 11gr2更新包来记录下部署方式&…

基于Springboot的在线竞拍系统(拍卖系统)

今天给大家带来了一个在线竞拍(拍卖)系统&#xff08;带设计报告&#xff09;&#xff0c;项目功能完善。 用户功能 包括沙箱支付宝支付&#xff0c;在线竞拍&#xff0c;收藏管理&#xff0c;个人资料管理&#xff0c;竞拍管理等等。 机构功能 包括&#xff0c;上传竞拍项目…

iOS App 上架流程图文教学

在上架App 之前必须先准备好开发者帐号&#xff0c;但申请开发者帐号因法兰克早在之前已经申请好了&#xff0c;故就跳过此步骤&#xff0c;直接从产生凭证到上传App开始讲起。首先&#xff0c;要将自己辛苦写好的App 送审的话&#xff0c;则要依序做完下列几件事情即可。 在开…

「轻松转换文件格式,一键修改文件的格式让文件管理更简便!」

在日常工作和生活中&#xff0c;我们经常会面临需要修改文件格式的情况。无论是转换文件为更普遍使用的格式&#xff0c;还是根据特定需求调整文件的扩展名&#xff0c;都需要一个简单而有效的文件管理工具来完成这项任务。那么&#xff0c;文件批量改名高手将会让您在文件格式…

oracle 自定义类型(type)的用法

emp表数据如下所示 定义object类型 create or replace type typeof_userinfo_row as object(user_id varchar2(50),user_name varchar2(50) )创建函数并将此类型作为返回值类型 create or replace function FUN_TEST return typeof_userinfo_row isFunctionResult typeof_use…

【k8s系列】一分钟搭建MicroK8s Dashboard

本文基于上一篇文章的内容进行Dashboard搭建&#xff0c;如果没有看过上一篇的同学请先查阅上一篇文章 k8s系列】使用MicroK8s 5分钟搭建k8s集群含踩坑经验 使用MicroK8s搭建Dashboard很简单&#xff0c;只需要在Master节点按照以下几步操作 1.启用Dashboard插件 microk8s en…

【数据可视化方案分享】电商数据分析

本文所分享的电商数据分析报表均来自奥威BI软件的电商数据分析方案&#xff01;该方案是一套包含数据采集、数据建模、数据分析报表的系统化、标准化数据分析方案&#xff0c;下载套用&#xff0c;立见效果&#xff01; 注意&#xff0c;奥威BI软件的电商数据分析方案分两类&a…

目标检测模型中的Bells and wisthles

目标检测模型中的Bells and wisthles 目标检测模型中的Bells and wisthles1. Data augmentation 数据增强2. Multi-scale Training/Testing 多尺度训练/测试3. Global Context 全局语境4. Box Refinement/Voting 预测框微调/投票法5. OHEM 在线难例挖掘6. Soft NMS 软化非极大抑…

解析Transformer基本结构与实现

目录 基本结构 1.输入部分包含&#xff1a; 2. 编码器部分&#xff1a; 2.1 掩码张量 学习并实现了生成向后遮掩的掩码张量函数: subsequent_mask 2.2 注意力机制 2.3 多头注意力机制 3. 解码器部分&#xff1a; 4. 输出部分包含&#xff1a; 三类应用 机器翻译类应用…

你知道GPT-3带的即时学习能力是什么吗

你知道GPT-3带的即时学习能力是什么吗 在人工智能领域&#xff0c;GPT-3&#xff08;Generative Pre-trained Transformer 3&#xff09;是当前比较先进的自然语言处理模型之一。它采用了自监督学习的方式进行训练&#xff0c;并且拥有强大的“in-context learning”&#xff…

自学Python 69 Selenium八大元素定位方法(新版BY方法)

Python Selenium八大元素定位方法(新版BY方法) 文章目录 Python Selenium八大元素定位方法(新版BY方法)前言一、常用的八种定位方法&#xff08;新旧对比&#xff09;二、查看网页元素三、八大元素定位示例1、id定位2、name定位3、class定位4、tag定位5、link定位6、partial_li…