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 {

    @Resource
    private 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 {
	@Autowired
    private ActivityMapper activityMapper;
	
	 @Override
    public 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的一些总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯专题-试题版-【01字符串】【2n皇后问题】【A+B问题】【Fibonacci数列】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

Python:pyecharts可视化

文章目录 简介Geo地理图绘制地图下载 折线图区域突出显示横坐标带选择展示 add地图Mapformatter控制value显示在图中显示value值目标html的解析自定义地图js资源原生地图js的解析解决省份上文字不居中的问题 桑基图设置桑基柱的颜色 参考文献 简介 &#xff08;这是20年的笔记…

【MySQL】库的操作

目录 一、创建数据库 二、字符集和校验规则 1、查看系统默认字符集以及校验规则 2、创建数据库案例 3、校验规则对数据库的影响 3.1、不区分大小写 3.2、区分大小写 3.3、进行查询 3.3.1、不区分大小写的查询以及结果 3.3.2、区分大小写的查询以及结果 3.4、结果排序…

flutter - 编写 阿里云-金融级实名认证插件

项目中有实名认证的需求&#xff0c;用户上传身份证反正面&#xff0c;进行人脸核验&#xff0c;后台集成的是阿里云的金融级实名认证SDK&#xff0c;巧合的是阿里云没有packages 需要自己造轮子。 废话不多少&#xff0c;直接上代码&#xff1a; 新建项目 ProjectType Plugin…

wsl下面的子系统启用systemctl

下载地址 https://github.com/gdraheim/docker-systemctl-replacement 操作 mv /usr/bin/systemctl /usr/bin/systemctl.old #对原文件进行备份sudo scp /mnt/c/Users/Administrator/Desktop/systemctl.py /usr/bin/systemctl #把项目中的systemctl.py文件拷贝到/use/bin/ 目…

Diffusion扩散模型学习2——Stable Diffusion结构解析-以文本生成图像为例

Diffusion扩散模型学习2——Stable Diffusion结构解析 学习前言源码下载地址网络构建一、什么是Stable Diffusion&#xff08;SD&#xff09;二、Stable Diffusion的组成三、生成流程1、文本编码2、采样流程a、生成初始噪声b、对噪声进行N次采样c、单次采样解析I、预测噪声II、…

安装mmdetection2.22(windows下)

安装mmdetection2.22 确定版本安装mmcv1.4安装mmdetection测试方案1方案2 确定版本 安装mmcv1.4 首先.cuda,pytorch得安装好&#xff0c;这里我拷贝pt1.8虚拟环境 安装mmcv1.4 安装mmdetection 参考文章 下载 cd E:\Code\mmdetection\mmdetection-2.22.0 pip install -r…

MATLAB 之 低层绘图操作和光照及材质处理

这里写目录标题 一、低层绘图操作1. 曲线对象2. 曲面对象3. 文本对象4. 其他核心对象4.1 区域块对象4.2 方框对象 二、光照和材质处理1. 光照处理2. 材质处理2.1 图形对象的反射特性2.2 material 函数 一、低层绘图操作 MATLAB 将曲线、曲面、文本等图形均视为对象&#xff0c…

【MySQL数据库 | 第十九篇】SQL性能分析工具

目录 前言&#xff1a; SQL执行频率&#xff1a; 慢查询日志&#xff1a; profile&#xff1a; profile各个指令&#xff1a; 总结&#xff1a; 前言&#xff1a; 本篇我们将为大家讲解SQL性能的分析工具&#xff0c;而只有熟练的掌握了性能分析的工具&#xff0c;才可以更…

【Spring Cloud Sleuth 分布式链路跟踪】 —— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d S l e u t h 分布式链路跟踪 \color{#FF1493}{Spring Cloud Sleuth 分布式链路跟踪} SpringCloudSleuth分布式链路跟踪&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云…

力扣 257. 二叉树的所有路径

题目来源&#xff1a;https://leetcode.cn/problems/binary-tree-paths/description/ C题解1&#xff1a;使用递归&#xff0c;声明了全局变量result&#xff0c;遇到叶子节点就将字符串添加到result中。 递归三步法&#xff1a; 1. 确认传入参数&#xff1a;当前节点已有路径…

如何保证API接口的安全性

API接口的安全性是非常重要的&#xff0c;以下是一些保证API接口安全性的措施&#xff1a; 用户认证、授权&#xff1a;接口的调用者必须提供有效的身份认证信息&#xff0c;包括用户名、密码、密钥等&#xff0c;以保证接口的调用者的身份有效性。同时&#xff0c;需要在接口的…

echarts的基础知识和配置项

异步数据加载和更新 ECharts 中在异步更新数据的时候需要通过series的name属性对应到相应的系列&#xff0c;如果没有name&#xff0c;series就会根据数组的顺序索引&#xff0c;把数据跟前面的配置对应上 loading动画 如果数据加载时间较长&#xff0c;一个空的坐标轴放在画…

基于深度学习的高精度人脸口罩检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度人脸口罩检测识别系统可用于日常生活中或野外来检测与定位人脸口罩目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的人脸口罩目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5…

《面试1v1》Redis持久化

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

<Oracle>《Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》(第一部分)

《Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》&#xff08;第一部分&#xff09; 1 说明1.1 前言1.2 资源下载 2 安装步骤2.1 上传安装包2.2 下载数据库预安装包2.3 安装数据库预安装包 1 说明 1.1 前言 本文是Linux系统命令行模式安装Oracle数据库的学习实验记录…

【C++实现二叉树的遍历】

目录 一、二叉树的结构二、二叉树的遍历方式三、源码 一、二叉树的结构 二、二叉树的遍历方式 先序遍历&#xff1a; 根–>左–>右中序遍历&#xff1a; 左–>根–>右后序遍历&#xff1a;左–>右–>根层次遍历&#xff1a;顶层–>底层 三、源码 注&am…

云原生监控平台 Prometheus 从部署到监控

1.监控系统架构设计 角色 节点 IP地址 监控端 Prometheus &#xff0c;Grafana&#xff0c;node_exporter &#xff0c;Nginx 47.120.35.251 被监控端1 node_exporter 47.113.177.189 被监控端2 mysqld_exporter&#xff0c;node_exporter&#xff0c;Nginx&#xff…

ivx低代码开发平台

前言 低代码开发平台&#xff08;Low-Code Development Platform, LCDS&#xff09;为企业和开发者提供了高效的应用开发方式。在2023年&#xff0c;中国的低代码开发平台正在快速发展&#xff0c;以下是其中最受关注的十大平台&#xff1a; iVX&#xff1a;iVX是一款新型的低代…

react总结

一、React 入门 1.1 特点 高性能、声明式、组件化、单向响应的数据流、JSX扩展、灵活 1.2 React初体验 <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&quo…