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

news2024/11/22 11:09:52

文章目录

  • 前言
  • 一、实体类的注解
  • 二、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的一些总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行业报告|2022年智能制造人才发展报告:自动化、PLC、机器人等控制执行类研发岗需求增长快

原创 | 文 BFT机器人 近年来&#xff0c;我国智能制造应用规模和发展水平大幅跃升&#xff0c;制造业智能化发展成效明显&#xff0c;有力支撑工业经济的高质量发展。与此同时&#xff0c;我国在2022年首次出现人口负增长&#xff0c;该趋势下我国发展制造业的人口红利正逐步降…

BurpSuite全平台通用扩展

前言 昨天分享的关于springboot3集成ChatGPT实现AI聊天、生成图片&#xff0c;被CSDN以违规拒发了&#xff0c;找人工客服最后一肚子气&#xff0c;从上大学开始入住CSDN一直偏爱&#xff0c;确实不想放弃&#xff0c;似乎现在他已经不再是一个纯技术交流分享平台了&#xff0…

LaWGPT:你的私人法律顾问!

LaWGPT&#xff1a;你的私人法律顾问&#xff01; LaWGPT 是一系列基于中文法律知识的开源大语言模型。 该系列模型在通用中文基座模型&#xff08;如 Chinese-LLaMA、ChatGLM 等&#xff09;的基础上扩充法律领域专有词表、大规模中文法律语料预训练&#xff0c;增强了大模型在…

工商业储能解读

工商业储能解读 0、前言1、2022-2023年工商业储能相关利好政策1.1 2022年1月4日1.2 2022年1月18日1.3 2022年2月10日1.4 2022年3月21日1.5 2022年3月22日1.6 2022年3月29日1.7 2022年4月2日1.8 2022年4月13日1.9 2022年4月25日1.10 2022年5月25日1.11 2022年5月30日1.12 2022年…

传输平台太多?难以管理?看这款跨网传输系统怎样解决

传输作为企业正常运行中最日常的行为&#xff0c;也意味着出现频率最高。微信、QQ、邮件、或是钉钉等办公软件&#xff0c;每天大家上班时开着各种软件&#xff0c;进行着不同的信息交互与传输。很多员工在工作时往往是哪个软件方便顺手就用哪个传输&#xff0c;但是这样也意味…

AI绘画Midjourney的咒语关键词汇总结

近期很多人都在研究Ai,被他强大的运算和准确性所震撼&#xff0c;和我们设计师相关的一个Ai绘画工具-Midjourney&#xff0c;绝对是占设计圈头部流量的&#xff0c;在圈内掀起一片热潮&#xff0c;今天我们就专门围绕他来展开说说&#xff0c;当然除了这个外&#xff0c;我们还…

Linux安装和配置VCenter

Linux安装和配置VCenter 以下演示安装 Linux VCenter&#xff0c;也就是使用VMware-VCSA-all-6.7.0-13010631.iso 镜像包。通过一台 Windows服务器远程连接 ESXI 服务器安装 Linux 版本的 VCenter。也就是Windows 服务器只是安装的界面的一个载体。 Linux VCenter环境搭建 下…

LLM 优先的软件架构:源自 ArchGuard Co-mate 的四个基本设计原则

在优化 ArchGuard 的 AI 辅助架构治理工具 Co-mate 的架构时&#xff0c;发现有一些模式与之前设计 AutoDev、ClickPrompt 等颇为相似。便思考着适合于 ArchGuard Co-mate 的架构设计原则是什么&#xff0c;写下了初步的三条原则。 而正好要在公司内分享 LLM 架构&#xff0c;…

【软考程序员学习笔记】——多媒体基础知识

目录 &#x1f34a; 一、多媒体的概念及分类 多媒体的分类 &#x1f34a;二、声音信号的数字化过程 采样 量化 编码 &#x1f34a;三、常见音频文件格式 &#x1f34a;四、图形/图像区别 图形 图像 &#x1f34a;五、常见图像文件格式 &#x1f34a;六、常见视频文件…

JDK8-2-流(3)- 流操作-distinct

JDK8-2-流&#xff08;3&#xff09;- 流操作-distinct 去重操作&#xff0c;如下开头两个菜品一样&#xff0c;对 menu 去重如下&#xff1a; public class DishDistinctTest1 {public static final List<Dish> menu Arrays.asList(new Dish("pork", false…

享元模式(十四)

每天都是全新的一天&#xff0c;感谢今日努力的自己。 上一章简单介绍了外观模式(十三), 如果没有看过, 请观看上一章 一. 享元模式 引用 菜鸟教程里面的外观模式介绍: https://www.runoob.com/design-pattern/flyweight-pattern.html 享元模式&#xff08;Flyweight Patter…

后,配置文件被清空,导致无法开启WiFi

root cause&#xff1a; /data/vendor/wifi/wpa/wpa_supplicant.conf 是0字节&#xff0c;导致wpa_supplicant_init_iface缺少”p2p_disabled1“的配置就会在走错flow到p2p wpa_supplicant_init_iface 》wpas_p2p_init 从而在HidlManager::registerInterface 进入 if (isP2pIf…

DeepSpeed零冗余优化器Zero Redundancy Optimizer

零冗余优化器 内容 零概述培训环境启用零优化 训练 1.5B 参数 GPT-2 模型训练 10B 参数 GPT-2 模型使用 ZeRO-Infinity 训练万亿级模型 使用 ZeRO-Infinity 卸载到 CPU 和 NVMe分配 Massive Megatron-LM 模型以内存为中心的平铺注册外部参数提取权重 如果您还没有这样做&…

【LeetCode】HOT 100(12)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

佩戴比较舒适的蓝牙耳机有哪些?值得入手的蓝牙耳机分享

​对于年轻人来说&#xff0c;耳机使用场景丰富&#xff0c;时尚追求度高&#xff0c;喜好的音乐类型也是多种多样&#xff0c;需求侧重也不尽相同。下面我来推荐几款相当不错的蓝牙耳机给大家&#xff0c;总会有喜欢那款&#xff01; 一、南卡OE蓝牙耳机 佩戴舒适度打分&…

【QQ界面展示-设置消息正文的背景图 Objective-C语言】

一、咱们上午说到哪儿了,还记得吗, 1.咱们上午是不是说到这儿了,可以显示正文、可以显示文字、并且,设置好背景图片了, 现在的问题就是,正文里面的文字,是不是超出这个图片了, 正文里面的文字,超出背景图片了, 那么,接下来,就给大家看一下,怎么解决这个问题, …

Macbook Pro双系统装Window10后设置触摸屏滑动方向

最近想给自己的Macbook Pro装Windows10操作系统&#xff0c;毕竟Windows才是真正的生产力工具&#xff0c;装了以后不需要两台笔记本了&#xff0c;直接在一台笔记本上有MacOS和Windows 装好以后发现触摸屏不能轻点触控还有触摸屏的滑动方向是反的 第一个问题&#xff0c;不能轻…

Ansys Zemax | 如何在序列模式下模拟分光棱镜

概述 这篇文章介绍了&#xff1a; 如何在序列模式下使用多重结构创建分光棱镜 如何在布局图以及分析/计算窗口中同时追迹透射和反射光线 在考虑偏振及镀膜的影响下如何计算透射和反射光线的总能量 &#xff08;联系我们获取文章附件&#xff09; 介绍 在 OpticStudio 中…

xxlJob任务管理平台500:xxl-job remoting error(connect timed out)

目录 一、问题截图 二、问题处理 2.1.查看执行器地址 2.2.查看本地端口 2.3.总结 三、关于地址的题外话 一、问题截图 此时可以看到code500&#xff0c;msg是连接超时&#xff0c;说明地址不通&#xff0c;那就是查看地址配置。 二、问题处理 2.1.查看执行器地址 …

使用CloudOS帮助企业落地云原生PaaS平台

PaaS究竟是什么&#xff1f; IaaS、SaaS的定义很清楚&#xff0c;而PaaS的定义就比较宽泛。所以&#xff0c;很多人把PaaS当做一个万能的“框”&#xff0c;什么都往里装&#xff0c;特别像一排垃圾桶中的那个“其他垃圾”桶&#xff0c;当你拎了一袋垃圾&#xff0c;不知道往…