CRUD流程

CRUD流程

第一步:DAO层(与数据库进行交互)

1.阅读开发文档,按照开发文档在ideal里创建结构

请添加图片描述

2.创建实体类,和对应的mapper层(可以用mybits),mapper层主要与数据库进行交互。在这里插入图片描述
3.DAO层DO(实体类),mapper文件(接口类)----------->xml文件(接口文件具体的实现方法)】在这里插入图片描述
4.mapper文件(定义接口和方法名称)接口一般是增删改查四种,例如:
package com.xcyy.system.mapper;

import com.xcyy.common.objdect.entity.MeractivitiesDO;

/**
* @author ksm
* @description 针对表【MerActivities(商户活动的表,存储活动相关信息)】/**
     * 根据ID查询
     */
    MeractivitiesDO selectById(String ActivityID);
* @createDate 2024-06-21 11:38:21
* @Entity com.xcyy.system.domain.Meractivities
*/
public interface MeractivitiesMapper  {
    /**
     * 根据ID查询
     */
    MeractivitiesDO selectById(String ActivityID);
    /**
     * 查询所有
     */
    MeractivitiesDO selectAll();
    /**
     * 新增信息
     */
    int insertMertable(MeractivitiesDO meractivities);
    /**
     * 删除信息
     */
    int deleteByActivityid(String ActivityID);
    /**
     * 更新信息
     */
    int updateByActivityid(MeractivitiesDO meractivities);
}

5.xml文件(实现具体的mapper方法)例如:
<?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.xcyy.system.mapper.MeractivitiesMapper">

    <resultMap id="BaseResultMap" type="com.xcyy.common.objdect.entity.MeractivitiesDO">
        <id property="activityId" column="activity_id"/>
        <result property="imagePath" column="image_url"/>
        <result property="link" column="=link"/>
        <result property="description" column="description"/>
        <result property="creator" column="creator"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="status" column="status"/>
        <result property="title" column="title"/>
        <result property="startTime" column="start_time"/>
        <result property="endTime" column="end_time" />
    </resultMap>

    <select id="selectById" parameterType="com.xcyy.common.objdect.entity.MeractivitiesDO" resultMap="BaseResultMap">
        select activity_id,image_url,link,
        description,creator,create_time,
        update_time,status,title,
        start_time,end_time from mall_activity
        <where>
            activity_id = #{activityID}
        </where>
    </select>
            
     <select id="selectAll" parameterType="com.xcyy.common.objdect.entity.MeractivitiesDO" resultMap="BaseResultMap">
        select*
    </select>
            
    <insert id="insertMertable" parameterType="com.xcyy.common.objdect.entity.MeractivitiesDO">
        INSERT INTO mall_activity
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="activityId != null">activity_id</if>
            <if test="imagePath != null">image_url</if>
            <if test="link != null">link</if>
            <if test="description != null">description</if>
            <if test="creator != null">creator</if>
            <if test="createTime != null">create_time</if>
            <if test="updateTime != null">update_time</if>
            <if test="status != null">status</if>
            <if test="title != null">title</if>
            <if test="startTime != null">start_time</if>
            <if test="endTime != null">end_time</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="activityId != null">#{activityId},</if>
            <if test="imagePath != null">#{imagePath},</if>
            <if test="link != null">#{link},</if>
            <if test="description != null">#{description},</if>
            <if test="creator != null">#{creator},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateTime != null">#{updateTime},</if>
            <if test="status != null">#{status},</if>
            <if test="title != null">#{title},</if>
            <if test="startTime != null">#{startTime},</if>
            <if test="endTime != null">#{endTime},</if>
        </trim>

    </insert>
    <delete id="deleteByActivityid" parameterType="com.xcyy.common.objdect.entity.MeractivitiesDO">
        delete from mall_activity
        <where>
            activity_id = #{activityID}
        </where>
    </delete>
    <update id="updateByActivityid" parameterType="com.xcyy.common.objdect.entity.MeractivitiesDO">
        UPDATE mall_activity
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="activityId != null">activity_id = #{activityId},</if>
            <if test="imagePath != null">image_url = #{imagePath},</if>
            <if test="link != null">link = #{link},</if>
            <if test="description != null">description = #{description},</if>
            <if test="creator != null">creator = #{creator},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="status != null">status = #{status},</if>
            <if test="title != null">title = #{title},</if>
            <if test="startTime != null">start_time = #{startTime},</if>
            <if test="endTime != null">end_time = #{endTime},</if>
        </trim>
        where activity_id = #{activityID}
    </update>
</mapper>

第二步:Service层(中间层,与DAO层和Controller层进行交互)

1.Service接口层(做一些比基础“增删改查”更复杂的逻辑,比如“排序某个数据库字段(点赞率)并查询第一个字段返回给前端”)例如:
package com.xcyy.system.service;

import com.xcyy.common.objdect.bo.GenericPageRspBO;
import com.xcyy.common.objdect.bo.MeractivitiesBO;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author ksm
 * @description 针对表【MerActivities(商户活动的表,存储活动相关信息)】的数据库操作Service
 * @createDate 2024-06-21 11:38:21
 */
public interface IMeractivitiesService {
    MeractivitiesBO selectMeractivitiesById(String activityid);

    GenericPageRspBO<MeractivitiesBO> selectAllMeractivities(MeractivitiesBO meractivitiesBO);

    int insertMeractivities(MultipartFile multipartFile, MeractivitiesBO meractivitiesBO);

    int deleteMeractivitiesById(String activityid);

    int updateMeractivitiesById(MultipartFile multipartFile,MeractivitiesBO meractivitiesBO);
}
2.Service实现层(实现接口层的业务)主要是调用Mapper层的CRUD来实现 例如:
package com.xcyy.system.service.impl;

import com.xcyy.common.core.exception.ServiceException;
import com.xcyy.common.core.utils.BeanCopyUtils;
import com.xcyy.common.core.utils.DateTimeUtils;
import com.xcyy.common.core.utils.PageInfo;
import com.xcyy.common.core.utils.PageUtil;
import com.xcyy.common.core.utils.uuid.IdUtils;
import com.xcyy.common.objdect.bo.GenericPageRspBO;
import com.xcyy.common.objdect.bo.MeractivitiesBO;
import com.xcyy.common.objdect.entity.MeractivitiesDO;
import com.xcyy.common.security.utils.SecurityUtils;
import com.xcyy.file.utils.MinIOFileUtils;
import com.xcyy.system.mapper.MeractivitiesMapper;
import com.xcyy.system.service.IMeractivitiesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author ksm
 * @description 针对表【MerActivities(商户活动的表,存储活动相关信息)】的数据库操作Service实现
 * @createDate 2024-06-21 11:38:21
 */
@Service
public class MeractivitiesServiceImpl implements IMeractivitiesService {
    @Autowired
    MeractivitiesMapper meractivitiesMapper;
    // 事务回滚
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    //根据ID查询
    public MeractivitiesBO selectMeractivitiesById(String activityid) {
        return BeanCopyUtils.deepCopyBean(meractivitiesMapper.selectById(activityid), MeractivitiesBO.class);
    }
    @Override
    //list查询
    public GenericPageRspBO<MeractivitiesBO> selectAllMeractivities(MeractivitiesBO meractivitiesBO){
        MeractivitiesDO meractivitiesDO = BeanCopyUtils.deepCopyBean(meractivitiesBO, MeractivitiesDO.class);
        PageInfo<MeractivitiesDO> meractivitiesDOPageInfo = PageUtil.pageQueryWithCount(
                meractivitiesBO.getPageNum(),
                meractivitiesBO.getPageSize(),
                () -> meractivitiesMapper.selectAll(meractivitiesDO)
        );
        GenericPageRspBO genericPageRspBO = new GenericPageRspBO();
        genericPageRspBO.setTotal(meractivitiesDOPageInfo.getTotal());
        genericPageRspBO.setResultList(BeanCopyUtils.deepCopyBeanList(meractivitiesDOPageInfo.getList(), MeractivitiesDO.class));
        return genericPageRspBO;
    }
    // 事务回滚
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    //增,向数据库里增加一行数据,并把图片存入文件数据库
    public int insertMeractivities(MultipartFile multipartFile, MeractivitiesBO meractivitiesBO) {
        // 上传文件返回文件地址
        String fileUrl = MinIOFileUtils.uploadMinIOFile(
                multipartFile,
                meractivitiesBO.getActivityid().toString(),
                "meractivities"
        );
        //修改文件地址存入数据库
        meractivitiesBO.setImagepath(fileUrl);
        meractivitiesBO.setActivityid(IdUtils.fastSimpleUUID());
        meractivitiesBO.setStatus(Boolean.TRUE);
        meractivitiesBO.setCreatetime(DateTimeUtils.getCurrentLocalDate());
        meractivitiesBO.setCreator(SecurityUtils.getLoginUser().getUsername());
        // 将BO对象转换为DO对象
        MeractivitiesDO meractivitiesDO = BeanCopyUtils.deepCopyBean(meractivitiesBO, MeractivitiesDO.class);
        return meractivitiesMapper.insertMertable(meractivitiesDO);
    }

    // 事务回滚
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    //删除数据库的一行数据
    public int deleteMeractivitiesById(String activityid) {
        // 删除文件
        MinIOFileUtils.deleteMinIOFile(
                new String[]{
                        meractivitiesMapper.selectById(activityid).getImagePath()
                }
        );
        // 删除数据库
        return meractivitiesMapper.deleteByActivityid(activityid);

    }
    // 事务回滚
    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public int updateMeractivitiesById(MultipartFile multipartFile, MeractivitiesBO meractivitiesBO) {
        meractivitiesBO.setUpdatetime(DateTimeUtils.getCurrentLocalDate());
        if (!multipartFile.isEmpty()) {
            // 上传文件返回文件地址
            String fileUrl = MinIOFileUtils.uploadMinIOFile(
                    multipartFile,
                    meractivitiesBO.getActivityid().toString(),
                    "meractivities");
            //修改文件地址存入实体层
            meractivitiesBO.setImagepath(fileUrl);
        }
        // 将BO对象转换为DO对象
        MeractivitiesDO meractivitiesDO = BeanCopyUtils.deepCopyBean(meractivitiesBO, MeractivitiesDO.class);
        return meractivitiesMapper.updateByActivityid(meractivitiesDO);
    }
}


第三步:Controller层

1.用来实现和前端的交互
1.http的get、post、put、delete 的原理

http与服务器交互提供了四种方式,get、post、put和delete
get:是相当于select查询操作,不会改变或影响服务器端的任何内容信息;
post:是相当于insert插入操作,会增加数据,存入到服务器端;
put:是相当于update更新操作,不会增加数据,只是修改服务器端的信息;
delete:是相当于delete删除操作,是用来删除资源的;
url:是资源定位符
get、put、delete对应的url可以理解为:/url/XXX,post对应的url可以理解为:/url

get对应的就是getMapping
put对应的就是putMapping
post对应的就是postMapping
delete对应的就是deleteMapping

一般传输少量数据直接用getMapping就可以了,getMapping的请求url的形式有两种,
一种是 后台访问地址?参数1= “参数1”&参数2=“参数2”,在后台取出路径上的值可以用,在后台程序对应方法的路径可以只需要写路径即可

第二种是 后台访问地址 ?参数,在后台程序对应方法的路径之后需要加一个{参数名}类似于:

@RequiresPermissions("system:meractivities:query")
@GetMapping("/find/{id}")
public MeractivitiesDTO selectMeractivitiesById(@PathVariable String id) {
    return BeanCopyUtils.deepCopyBean(meractivitiesService.selectMeractivitiesById(id), MeractivitiesDTO.class);
}

在后台取出路径上的参数时,
第一种用@RequestParam,这个注解的value指定路径上的参数名,require用来标识是否是必须要传的参数

@PostMapping("/insert")
public AjaxResult insertMeractivities(@RequestParam("multipartFile")MultipartFile multipartFile, MeractivitiesVO meractivitiesVO) {

    return toAjax(meractivitiesService.insertMeractivities(
                    multipartFile,
                    BeanCopyUtils.deepCopyBean(meractivitiesVO, MeractivitiesBO.class)
            )
    );
}

第二种用@PathVariable,这个直接在注解的参数中写入参数名就可以了

@DeleteMapping("/delete/{id}")
public AjaxResult deleteMeractivitiesById(@PathVariable String id) {
    return toAjax(meractivitiesService.deleteMeractivitiesById(id));
}

但是用路径url的总长度是有限制的,对参数个数是没有限制的,不同浏览器对url的限长是不一样的,所以需要传输的数据量大的时候或者用表单的时候是需要用到post,postMapping请求的,因为post的请求体是不限制的。

post的参数呢是一个对象,从前端角度出发可以看成一个json格式的字符串,在后台接收的时候,可以直接用一个对象来接收,这个对象前面加上注解@ResquestBody即可

put跟post类似,对应的是更新操作,传过来的也是一个json字符串可以用@RequestBody的形式接收,也可以像get那样,用参数的形式进行传值

delete的用法就跟get类似了,delete对应的是删除,把字段的值传过来即可

2.controller语法
1.@Restcontroller,@RestMapping@Autowired
@RestController//
@RequestMapping(SystemRequestConstants.MALL_ACTIVITY)//这个url地址使用了字典常量,实际上是/XcYy/System/meractivities
public class MeractivitiesController extends BaseController {

    @Autowired
    private IMeractivitiesService meractivitiesService;//带了这个注解可以免去Test1Entity testEntity = new Test1Entity();这样的语法

    @RequiresPermissions("system:meractivities:query")//权限控制
    @GetMapping("/find/{id}")//实际上是/XcYy/System/meractivities/find/{id}
    public MeractivitiesDTO selectMeractivitiesById(@PathVariable String id) {
        return BeanCopyUtils.deepCopyBean(meractivitiesService.selectMeractivitiesById(id), MeractivitiesDTO.class);
    }
2.@GetMapping
/**
 * 根据ID查询
 * @param id
 * @return
 */
GetMapping("/select/{id}")
MyStudent selectById(@PathVariable String id)//在控制器中的处理方法的形参中使用@PathVariable注解去获取@RequestMapping中 { } 中传进来的值,并绑定到处理方法定一的形参上。 
{
    return myStudentMapper.selectByPrimaryKey(id);
}
3.@PostMapping
/**
 * 插入数据
 * @param id
 * @param name
 * @param birth
 * @param sex
 * @return
 */
@PostMapping("/student")
public int insertStu(@RequestParam String id, @RequestParam String name, @RequestParam String birth, @RequestParam String sex)
//@RequestParam用于将指定的请求参数赋值给方法中的形参。
{
    MyStudent myStudent = new MyStudent();
    myStudent.setsId(id);
    myStudent.setsName(name);
    myStudent.setsBirth(birth);
    myStudent.setsSex(sex);
    return myStudentMapper.insert(myStudent);
}
4.@PutMapping
   /**

 * 局部更新用PatchMapping 全局更新用PutMapping
 * @param myStudent
 * @return
   */
   @PatchMapping("/update")
   public int updateById(MyStudent myStudent) {
   return myStudentMapper.updateByPrimaryKey(myStudent);
   }
5.@DeleteMapping
/**
 * 根据ID删除一条数据
 *
 * @param id
 * @return
 */
@DeleteMapping("/delete/{id}")
public int deleteById(@PathVariable String id) {
    return myStudentMapper.deleteByPrimaryKey(id);
}

6.对于前端传值的时候注意:

对于json类型的数据(‘Content-Type’: ‘application/json’ ),需要使用@RequestBody接受,否则控制台会报错

对于其他类型的数据(‘Content-Type’: ‘application/x-www-form-urlencoded’),后台可以直接接受

最好使用json传值,因为null值在json中会被正常处理

第四步:使用Postman软件去测试接口

1.软件简介:

img

如何使用Postman?
下图是Postman的工作区间,各个模块功能的介绍如下:

1、New,在这里创建新的请求、集合或环境;还可以创建更高级的文档、Mock Server 和 Monitor以及API。
2、Import,这用于导入集合或环境。有一些选项,例如从文件,文件夹导入,链接或粘贴原始文本。
3、Runner,可以通过Collection Runner执行自动化测试。后续介绍。
4、Open New,打开一个新的标签,Postman窗口或Runner窗口。
5、My Workspace - 可以单独或以团队的形式创建新的工作区。
6、Invite - 通过邀请团队成员在工作空间上进行协同工作。
7、History - 所有请求的历史记录,这样可以很容易地跟踪你所做的操作。
8、Collections - 通过创建集合来组织你的测试套件。每个集合可能有子文件夹和多个请求。请求或文件夹也可以被复制。
9、Request tab - 这将显示您正在处理的请求的标题。默认对于没有标题的请求会显示“Untitled Request”。
10、HTTP Request - 单击它将显示不同请求的下拉列表,例如 GET, POST, COPY, DELETE, etc. 在测试中,最常用的请求是GET和POST。
11、Request URL - 也称为端点,显示API的URL。.
12、Save - 如果对请求进行了更改,必须单击save,这样新更改才不会丢失或覆盖。
13、Params - 在这里将编写请求所需的参数,比如Key - Value。
14、Authorization - 为了访问api,需要适当的授权。它可以是Username、Password、Token等形式。
15、Headers - 请求头信息
16、Body - 请求体信息,一般在POST中才会使用到
17、Pre-request Script - 请求之前 先执行脚本,使用设置环境的预请求脚本来确保在正确的环境中运行测试。
18、Tests - 这些脚本是在请求期间执行的。进行测试非常重要,因为它设置检查点来验证响应状态是否正常、检索的数据是否符合预期以及其他测试。
19、Settings - 最新版本的有设置,一般用不到。

img

2.如何处理GET请求:

在Postman的工作区中:
1、选择HTTP请求方式为GET
2、在URL区域输入 链接
3、点击 “Send”按钮
4、你将看到下方返回200状态码
5、在正文中应该有10个用户结果,表明您的测试已经成功运行。

img

注意: 在某些情况下,Get请求失败可能由于URL无效或需要身份验证。
3.如何处理POST请求:
Step 1)

1、选择HTTP请求方式为POST
2、在URL区域输入 链接:https://jsonplaceholder.typicode.com/users
3、切换到Body选项

img

Step 2)

Body选项
1、选中raw选项
2、选择JSON

img

Step 3)

在Body里添加Json代码

img

**注意:** 检查Body里用到的JSON格式很重要,以确保数据正确。
检测的工具比如:https://jsonformatter.curiousconcept.com/

img

Step 4)

发送请求
1、完成上述的信息输入,点击Send按钮
2、Status:应该是201,显示为创建成功
3、在Body里返回数据W

s-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3piajE4MzE0NDY5Mzk1,size_1,color_FFFFFF,t_70)

**注意:** 检查Body里用到的JSON格式很重要,以确保数据正确。
检测的工具比如:https://jsonformatter.curiousconcept.com/

img

Step 4)

发送请求
1、完成上述的信息输入,点击Send按钮
2、Status:应该是201,显示为创建成功
3、在Body里返回数据

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值