SpringBoot结合MyBatis-Plus快速CRUD笔记

2023-05-16

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、DTO & DO
  • 二、示例
    • 1. 定义Controller
    • 2.定义Service和实现
    • 3.定义Mapper
    • 4.前端访问测试
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:
这里记录下使用SpringBoot结合Mybatis-plus快速构建CRUD接口通用示例。
mybatis-plus是mybatis的超集,可以放心使用,具体参考官网。


提示:以下是本篇文章正文内容,下面案例可供参考

一、DTO & DO

以下是一些概念的厘清,理解因人而异。

DO、PO、VO、DTO等其实都是一个JavaBean,只是应用的范围不同,表示的意义不同,而这些不同是Java这么多年来形成的一种约定,这种习惯形成Java程序员之间一种共识。有些人喜欢把返回给前端的对象封装为VO、有些人喜欢将和数据交互的对象定义为DAO ,也有人喜欢返回前端使用DTO代替,总之屏蔽了MySQL原始的数据库表的细节,只需要对外暴露不同即可。我们为了方便,统一定义DTO为和前端进行数据交互的组件,DO就是和数据库表具有严格映射关系的对象了。每个人风格不同,但是大体表达的意思是一样的。

二、示例

SpringBoot单体应用大都包含Controller/Service/Mapper 这三个重要模块,其他诸如实体类Entity、DTO,甚至request/response
可以依据自己是否需要来定义,不过最好遵循公司内部的规范来,否则维护起来真的挺麻烦。

1. 定义Controller

以下是CRUD代码(示例):

@Api("Topic管理")
@Slf4j
@RestController
@RequestMapping("/topic")
public class TopicController {

    @Autowired
    private TopicService topicService;

    @PostMapping("/addOrUpdateTopic")
    @ApiOperation("添加或更新Topic")
    public Result<String> addOrUpdateTopic(@RequestBody @NotNull AddTopicRequest addTopicRequest) {
        try {
            topicService.saveOrUpdate(addTopicRequest);
        } catch (Exception e) {
            log.error("{} # applyTopic Error: {}", this.getClass().getName(), e.getMessage());
            return Result.errorData("Topic添加或更新失败", e.getMessage());
        }
        return Result.successMessage("Topic添加或更新成功!");
    }


    @PostMapping("/queryTopics")
    @ApiOperation("查询topics: 依据Topic名称,owner搜索")
    public Result<IPage<TopicDTO>> queryTopics(@RequestBody TopicQueryRequest queryDTO) {
        IPage<TopicDTO> topicDTOList = null;
        try {
            topicDTOList = topicService.queryAllTopics(queryDTO);
        } catch (Exception e) {
            log.error("{} # queryTopics Error: {}", this.getClass().getName(), e.getMessage());
            return Result.errorData(topicDTOList);
        }
        return Result.successData(topicDTOList);
    }


    @GetMapping("/findOne/{name}")
    @ApiOperation("根据topic name 查询topic")
    public Result<TopicDO> findOneTopic(@PathVariable("name") @NotNull String name) {
        return Result.successData(topicService.queryOneTopic(name));
    }


    @DeleteMapping("/deleteTopic/{id}")
    @ApiOperation("删除Topic")
    public Result<String> deleteTopic(@PathVariable @NotNull Long id) {
        try {
            topicService.deleteTopic(id);
        } catch (Exception e) {
            log.error("{} # deleteTopic Error: {}", this.getClass().getName(), e.getMessage());
            return Result.errorData("Topic删除失败", e.getMessage());
        }
        return Result.successMessage("Topic删除成功!");
    }

2.定义Service和实现

代码如下(示例):
定义接口:

public interface TopicService {
    /**
     * 添加topic
     *
     * @param addTopicRequest
     * @return
     */
    void saveOrUpdate(AddTopicRequest addTopicRequest);


    /**
     * 删除topic
     *
     * @param id
     * @return
     */
    void deleteTopic(Long id);


    /**
     * 添加topic
     *
     * @param topicName
     * @return
     */
    TopicDO queryOneTopic(String topicName);


    /**
     * 分页查询topic
     *
     * @return
     */
    IPage<TopicDTO> queryAllTopics(TopicQueryRequest queryDTO);

}

接口实现:

@Service("TopicService")
public class TopicServiceImpl extends ServiceImpl<TopicMapper, TopicDO> implements TopicService {

    @Autowired
    private TopicMapper topicMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(AddTopicRequest request) {
        TopicDO topicDO = TopicDO.builder()
                .id(request.getId())
                .topicName(request.getTopicName())
                .owner(request.getOwner()) // operator
                .description(request.getDescription())
                .partitionNum(request.getPartitionNum() == 0 ? TopicConstant.DEFAULT_PARTITION_NUM : request.getPartitionNum())
                .replicaNum(request.getReplicaNum() == 0 ? TopicConstant.DEFAULT_REPLICA_NUM : request.getReplicaNum())
                .retentionTime(request.getRetentionTime() == 0 ? TopicConstant.DEFAULT_RETENTION_TIME : request.getRetentionTime())
                .build();
        if (0 == topicDO.getId() || null == topicDO.getId()) {
            this.save(topicDO);
        } else {
            this.updateById(topicDO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTopic(Long id) {
        this.removeById(id);
    }

    @Override
    public TopicDO queryOneTopic(String topicName) {
        return this.getOne(Wrappers.<TopicDO>lambdaQuery().eq(TopicDO::getTopicName, topicName));
    }

    @Override
    public IPage<TopicDTO> queryAllTopics(TopicQueryRequest queryDTO) {
        if (queryDTO.getPageNo() == 0 || null == queryDTO.getPageNo()) {
            queryDTO.setPageNo(1);
        }
        if (queryDTO.getPageSize() == 0 || null == queryDTO.getPageNo()) {
            queryDTO.setPageSize(10);
        }
        Page<TopicDTO> page = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
        if (StringUtils.isNotBlank(queryDTO.getKeyword())) {
            queryDTO.setKeyword("%" + queryDTO.getKeyword() + "%");
        }
        IPage<TopicDTO> topicLists = topicMapper.queryPage(page, queryDTO);
        return topicLists;
    }
}

3.定义Mapper

mapper用于和数据库打交道,类似于DAO,以下是一个mapper接口,申明了之后就具备一些操作的特性。
原因是因为拿到的 mapper 其实是一个代理对象,底层调用的是 SqlSession 的方法,SqlSession 的方法里其实调用的 Executor 的方法。
其实就是配置文件+动态代理的增强。

@Repository
public interface TopicMapper extends BaseMapper<TopicDO> {
    /**
     * 分页查询
     *
     * @param page
     * @param queryDTO
     * @return
     */
    IPage<TopicDTO> queryPage(Page<TopicDTO> page, @Param("queryDTO") TopicQueryRequest queryDTO);
}


其实我们继承Mapper接口后,可以不用在写配置文件就可以进行crud功能,但是如果需要自定义的内容还是需要。

> /**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * <p>这个 Mapper 支持 id 泛型</p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> extends Mapper<T> {

TopicMapper.xml (可有可无,但是为了通用也便于后期维护扩展建议一定要有)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xx.dao.TopicMapper">
    <resultMap id="topicResultMap" type="com.xx.topic.TopicDTO">
        <result column="id" property="id"/>
        <result column="topic_name" property="topicName"/>
        <result column="partition_num" property="partitionNum"/>
        <result column="replica_num" property="replicaNum"/>
        <result column="retention_time" property="retentionTime"/>
        <result column="owner" property="owner"/>
        <result column="description" property="description"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>

    <select id="queryPage" resultMap="topicResultMap">
        SELECT
        id,topic_name,partition_num,replica_num,retention_time,owner,description,create_time,update_time
        FROM topic where is_deleted = 0
        <if test="queryDTO.keyword != null and queryDTO.keyword.trim() != '' ">
            AND ( topic_name LIKE #{queryDTO.keyword} OR `owner` LIKE #{queryDTO.keyword} )
        </if>
    </select>

</mapper>

4.前端访问测试

http://localhost:8080/swagger-ui.html#/topic-controller

在这里插入图片描述

总结

构建一个SpringBoot的单体应用目前来看越来越容易,到处可以使用的轮子,甚至很多开源的Demo都可以用来借鉴,比如有了mybatis-plus 对mybatis的增强,Lombok简化代码书写等,但是希望越来越快捷的同时可能也要多一点的思考,不然难以精进。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot结合MyBatis-Plus快速CRUD笔记 的相关文章

随机推荐

  • 记一次神奇的时间转换问题(SheetJS)

    最近在写一个功能 xff0c 使用SheetJS读取Excel表格 xff0c 在读取日期的时候发现了一个隐藏很深的坑 xff0c 特此记录一下 SheetJS读取Excel文件时 xff0c 可指定参数 cellDates true xf
  • 通信常识

    bsc指的是基站控制器 xff08 Base Station Controller xff09 由一下模块组成 xff1a AM CM模块 xff1a 话路交换和信息交换的中心 BM模块 xff1a 完成呼叫处理 信令处理 无线资源管理 无
  • python解析基于xml格式的日志文件

    大家中午好 xff0c 由于过年一直还没回到状态 xff0c 好久没分享一波小知识了 xff0c 今天 xff0c 继续给大家分享一波python解析日志的小脚本 首先 xff0c 同样的先看看日志是个啥样 都是xml格式的 xff0c 是
  • 如何在无显示屏的情况下调试树莓派

    一 准备 1 树莓派 xff1b 2 SD卡 读卡器 网线 xff1b 3 系统镜像下载链接 xff1b 4 软件 xff1a SD Card Formatter下载链接 xff1b balenaEtcher下载链接 xff1b VNC V
  • VNC怎么和宿主机共享粘贴板

    VNC怎么和宿主机共享粘贴板 假设目标主机是linux xff0c 终端主机是windows xff08 就是在windows上使用VNC登陆linux xff09 在linux中执行vncconfig nowin amp 在linux选中
  • 系统调用,进程切换

    模式切换 不等同于 进程上下文切换 当进程调用系统调用或者发生中断时 xff0c CPU从用户模式 xff08 用户态 xff09 切换成内核模式 xff08 内核态 xff09 xff0c 此时 xff0c 无论是系统调用程序还是中断服务
  • brew换源

    bin zsh c 34 curl fsSL https gitee com cunkai HomebrewCN raw master Homebrew sh 34 mac安装homebrew失败怎么办 xff1f 金牛肖马的回答 知乎 h
  • 2022年书单

    2022年书单 纸质书 类别序号书名进度社会科学0 从零开始的女性主义 x1f44c 社会科学1 如何抑制女性写作 x1f44c 社会科学2 父权制与资本主义 社会科学3 下流社会 x1f44c 社会科学4 低欲望社会 x1f44c 社会科
  • 书店漫游记录

    目录 北京 上海 杭州 天津 南京 青岛 深圳 香港 北京 万圣书园 豆瓣书店 野草书店 三联韬奋书店 xff08 三里屯 xff09 三联韬奋书店 xff08 美术馆 xff09 Pageone xff08 北京坊 xff09 Pageo
  • C++ std::string 不可初始化为NULL及基本用法

    偶然看到一个问题 xff0c 顺便总结一下std string C 43 43 basic string S construct null not valid stackoverflow例子 std string 字符串不可以初始化为NUL
  • 通过查看端口状态查看mongodb是否已经启动

    LINUX环境下 xff0c 可以通过查看端口27017的状态查看mongod是否已经启动 netstat lanp span class hljs string grep 34 span span class hljs number 27
  • linux & windows C++开发差异

    新手注意事项 1 文件与目录的大小写以及路径分隔符的差别 windows下不区分大小写 xff0c 路径分隔符一般使用 xff1b linux下区分大小写 xff0c 路径分隔符使用 2 itoa 函数在linux下并不存在 所以使用类似s
  • 深度学习结合SLAM的研究思路/成果整理之(一)使用深度学习方法替换SLAM中的模块

    整理了部分近两年深度学习结合SLAM的一些研究成果 xff08 参考知乎帖子https www zhihu com question 66006923 和泡泡机器人公众号 xff0c 附上论文链接和已找到的源代码 数据集链接 xff0c 大
  • 深度学习与自动驾驶领域的数据集(KITTI,Oxford,Cityscape,Comma.ai,BDDV,TORCS,Udacity,GTA,CARLA,Carcraft)

    http blog csdn net solomon1558 article details 70173223 Torontocity HCI middlebury caltech 行人检测数据集 ISPRS航拍数据集 mot challe
  • 又一遍……ORB_SLAM2+ZED相机(SDK2.2.1)+CUDA9.0+ROS Kinetic 安装测试 some tips

    很久没碰过ORB SLAM2了 xff0c 今天有需要 xff0c 再来试一遍 xff5e ORB SLAM2的github链接 1 安装ORB SLAM2的依赖库 按照链接一步一步来就可以 eigen直接用命令安装就可以 sudo apt
  • MacOS设置终端代理

    前言 国内的开发者或多或少都会因为网络而烦恼 xff0c 因为一些特殊原因有时候网络不好的时候需要使用代理才能完成对应的操作 原来我一直都是使用斐讯路由器然后刷了梅林的固件 xff0c 直接在路由器层面设置转发代理 xff0c 把一些国内网
  • Linux SIGPIPE信号产生原因与解决方法

    TCP 四次握手 产生SIGPIPE的原因 SIGPIPE信号产生的原因 xff1a 简单来说 xff0c 就是客户端程序向服务器端程序发送了消息 xff0c 然后关闭客户端 xff0c 服务器端返回消息的时候就会收到内核给的SIGPIPE
  • Homebrew最新安装--解决安装超时的问题

    更新 2021 1 20 可以直接用下边的脚本进行安装 bin zsh c span class token string 34 span class token variable span class token variable spa
  • TIDB使用时的注意点笔记

    场景 xff1a 虽然TiDB号称完全兼容MySQL 5 7 协议 MySQL 5 7 常用的功能及语法 xff0c 但是其与MySQL数据库仍然存在一些差异 xff0c 可能会导致下游TiDB环境故障 以下是我们使用TiDB时需要重点关注
  • SpringBoot结合MyBatis-Plus快速CRUD笔记

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 DTO amp DO二 示例1 定义Controller2 定义Service和实现3 定义Mapper4 前端访问测试