当前位置: 首页 > news >正文

如何实现前后端交互以及方法传参中传字段和传对象的区别和方法。

如何实现前后端交互?

这里就拿做jeecgboot项目时的一个功能举例,该功能要实现的目标是后端查询数据库中的所需要显示的数据的条数,并显示到前端界面。数据库的内容变化的时候,前端显示也会实时改变。

数据库设计:

首先看一下数据库,数据库中有一个待办表tobedone,表结构如下:

图1 待办表的表结构

还有一个年度关键指标表,kpi表。表结构如下:

图2 年度关键指标表的结构

实体类设计:

根据设计好的表结构,分别设计两个实体类,将各个字段都写到实体类中去。这个是待办表的实体类。

package org.jeecg.modules.demo.tobedone.entity;import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** @Description: 待办* @Author: jeecg-boot* @Date:   2025-08-07* @Version: V1.0*/
@Data
@TableName("yx_tobedone")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="待办")
public class Tobedone implements Serializable {private static final long serialVersionUID = 1L;/**主键*/@TableId(type = IdType.ASSIGN_ID)@Schema(description = "主键")private java.lang.String id;/**创建人*/@Schema(description = "创建人")private java.lang.String createBy;/**创建日期*/@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "创建日期")private java.util.Date createTime;/**更新人*/@Schema(description = "更新人")private java.lang.String updateBy;/**更新日期*/@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "更新日期")private java.util.Date updateTime;/**所属部门*/@Schema(description = "所属部门")private java.lang.String sysOrgCode;/**完成时间*/@Excel(name = "待办完成时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "待办完成时间")private java.util.Date tobedoneFinishedtime;/**指标id*/@Excel(name = "指标id", width = 15)@Schema(description = "指标id")private java.lang.String kpiId;/*任务状态*/@Excel(name = "任务状态", width = 15)@Schema(description = "任务状态")private java.lang.String taskstatus;/*配合部门*/@Excel(name = "配合部门", width = 15)@Schema(description = "配合部门")private java.lang.String coopDepart;/*任务类型*/@Excel(name = "任务类型", width = 15)@Schema(description = "任务类型")private java.lang.String tasktype;/*任务类型*/@Excel(name = "驳回情况", width = 15)@Schema(description = "驳回情况")private java.lang.String refusestatus;/*任务类型*/@Excel(name = "汇报月份", width = 15)@Dict(dicCode = "month_type")@Schema(description = "汇报月份")private java.lang.String reportMonth;/*任务类型*/@Excel(name = "完成进度", width = 15)@Schema(description = "完成进度")private java.lang.String completionProgress;/*任务类型*/@Excel(name = "是否预警", width = 15)@Schema(description = "是否预警")private java.lang.String whetherWarn;/*任务类型*/@Excel(name = "审批月份", width = 15)@Dict(dicCode = "month_type")@Schema(description = "审批月份")private java.lang.String approvalMonth;}

别看这个字段这么多,其实做一个简单的交互就用了其中一部分字段。

然后是年度关键指标表的实体类:

package org.jeecg.modules.demo.kpi.entity;import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** @Description: 年度关键指标* @Author: jeecg-boot* @Date:   2025-08-07* @Version: V1.0*/
@Data
@TableName("yx_kpi")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="年度关键指标")
public class Kpi implements Serializable {private static final long serialVersionUID = 1L;/**主键*/@TableId(type = IdType.ASSIGN_ID)@Schema(description = "主键")private java.lang.String id;/**创建人*/@Schema(description = "创建人")private java.lang.String createBy;/**创建日期*/@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "创建日期")private java.util.Date createTime;/**更新人*/@Schema(description = "更新人")private java.lang.String updateBy;/**更新日期*/@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "更新日期")private java.util.Date updateTime;/**所属部门*/@Schema(description = "所属部门")private java.lang.String sysOrgCode;/**指标类型*/@Excel(name = "指标类型", width = 15, dicCode = "index_type")@Dict(dicCode = "index_type")@Schema(description = "指标类型")private java.lang.String indextype;/**考核指标*/@Excel(name = "考核指标", width = 15)@Schema(description = "考核指标")private java.lang.String assessindex;/**权重*/@Excel(name = "权重", width = 15)@Schema(description = "权重")private java.lang.String weight;/**指标定义及公式*/@Excel(name = "指标定义及公式", width = 15)@Schema(description = "指标定义及公式")private java.lang.String indexdefineandtime;/**评价细则*/@Excel(name = "评价细则", width = 15)@Schema(description = "评价细则")private java.lang.String commentrules;/**责任部门*/@Excel(name = "责任部门", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")@Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")@Schema(description = "责任部门")private java.lang.String respondepartment;/**基本目标值*/@Excel(name = "基本目标值", width = 15)@Schema(description = "基本目标值")private java.lang.String basetargetvalue;/**激励目标值*/@Excel(name = "激励目标值", width = 15)@Schema(description = "激励目标值")private java.lang.String motivatetargetvalue;/**完成时间*/@Excel(name = "指标完成时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")@Schema(description = "指标完成时间")private java.util.Date kpiFinishedtime;/**配合部门*/@Excel(name = "配合部门", width = 15, dictTable = "sys_depart where depart_name like '%部' or depart_name like '%处'", dicText = "depart_name", dicCode = "id")@Dict(dictTable = "sys_depart where depart_name like '%部' or depart_name like '%处'", dicText = "depart_name", dicCode = "id")@Schema(description = "配合部门")private java.lang.String cooperatedept;/**创建人部门id*/@Excel(name = "部门id", width = 15)@Schema(description = "部门id")private java.lang.String createByDepartId;
}

数据访问层和服务层设计:

现在数据库和实体类都设计好了,就开始编写数据访问层和服务层,然后编写控制类实现接口,准备提供给前端。

要实现查询数据库中的所需要显示的数据的条数,写一个xml,编写sql语句查询。

<select id="ReceiveSumOfKpi" resultType="integer" parameterType="string">SELECT COUNT(*) as total_countfrom yx_kpi as k INNER JOIN yx_tobedone as twhere t.kpi_id=k.id and t.coop_depart=#{orgId} and t.taskstatus=#{status};</select>

进行表连接,然后根据where语句去查配合部门为该部门,状态为传入状态的数据,并使用count进行计数。

有了xml就实现数据访问层和服务层接口,都编写一个方法:

//记录接收年度关键指标记录的总数int ReceiveSumOfKpi(String orgId,String status);

这里注意mapper接口要使用@Mapper注解。

然后实现服务层接口,编写一个实现类:

/*接收年度关键指标记录的总数* */@Overridepublic int ReceiveSumOfKpi(String orgId, String status) {return tobedoneMapper.ReceiveSumOfKpi(orgId,status);}

控制类设计:

最后实现控制类,加上权限管理。

/** 接收年度关键指标列表总数的记录* */@RequiresPermissions("Receive_kpi:yx_Receive_kpi:ReceiveSumOfKpi")@Transactional//事务处理注解@RequestMapping(value = "/ReceiveSumOfKpi",method = {RequestMethod.GET,RequestMethod.POST})public int ReceiveSumOfKpi(){LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();int sum=tobedoneService.ReceiveSumOfKpi(sysUser.getOrgId(),Constants.TODO);System.out.println(sum);return sum;}

这样后端的接口就写好了,这里控制类没有写全,接口是/tobedone/tobedone下的ReceiveSumOfKpi。

前端设计:

我在前端和后端都实现了权限管理,这里不主要说权限管理的方法,主要说交互的方法。

api设计:

首先想往前端传数据,前端得拿到后端的接口,这就编写一个api用来调用后端的接口。

import axios from 'axios';
import { getToken } from '/@/utils/auth';
import { useGlobSetting } from '/@/hooks/setting';const globSetting = useGlobSetting();
const baseUrl = globSetting.apiUrl;// 创建axios实例
const api = axios.create({baseURL: baseUrl + '/tobedone/tobedone', // 使用全局配置的API基础URLheaders: {'Content-Type': 'application/json'},timeout: 15000 // 请求超时时间
});// 请求拦截器 - 添加授权令牌
api.interceptors.request.use((config) => {const token = getToken();if (token) {// 在请求头中添加tokenconfig.headers['X-Access-Token'] = token;}return config;},(error) => {return Promise.reject(error);}
);// 响应拦截器 - 处理错误
api.interceptors.response.use((response) => {return response.data;},(error) => {console.error('API请求错误:', error);return Promise.reject(error);}
);// 待办看板相关api
export const KanBanApi = {// 获取接收年度关键指标列表的总数ReceiveSumOfKpi: () => api.get('/ReceiveSumOfKpi'),// 获取汇报年度关键指标列表的总数ReportSumOfKpi: () => api.get('/ReportSumOfKpi'),// 获取审批年度关键指标列表的总数ApprovalSumOfKpi: () => api.post('/ApprovalSumOfKpi'),//年度关键指标记录的总数KpiSum: () => api.get('/KpiSum'),
};export default api;

主要就是创建axios实例,请求拦截器和响应拦截器。核心功能还是export导出的相关api。

前面有点像方法名,用来前端调用这个方法,然后会使用api.get去调用后端的接口,这里没有/tobedone/tobedone是因为在创建axios实例的时候设置了baseUrl。

现在api也设计好了,就开始写前端页面。

页面设计:

<template><div class="card-container"><div class="card-item" v-auth="'Receive_kpi:yx_Receive_kpi:ReceiveSumOfKpi'"><div class="text">{{cardList[0].title}}</div><div class="count">{{cardList[0].count}}</div></div><div class="card-item" v-auth="'Report_kpi:yx_Report_kpi:ReportSumOfKpi'"><div class="text">{{cardList[1].title}}</div><div class="count">{{cardList[1].count}}</div></div><div class="card-item" v-auth="'Approval_kpi:yx_Approval_kpi:ApprovalSumOfKpi'"><div class="text">{{cardList[2].title}}</div><div class="count">{{cardList[2].count}}</div></div><div class="card-item" v-auth="'kpi:yx_kpi:KpiSum'"><div class="text">{{cardList[3].title}}</div><div class="count">{{cardList[3].count}}</div></div></div>
</template><script setup lang="ts">
import {onMounted, ref} from 'vue';
import {KanBanApi} from "@/views/ToDoKanBan/ToDoKanBan.api";
const cardList=ref([{title:"接收年度关键指标",count:null},{title:"汇报年度关键指标",count:null},{title:"审批年度关键指标",count:null},{title:"年度关键指标列表", count:null}
]);// 页面加载时获取接收年度关键指标记录的总数
onMounted(async () => {try {const responseOfReceiveSumOfKpi = await KanBanApi.ReceiveSumOfKpi();const responseOfReportSumOfKpi = await KanBanApi.ReportSumOfKpi();const responseOfApprovalSumOfKpi = await KanBanApi.ApprovalSumOfKpi();const responseKpiSum= await KanBanApi.KpiSum();// 如果返回的直接就是数字cardList.value[0].count = responseOfReceiveSumOfKpi;cardList.value[1].count = responseOfReportSumOfKpi;cardList.value[2].count = responseOfApprovalSumOfKpi;cardList.value[3].count = responseKpiSum;} catch (error) {console.error('获取指标数量失败:', error);}
});
</script>
<style scoped lang="less">
.card-container {display: flex;flex-wrap: wrap;gap: 20px;padding: 20px;
}
.card-item {width: calc(25% - 20px); /* 每行4个,可根据需求调整 */background-color: #0b3b9c;border-radius: 8px;color: #fff;text-align: center;padding: 15px;box-sizing: border-box;
}
.text {margin-bottom: 6px;
}.count {font-size: 14px;
}
</style>

前端模板主要用来显示cardList的title和count,而count的显示方法在页面加载的时候就进行方法挂载了。调用了四个api,分别赋值给cardList.value[0].count等。这样就可以显示了。实现了前后端的交互。

传参的时候传字段和传对象的区别和方法?

传参的时候传递字段:

传递字段就是将多个独立的字段作为方法的参数逐个传递。

演示代码:

// 传递单个字段
public class UserService {// 方法接收多个独立字段作为参数public void createUser(String username, int age, String email) {System.out.println("创建用户: " + username + ", 年龄: " + age + ", 邮箱: " + email);}
}// 调用方式
public class Main {public static void main(String[] args) {UserService service = new UserService();// 逐个传递字段service.createUser("张三", 25, "zhangsan@example.com");}
}

传递字段的好处就是简单直接,适合参数数量少的且关联性低的场景,调用的时候直观,无需创建额外的对象。缺点就是参数数量多的时候方法签名冗长,当参数需要新增或者修改的时候需要修改签名,违反开闭原则,并且如果参数顺序错误也会导致错误。

传参的时候传递对象:

传递对象就是将多个字段封装到一个对象中,方法仅接收该对象作为参数。

演示代码:

// 1. 定义封装参数的对象
public class User {private String username;private int age;private String email;// 构造方法、getter和setterpublic User(String username, int age, String email) {this.username = username;this.age = age;this.email = email;}// getter和setter省略...
}// 2. 方法接收对象作为参数
public class UserService {// 仅接收一个User对象public void createUser(User user) {System.out.println("创建用户: " + user.getUsername() + ", 年龄: " + user.getAge() + ", 邮箱: " + user.getEmail());}
}// 3. 调用方式
public class Main {public static void main(String[] args) {UserService service = new UserService();// 创建对象并传递User user = new User("张三", 25, "zhangsan@example.com");service.createUser(user);}
}

传递参数的时候关联性强,无需修改方法的签名,参数增减的时候只需要扩展字段就可以了。避免参数顺序混淆,能够降低出错概率。缺点就是需要额外定义对象类,增加代码量。

http://www.dtcms.com/a/337736.html

相关文章:

  • 音乐怎么测试?正在播放音乐,中途拔掉u盘,再次插上u盘,是怎么播放的?
  • 低端设备加载webp ANR
  • JavaScript 常用事件总结汇总
  • 前端css学习笔记7:各种居中布局空白问题
  • Ethan独立开发新品速递 | 2025-08-18
  • 开发避坑指南(28):Spring Boot端点检查禁用失效解决方案
  • 【Linux操作系统】简学深悟启示录:进程状态优先级
  • 遨游三防科普|三防平板是指哪三防?应用在什么场景?
  • linux对外提供snmp服务
  • Pytest项目_day18(读取ini文件)
  • Spring Boot 实用小技巧:多级缓存(Caffeine + Redis)- 第545篇
  • 如何解决机器翻译的“幻觉“问题(Hallucination)?
  • 当AI学会“思考”:大语言模型背后的智能本质与伦理边界
  • 【提示词技巧】通用提示词原则介绍
  • Linux学习-软件编程(进程间通信1)
  • ROS 2 中用于建图的一些 topic
  • PyTorch神经网络工具箱(优化器)
  • buuctf:护网杯_2018_gettingstart、oneshot_tjctf_2016
  • llamafactory使用qlora训练
  • VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
  • 使用LLaMA-Factory对大模型进行微调-详解
  • OSG+Qt —— 笔记2- Qt窗口绘制棋盘及模型周期运动(附源码)
  • linux:告别SSH断线烦恼,Screen命令核心使用指南
  • 第四章:大模型(LLM)】07.Prompt工程-(1)Prompt 原理与基本结构
  • 大数据分析-读取文本文件内容进行词云图展示
  • Zephyr 中的 bt_le_per_adv_set_data 函数的介绍和应用方法
  • [机器学习]09-基于四种近邻算法的鸢尾花数据集分类
  • 具身智能赋能轮椅机器人的认知革命与人机共生新范式
  • 【软考架构】第4章 信息安全的抗攻击技术
  • 从「行走」到「思考」:机器人进化之路与感知—决策链路的工程化实践