SpringCloud+Vue3主子表插入数据(芋道)

目的:多表联查获取到每个班级里面所有的学生上课的信息。点击消课插入到消课主表和消课子表,主表记录班级信息,消课人员信息,上课时间。子表记录上课学员的信息,学员姓名、手机号、班级名称、班级类型、上课时间、老师名称

前端:

html 复制代码
<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
<!-- 列表 -->

<ContentWrap>
  <el-button
          type="primary"
          plain
         @click="submitForm"
        >
          消课
        </el-button>
  <el-table v-loading="loading" :data="list" 
  :stripe="true" 
  :show-overflow-tooltip="true"
  @selection-change="handleSelectionChange"
  >
  <el-table-column
    label="序号"
    type="index"
    header-align="center"
    align="center"
    width="60px"
    fixed
   />
   <el-table-column type="selection" width="55" />
    <el-table-column label="班级名称" align="center" prop="className" />
    <el-table-column label="班级类型" align="center" prop="classType" width="100px">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.COURSE_TYPE" :value="scope.row.classType" />
          </template>
        </el-table-column>
    <el-table-column label="学生姓名" align="center" prop="stsStudentName" />
    <el-table-column label="手机号" align="center" prop="stsPhone" />
    <el-table-column label="所报课程" align="center" prop="courseName" />
    <el-table-column label="上课时间" align="center" prop="firstClassStartTime" />
    <!-- <el-table-column
      label="上课时间"
      align="center"
      prop="classTime"
      :formatter="dateFormatter"
      width="180px"
    /> -->
    <el-table-column label="授课教师" align="center" prop="teacherName" />
    
  </el-table>

  <!-- 分页 -->
  <Pagination
    :total="total"
    v-model:page="queryParams.pageNo"
    v-model:limit="queryParams.pageSize"
    @pagination="getList"
  />
</ContentWrap>


</Dialog>
</template>

<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CancleClassApi, CancleClassVO } from '@/api/study/cancleclass'
import { ref } from 'vue';

/** 消课记录 列表 */
defineOptions({ name: 'CancleClass' })
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,

})
const formData = ref({
  id: undefined,
  studentId: undefined
})

const emit = defineEmits(['clickChild'])
const studentId = ref([])
const handleSelectionChange = (val: CancleClassVO[]) => {
  studentId.value = []
  for (let i = 0; i < val.length; i++) {
    studentId.value.push(val[i])
  }
}
const submitForm=async ()=>{
  const tableData = formData.value as unknown as CancleClassVO
  tableData.studentId = studentId.value
  await CancleClassApi.createCancleClass(tableData)
  //传递给父组件
  dialogVisible.value = false;  
}
const open = async (type: string, classId?: number) => {
  dialogVisible.value = true
  loading.value = true
try {
  const data = await CancleClassApi.getCancleClassDetail(classId)
  list.value = data
} finally {
  loading.value = false
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 查询列表 */
// const getList = async () => {

// }


// onMounted(() => {
// getList()
// })
</script>
<style scoped lang="scss">

:deep(.el-dialog__body){
  width: 1000px !important;
  height: 1000px !important; 
}
</style>

关键:

html 复制代码
const formData = ref({
  id: undefined,
  studentId: undefined
})


const studentId = ref([])
const handleSelectionChange = (val: CancleClassVO[]) => {
  studentId.value = []
  for (let i = 0; i < val.length; i++) {
    studentId.value.push(val[i])
  }
}
const submitForm=async ()=>{
  const tableData = formData.value as unknown as CancleClassVO
  tableData.studentId = studentId.value
  await CancleClassApi.createCancleClass(tableData)
  //传递给父组件
  dialogVisible.value = false;  
}

index.ts

html 复制代码
import request from '@/config/axios'

// 消课记录 VO
export interface CancleClassVO {
  id: number // 主键id
  className: string // 班级名称
  classType: string // 班级类型
  reportCourse: string // 所报课程
  classTime: Date // 上课时间
  classTeacher: string // 授课教师
  cancelClassPerson: string // 消课人
  cancelClassTime: Date // 消课时间
  studentName: string // 学员姓名
  phone: string // 手机号
  arrivedNum: number // 实到人数
  arrivingNum: number // 应到人数
  rollCallPerson: string // 点名操作人员
  rollCallTime: Date // 店面时间
  operaName: string // 操作人
  operaTime: Date // 操作时间
  operaType: string // 操作类型
  operaExplain: string // 操作说明
  studentId: any
}

// 消课记录 API
export const CancleClassApi = {
  // 查询消课记录分页
  getCancleClassPage: async (params: any) => {
    return await request.get({ url: `/study/cancle-class/page`, params })
  },

    // 查询消课记录分页
    getCancleClassPage2: async (params: any) => {
      return await request.get({ url: `/study/cancle-class/page2`, params })
    },
  

  // 查询消课记录详情
  getCancleClass: async (id: number) => {
    return await request.get({ url: `/study/cancle-class/get?id=` + id })
  },

    // 查询消课记录详情
    getCancleClass2: async (id: number) => {
      return await request.get({ url: `/study/cancle-class/get2?id=` + id })
    },

  // 查询消课记录详情
  getCancleClassDetail: async (id: number) => {
   return await request.gets({ url: `/study/cancle-class/findByIds?id=` + id })
 },

   // 查询消课记录详情2
   getFindDetail: async (id: number) => {
    return await request.gets({ url: `/study/cancle-class/findDetail?id=` + id })
  },

  // 新增消课记录
  createCancleClass: async (data: CancleClassVO) => {
    return await request.post({ url: `/study/cancle-class/create`, data })
  },

  // 修改消课记录
  updateCancleClass: async (data: CancleClassVO) => {
    return await request.put({ url: `/study/cancle-class/update`, data })
  },

  // 删除消课记录
  deleteCancleClass: async (id: number) => {
    return await request.delete({ url: `/study/cancle-class/delete?id=` + id })
  },

  // 导出消课记录 Excel
  exportCancleClass: async (params) => {
    return await request.download({ url: `/study/cancle-class/export-excel`, params })
  },
}

关键:

html 复制代码
studentId: any

解析:通过遍历studentId来往后端传值,传的是对象的数组,后端通过studentId来遍历插入值

通过const tableData = formData.value as unknown as CancleClassVO映射往后端传值

html 复制代码
// 消课记录 VO
export interface CancleClassVO {
  id: number // 主键id
  className: string // 班级名称
  classType: string // 班级类型
  reportCourse: string // 所报课程
  classTime: Date // 上课时间
  classTeacher: string // 授课教师
  cancelClassPerson: string // 消课人
  cancelClassTime: Date // 消课时间
  studentName: string // 学员姓名
  phone: string // 手机号
  arrivedNum: number // 实到人数
  arrivingNum: number // 应到人数
  rollCallPerson: string // 点名操作人员
  rollCallTime: Date // 店面时间
  operaName: string // 操作人
  operaTime: Date // 操作时间
  operaType: string // 操作类型
  operaExplain: string // 操作说明
  studentId: any
}

调用新增方法往后台插入值

await CancleClassApi.createCancleClass(tableData)

后端:

不仅要给主表建实体类,保存回显方法,还要给子表建立相应的实体类,保存回显方法。

项目架构:

controller:

实体类:

Mapper:

Service和实现类:

主表

实体类:

java 复制代码
package com.todod.education.module.study.dal.dataobject.cancleclass;

import lombok.*;

import java.sql.Time;
import java.time.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.todod.education.framework.mybatis.core.dataobject.BaseDO;

/**
 * 消课记录 DO
 *
 * @author 平台管理员
 */
@TableName("study_cancle_class")
@KeySequence("study_cancle_class_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CancleClassDO extends BaseDO {

    /**
     * 主键id
     */
    @TableId
    private Long id;

    /**
     * 班级id
     */
    private Long classId;
    /**
     * 课程id
     */
    private Long courseId;
    /**
     * 学员姓名
     */
    @TableField(exist = false)
    private String stsStudentName;
    /**
     * 手机号
     */
    @TableField(exist = false)
    private String stsPhone;
    /**
     * 班级名称
     */
    @TableField(exist = false)
    private String className;
    /**
     * 班级类型
     */
    @TableField(exist = false)
    private String classType;
    /**
     * 所报课程
     */
    @TableField(exist = false)
    private String courseNames;
    /**
     * 所报课程
     */
    @TableField(exist = false)
    private String courseName;
    /**
     * 授课教师
     */
    @TableField(exist = false)
    private String teacherNames;

    /**
     * 授课教师
     */
    @TableField(exist = false)
    private String teacherName;

    /**
     * 上课时间
     */
    @TableField(exist = false)
    private Time firstClassStartTime;

    /**
     * 上课日期
     */
    @TableField(exist = false)
    private Date firstClassDate;

    /**
     * 消课人
     */
    private String cancelClassPerson;
    /**
     * 消课时间
     */
    private LocalDateTime cancelClassTime;

    /**
     * 实到人数
     */
    private Integer arrivedNum;
    /**
     * 应到人数
     */
    private Integer arrivingNum;
    /**
     * 点名操作人员
     */
    private String rollCallPerson;
    /**
     * 点名时间
     */
    private LocalDateTime rollCallTime;
    /**
     * 操作人
     */
    private String operaName;
    /**
     * 操作时间
     */
    private LocalDateTime operaTime;
    /**
     * 操作类型
     */
    private String operaType;
    /**
     * 操作说明
     */
    private String operaExplain;

}

由于多表联查所以在这个表里的实体类映射的时候,很多字段是从别的表里获取的,所以要加上这句话

复制代码
@TableField(exist = false)

否则会去数据库里查相应字段报错。

controller:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass;

import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;

import com.todod.education.framework.common.pojo.PageParam;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.CommonResult;
import com.todod.education.framework.common.util.object.BeanUtils;
import static com.todod.education.framework.common.pojo.CommonResult.success;

import com.todod.education.framework.excel.core.util.ExcelUtils;

import com.todod.education.framework.apilog.core.annotation.ApiAccessLog;
import static com.todod.education.framework.apilog.core.enums.OperateTypeEnum.*;

import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.module.study.service.cancleclass.CancleClassService;

@Tag(name = "管理后台 - 消课记录")
@RestController
@RequestMapping("/study/cancle-class")
@Validated
public class CancleClassController {

    @Resource
    private CancleClassService cancleClassService;

    @PostMapping("/create")
    @Operation(summary = "创建消课记录")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:create')")
    public CommonResult<Long> createCancleClass(@Valid @RequestBody CancleClassSaveReqVO createReqVO) {
        return success(cancleClassService.createCancleClass(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新消课记录")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:update')")
    public CommonResult<Boolean> updateCancleClass(@Valid @RequestBody CancleClassSaveReqVO updateReqVO) {
        cancleClassService.updateCancleClass(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除消课记录")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('study:cancle-class:delete')")
    public CommonResult<Boolean> deleteCancleClass(@RequestParam("id") Long id) {
        cancleClassService.deleteCancleClass(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得消课记录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:query')")
    public CommonResult<CancleClassRespVO> getCancleClass(@RequestParam("id") Long id) {
        CancleClassDO cancleClass = cancleClassService.getCancleClass(id);
        return success(BeanUtils.toBean(cancleClass, CancleClassRespVO.class));
    }

    @GetMapping("/findByIds")
    public List<CancleClassDO> findUsersByIds(@RequestParam Long id) {
        return cancleClassService.selectCheck(id);
    }

    @GetMapping("/findDetail")
    public List<CancleClassDO> findDetail(@RequestParam Long id) {
        return cancleClassService.selectDetail(id);
    }

    @GetMapping("/get2")
    @Operation(summary = "获得消课记录2")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:query')")
    public CommonResult<CancleClassRespVO> getCancleClass2(@RequestParam("id") Long id) {
        CancleClassDO cancleClass = cancleClassService.getCancleClass2(id);
        return success(BeanUtils.toBean(cancleClass, CancleClassRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得消课记录分页")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:query')")
    public CommonResult<PageResult<CancleClassRespVO>> getCancleClassPage(@Valid CancleClassPageReqVO pageReqVO) {
        PageResult<CancleClassDO> pageResult = cancleClassService.getCancleClassPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, CancleClassRespVO.class));
    }

    @GetMapping("/page2")
    @Operation(summary = "获得消课记录分页2")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:query')")
    public CommonResult<PageResult<CancleClassRespVO>> getCancleClassPage2(@Valid CancleClassPageReqVO pageReqVO) {
        PageResult<CancleClassDO> pageResult = cancleClassService.getCancleClassPage2(pageReqVO);
        return success(BeanUtils.toBean(pageResult, CancleClassRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出消课记录 Excel")
    @PreAuthorize("@ss.hasPermission('study:cancle-class:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportCancleClassExcel(@Valid CancleClassPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<CancleClassDO> list = cancleClassService.getCancleClassPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "消课记录.xls", "数据", CancleClassRespVO.class,
                        BeanUtils.toBean(list, CancleClassRespVO.class));
    }

}

主要看create新增方法,插入主表子表有这一个新增方法即可

CancleClassSaveReqVO:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass.vo;

import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;

@Schema(description = "管理后台 - 消课记录新增/修改 Request VO")
@Data
public class CancleClassSaveReqVO {

    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")
    private Long id;

    @Schema(description = "学员id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")
    private List<CancleClassInfoDO> studentId;

    @Schema(description = "课程id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")
    private Long courseId;

    @Schema(description = "班级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")
    private Long classId;

    @Schema(description = "上课时间")
    private LocalDateTime classTime;

    @Schema(description = "消课人")
    private String cancelClassPerson;

    @Schema(description = "消课时间")
    private LocalDateTime cancelClassTime;

    @Schema(description = "实到人数")
    private Integer arrivedNum;

    @Schema(description = "应到人数")
    private Integer arrivingNum;

    @Schema(description = "点名操作人员")
    private String rollCallPerson;

    @Schema(description = "点名时间")
    private LocalDateTime rollCallTime;

    @Schema(description = "操作人", example = "王五")
    private String operaName;

    @Schema(description = "操作时间")
    private LocalDateTime operaTime;

    @Schema(description = "操作类型", example = "2")
    private String operaType;

    @Schema(description = "操作说明")
    private String operaExplain;

}

CancleClassRespVO:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass.vo;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

import java.sql.Time;
import java.time.LocalTime;
import java.util.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;

@Schema(description = "管理后台 - 消课记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CancleClassRespVO {


    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long id;

    @Schema(description = "学员id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long studentId;

    @Schema(description = "班级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long classId;

    @Schema(description = "课程id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long courseId;

    @Schema(description = "学员姓名", example = "芋艿")
    private String stsStudentName;

    @Schema(description = "手机号")
    private String stsPhone;

    @Schema(description = "班级名称", example = "李四")
    @ExcelProperty("班级名称")
    private String className;

    @Schema(description = "班级类型", example = "1")
    @ExcelProperty("班级类型")
    private String classType;

    @Schema(description = "所报课程")
    @ExcelProperty("所报课程")
    private String courseNames;

    @Schema(description = "所报课程")
    @ExcelProperty("所报课程")
    private String courseName;

    @Schema(description = "上课时间")
    private Time firstClassStartTime;

    @Schema(description = "上课日期")
    private Date firstClassDate;

    @Schema(description = "授课教师")
    @ExcelProperty("授课教师")
    private String teacherNames;

    @Schema(description = "授课教师")
    @ExcelProperty("授课教师")
    private String teacherName;

    @Schema(description = "消课人")
    @ExcelProperty("消课人")
    private String cancelClassPerson;

    @Schema(description = "消课时间")
    @ExcelProperty("消课时间")
    private LocalDateTime cancelClassTime;

    @Schema(description = "创建时间")
    @ExcelProperty("创建时间")
    private LocalDateTime createTime;


    @Schema(description = "操作人", example = "王五")
    private String operaName;

    @Schema(description = "操作时间")
    private LocalDateTime operaTime;

    @Schema(description = "操作类型", example = "2")
    private String operaType;

    @Schema(description = "操作说明")
    private String operaExplain;

    @Schema(description = "实到人数")
    private Integer arrivedNum;

    @Schema(description = "应到人数")
    private Integer arrivingNum;

    @Schema(description = "点名操作人员")
    private String rollCallPerson;

    @Schema(description = "点名时间")
    private LocalDateTime rollCallTime;
}

CancleClassPageReqVO:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass.vo;

import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.todod.education.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;

import static com.todod.education.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;

@Schema(description = "管理后台 - 消课记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CancleClassPageReqVO extends PageParam {


    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long id;

    @Schema(description = "班级名称", example = "李四")
    private String className;

    @Schema(description = "上课时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private LocalDateTime[] classTime;

    @Schema(description = "消课时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private LocalDateTime[] cancelClassTime;

    @Schema(description = "创建时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private LocalDateTime[] createTime;

    @Schema(description = "所报课程", example = "李四")
    private String courseName;

    @Schema(description = "学员姓名")
    private String stsStudentName;

    @Schema(description = "手机号")
    private String stsPhone;
}

Mapper:

java 复制代码
package com.todod.education.module.study.dal.mysql.cancleclass;

import java.util.*;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.todod.education.framework.mybatis.core.mapper.BaseMapperX;
import com.todod.education.module.study.controller.admin.entranceexam.vo.EntranceExamPageReqVO;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.module.study.dal.dataobject.entranceexam.EntranceExamDO;
import org.apache.ibatis.annotations.Mapper;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import org.apache.ibatis.annotations.Param;

/**
 * 消课记录 Mapper
 *
 * @author 平台管理员
 */
@Mapper
public interface CancleClassMapper extends BaseMapperX<CancleClassDO> {

    default PageResult<CancleClassDO> selectPage(CancleClassPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<CancleClassDO>()
                .likeIfPresent(CancleClassDO::getClassName, reqVO.getClassName())
                .betweenIfPresent(CancleClassDO::getCancelClassTime, reqVO.getCancelClassTime())
                .betweenIfPresent(CancleClassDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(CancleClassDO::getId));
    }

    IPage<CancleClassDO> fetchPageResults(IPage<CancleClassDO> page, @Param("queryEntry") CancleClassPageReqVO pageReqVO);

    List<CancleClassDO> selectCheck(@Param("id") Long id);

    List<CancleClassDO> selectDetail(@Param("id") Long id);


}

Service:

java 复制代码
package com.todod.education.module.study.service.cancleclass;

import java.util.*;
import jakarta.validation.*;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.PageParam;

/**
 * 消课记录 Service 接口
 *
 * @author 平台管理员
 */
public interface CancleClassService {

    /**
     * 创建消课记录
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    Long createCancleClass(@Valid CancleClassSaveReqVO createReqVO);

    /**
     * 更新消课记录
     *
     * @param updateReqVO 更新信息
     */
    void updateCancleClass(@Valid CancleClassSaveReqVO updateReqVO);

    /**
     * 删除消课记录
     *
     * @param id 编号
     */
    void deleteCancleClass(Long id);

    /**
     * 获得消课记录
     *
     * @param id 编号
     * @return 消课记录
     */
    CancleClassDO getCancleClass(Long id);

    /**
     * 获得消课记录
     *
     * @param id 编号
     * @return 消课记录
     */
    CancleClassDO getCancleClass2(Long id);



    /**
     * 获得消课记录分页
     *
     * @param pageReqVO 分页查询
     * @return 消课记录分页
     */
    PageResult<CancleClassDO> getCancleClassPage(CancleClassPageReqVO pageReqVO);

    /**
     * 获得消课记录分页2
     *
     * @param pageReqVO 分页查询
     * @return 消课记录分页
     */
    PageResult<CancleClassDO> getCancleClassPage2(CancleClassPageReqVO pageReqVO);

    List<CancleClassDO> selectCheck(Long id);

    List<CancleClassDO> selectDetail(Long id);



}

实现类:

java 复制代码
package com.todod.education.module.study.service.cancleclass;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction;
import com.mzt.logapi.starter.annotation.LogRecord;
import com.todod.education.module.study.controller.admin.monthexam.vo.MonthExamPageReqVO;
import com.todod.education.module.study.controller.admin.plan.vo.PlanSaveReqVO;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import com.todod.education.module.study.dal.dataobject.monthexam.MonthExamDO;
import com.todod.education.module.study.dal.dataobject.plan.PlanDO;
import com.todod.education.module.study.dal.mysql.cancleclass.CancleClassInfoMapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.PageParam;
import com.todod.education.framework.common.util.object.BeanUtils;

import com.todod.education.module.study.dal.mysql.cancleclass.CancleClassMapper;

import static com.todod.education.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.todod.education.module.study.enums.ErrorCodeConstants.*;
import static com.todod.education.module.system.enums.LogRecordConstants.*;

/**
 * 消课记录 Service 实现类
 *
 * @author 平台管理员
 */
@Service
@Validated
public class CancleClassServiceImpl implements CancleClassService {

    @Resource
    private CancleClassMapper cancleClassMapper;

    @Resource
    private CancleClassInfoMapper cancleClassInfoMapper;

    @Override
    @LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",
            success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)
    public Long createCancleClass(CancleClassSaveReqVO createReqVO) {
        if(createReqVO.getStudentId().size() == 0){
            throw exception(CANCLE_CLASS_NOT_EXISTS);
        }
        // 插入
        CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);
        cancleClassMapper.insert(cancleClass);

        List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();
        for (CancleClassInfoDO studentId : studentIds) {
            CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();
            cancleClassInfoDO.setStudentId(studentId.getStudentId());
            cancleClassInfoDO.setStudentName(studentId.getStudentName());
            cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());
            cancleClassInfoDO.setClassType(studentId.getClassType());
            cancleClassInfoDO.setClassName(studentId.getClassName());
            cancleClassInfoDO.setCourseName(studentId.getCourseName());
            cancleClassInfoDO.setTeacherName(studentId.getTeacherName());
            cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());
            cancleClassInfoDO.setId(studentId.getId());
            cancleClassInfoMapper.insert(cancleClassInfoDO);
        }

// 3. 记录操作日志上下文
        LogRecordContext.putVariable("cancleClass", cancleClass);
        return cancleClass.getId();

    }

//    @Override
//    @LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",
//            success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)
//    public Long createCancleClass(CancleClassSaveReqVO createReqVO) {
//        // 插入
//        CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);
//        cancleClassMapper.insert(cancleClass);
//
//        // 3. 记录操作日志上下文
//        LogRecordContext.putVariable("cancleClass", cancleClass);
//
//        // 返回
//        return cancleClass.getId();
//    }

    @Override
    @LogRecord(type = STUDY_PLAN_TYPE, subType = STUDY_CANCLE_CLASS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
            success = STUDY_CANCLE_CLASS_UPDATE_SUCCESS)
    public void updateCancleClass(CancleClassSaveReqVO updateReqVO) {
        // 校验存在
        validateCancleClassExists(updateReqVO.getId());

        CancleClassDO oldCancleClassDO = cancleClassMapper.selectById(updateReqVO.getId());

        // 更新
        CancleClassDO updateObj = BeanUtils.toBean(updateReqVO, CancleClassDO.class);
        cancleClassMapper.updateById(updateObj);
        // 3. 记录操作日志上下文
        LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCancleClassDO, PlanSaveReqVO.class));
        LogRecordContext.putVariable("cancleClass", oldCancleClassDO);
    }

    @Override
    @LogRecord(type = STUDY_PLAN_TYPE, subType = STUDY_CANCLE_CLASS_DELETE_SUB_TYPE, bizNo = "{{#id}}",
            success = STUDY_CANCLE_CLASS_DELETE_SUCCESS)
    public void deleteCancleClass(Long id) {
        // 校验存在
        validateCancleClassExists(id);

        CancleClassDO oldCancleClassDO = cancleClassMapper.selectById(id);

        // 删除
        cancleClassMapper.deleteById(id);

        // 3. 记录操作日志上下文
        LogRecordContext.putVariable("cancleClass", oldCancleClassDO);
    }

    private void validateCancleClassExists(Long id) {
        if (cancleClassMapper.selectById(id) == null) {
            throw exception(CANCLE_CLASS_NOT_EXISTS);
        }
    }

    @Override
    public CancleClassDO getCancleClass(Long id) {
        return cancleClassMapper.selectById(id);
    }

    @Override
    public CancleClassDO getCancleClass2(Long id) {
        return cancleClassMapper.selectById(id);
    }

    @Override
    public PageResult<CancleClassDO> getCancleClassPage(CancleClassPageReqVO pageReqVO) {
        return cancleClassMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<CancleClassDO> getCancleClassPage2(CancleClassPageReqVO pageReqVO) {
        IPage<CancleClassDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        cancleClassMapper.fetchPageResults(page, pageReqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public List<CancleClassDO> selectCheck(Long id) {
        return cancleClassMapper.selectCheck(id);
    }

    @Override
    public List<CancleClassDO> selectDetail(Long id) {
        return cancleClassMapper.selectDetail(id);
    }





}

XML文件:

java 复制代码
<?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.todod.education.module.study.dal.mysql.cancleclass.CancleClassMapper">

    <select id="fetchPageResults" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">
        SELECT tcm.class_name,tcm.id AS class_id,tcm.class_type,tcmc.teacherNames,tcmc.courseNames,tcms.students,
        FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,
        FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_date

        FROM teach_class_manage tcm
        INNER JOIN (
        SELECT tcmc.class_id,string_agg(htm.teacher_name, ',') AS teacherNames,string_agg(tcm.course_name, ',') AS courseNames

        FROM teach_class_manage_course tcmc
        INNER JOIN hr_teacher_manage htm ON htm."id" = tcmc.teacher_id
        INNER JOIN teach_course_manage tcm ON tcm."id" = tcmc.course_id
        GROUP BY tcmc.class_id
        ) tcmc ON tcm."id" = tcmc.class_id
        LEFT JOIN (
        SELECT tcms.class_id,COALESCE(COUNT(*), 0) AS students

        FROM teach_class_manage_student tcms
        GROUP BY tcms.class_id
        ) tcms ON  tcm."id" = tcms.class_id
        LEFT JOIN study_time_table stt ON stt.study_course_id = ANY(ARRAY(SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id))
        WHERE 1 = 1 AND tcm.deleted = 0

        <if test=" queryEntry.stsStudentName != null and queryEntry.stsStudentName != '' and queryEntry.stsStudentName != 'null' ">
            AND ss.sts_student_name like '%${queryEntry.stsStudentName}'
        </if>
        ORDER BY
        tcm.create_time desc
    </select>

    <select id="selectCheck" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">
        SELECT
        tcm.class_name,
        tcm.class_type,
        ss.sts_student_name,
        FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,
--                 FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_date
        ss.sts_phone,
        tcs.student_id,
        tcmc.course_id,
        tcm2.course_name,
        htm.teacher_name
        FROM
        teach_class_manage tcm
        JOIN teach_class_manage_student tcs ON tcm.id = tcs.class_id
        JOIN study_student ss ON tcs.student_id = ss.id
        JOIN teach_class_manage_course tcmc ON tcm.id = tcmc.class_id
        JOIN teach_course_manage tcm2 ON tcmc.course_id = tcm2.id
        JOIN hr_teacher_manage htm ON tcmc.teacher_id = htm.id
        LEFT JOIN study_time_table stt ON stt.study_course_id = ANY(ARRAY(SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id))
        WHERE
        tcm.id = #{id}
        ORDER BY
        tcs.student_id, tcmc.course_id;


    </select>

    <select id="selectDetail" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">
        SELECT
            tcm.class_name,
            tcm.id AS class_id,
            tcm.class_type,
            tcmc.teacherNames,
            tcmc.courseNames,
            tcms.students,
            FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,
                FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_date
        FROM
            teach_class_manage tcm
                INNER JOIN (
                SELECT
                    tcmc.class_id,
                    string_agg(htm.teacher_name, ',') AS teacherNames,
                    string_agg(tcm.course_name, ',') AS courseNames
                FROM
                    teach_class_manage_course tcmc
                        INNER JOIN hr_teacher_manage htm ON htm.id = tcmc.teacher_id
                        INNER JOIN teach_course_manage tcm ON tcm.id = tcmc.course_id
                GROUP BY
                    tcmc.class_id
            ) tcmc ON tcm.id = tcmc.class_id
                LEFT JOIN (
                SELECT
                    tcms.class_id,
                    COALESCE(COUNT(*), 0) AS students
                FROM
                    teach_class_manage_student tcms
                GROUP BY
                    tcms.class_id
            ) tcms ON tcm.id = tcms.class_id
                LEFT JOIN study_time_table stt ON stt.study_course_id IN (SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id)
        WHERE
            tcm.deleted = 0
          AND tcm.id = 9 -- 替换为实际的参数或变量
        ORDER BY
            tcm.create_time DESC;
    </select>

</mapper>

从表

CancleClassInfoSaveReqVO:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass.vo;

import com.alibaba.excel.annotation.ExcelProperty;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.sql.Time;
import java.time.LocalDateTime;
import java.util.List;

@Schema(description = "管理后台 - 消课记录新增/修改 Request VO")
@Data
public class CancleClassInfoSaveReqVO {

    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")
    private Long id;

    @Schema(description = "学员id", example = "21490")
    private List<CancleClassInfoDO> studentId;

    @Schema(description = "学员姓名", example = "芋艿")
    private String studentName;

    @Schema(description = "手机号")
    private String studentPhone;

    @Schema(description = "班级名称", example = "李四")
    @ExcelProperty("班级名称")
    private String className;

    @Schema(description = "班级类型", example = "1")
    @ExcelProperty("班级类型")
    private String classType;

    @Schema(description = "所报课程")
    @ExcelProperty("所报课程")
    private String courseName;

    @Schema(description = "上课时间")
    @ExcelProperty("上课时间")
    private Time classStartTime;

    @Schema(description = "授课教师")
    @ExcelProperty("授课教师")
    private String teacherName;

    @Schema(description = "操作人", example = "王五")
    private String operaName;

    @Schema(description = "操作时间")
    private LocalDateTime operaTime;

    @Schema(description = "操作类型", example = "2")
    private String operaType;

    @Schema(description = "操作说明")
    private String operaExplain;

}

关键

@Schema(description = "学员id", example = "21490")

private List<CancleClassInfoDO> studentId;

要把学员id定义成一个list对象集合,用来往子表批量插入学生的数据

CancleClassInfoRespVO:

java 复制代码
package com.todod.education.module.study.controller.admin.cancleclass.vo;

import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.sql.Time;
import java.time.LocalDateTime;

@Schema(description = "管理后台 - 消课记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CancleClassInfoRespVO {

    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")
    private Long id;

    @Schema(description = "学员姓名", example = "芋艿")
    private String studentName;

    @Schema(description = "手机号")
    private String studentPhone;

    @Schema(description = "班级名称", example = "李四")
    @ExcelProperty("班级名称")
    private String className;

    @Schema(description = "班级类型", example = "1")
    @ExcelProperty("班级类型")
    private String classType;

    @Schema(description = "所报课程")
    @ExcelProperty("所报课程")
    private String courseName;

    @Schema(description = "上课时间")
    @ExcelProperty("上课时间")
    private Time classStartTime;

    @Schema(description = "授课教师")
    @ExcelProperty("授课教师")
    private String teacherName;

    @Schema(description = "创建时间")
    @ExcelProperty("创建时间")
    private LocalDateTime createTime;

    @Schema(description = "操作人", example = "王五")
    private String operaName;

    @Schema(description = "操作时间")
    private LocalDateTime operaTime;

    @Schema(description = "操作类型", example = "2")
    private String operaType;

    @Schema(description = "操作说明")
    private String operaExplain;

}

实现类:

java 复制代码
package com.todod.education.module.study.dal.dataobject.cancleclass;

import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.todod.education.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;

import java.sql.Time;
import java.time.LocalDateTime;

/**
 * 消课记录 DO
 *
 * @author 平台管理员
 */
@TableName("study_cancle_class_info")
@KeySequence("study_cancle_class_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CancleClassInfoDO extends BaseDO {

    /**
     * 主键id
     */
    @TableId
    private Long id;

    private Long studentId;

    /**
     * 学员姓名
     */

    private String studentName;
    /**
     * 手机号
     */
    private String studentPhone;
    /**
     * 班级名称
     */
    private String className;
    /**
     * 班级类型
     */
    private String classType;
    /**
     * 所报课程
     */
    private String courseName;
    /**
     * 授课教师
     */
    private String teacherName;

    /**
     * 上课时间
     */
    private Time classStartTime;

    /**
     * 操作人
     */
    private String operaName;
    /**
     * 操作时间
     */
    private LocalDateTime operaTime;
    /**
     * 操作类型
     */
    private String operaType;
    /**
     * 操作说明
     */
    private String operaExplain;


}

关键:

java 复制代码
  @Override
    @LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",
            success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)
    public Long createCancleClass(CancleClassSaveReqVO createReqVO) {
        if(createReqVO.getStudentId().size() == 0){
            throw exception(CANCLE_CLASS_NOT_EXISTS);
        }
        // 插入
        CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);
        cancleClassMapper.insert(cancleClass);

        List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();
        for (CancleClassInfoDO studentId : studentIds) {
            CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();
            cancleClassInfoDO.setStudentId(studentId.getStudentId());
            cancleClassInfoDO.setStudentName(studentId.getStudentName());
            cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());
            cancleClassInfoDO.setClassType(studentId.getClassType());
            cancleClassInfoDO.setClassName(studentId.getClassName());
            cancleClassInfoDO.setCourseName(studentId.getCourseName());
            cancleClassInfoDO.setTeacherName(studentId.getTeacherName());
            cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());
            cancleClassInfoDO.setId(studentId.getId());
            cancleClassInfoMapper.insert(cancleClassInfoDO);
        }

// 3. 记录操作日志上下文
        LogRecordContext.putVariable("cancleClass", cancleClass);
        return cancleClass.getId();

    }

主表插入:

复制代码
// 插入
CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);
cancleClassMapper.insert(cancleClass);

直接用Mapper以及mybatis-plus插入到数据库里面

子表插入:

复制代码
List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();
for (CancleClassInfoDO studentId : studentIds) {
    CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();
    cancleClassInfoDO.setStudentId(studentId.getStudentId());
    cancleClassInfoDO.setStudentName(studentId.getStudentName());
    cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());
    cancleClassInfoDO.setClassType(studentId.getClassType());
    cancleClassInfoDO.setClassName(studentId.getClassName());
    cancleClassInfoDO.setCourseName(studentId.getCourseName());
    cancleClassInfoDO.setTeacherName(studentId.getTeacherName());
    cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());
    cancleClassInfoDO.setId(studentId.getId());
    cancleClassInfoMapper.insert(cancleClassInfoDO);
}
复制代码
List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();

遍历前端传过来的studentId,往子表里插入数据

for (CancleClassInfoDO studentId : studentIds) {

CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();

cancleClassInfoDO.setStudentId(studentId.getStudentId());

cancleClassInfoDO.setStudentName(studentId.getStudentName());

cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());

cancleClassInfoDO.setClassType(studentId.getClassType());

cancleClassInfoDO.setClassName(studentId.getClassName());

cancleClassInfoDO.setCourseName(studentId.getCourseName());

cancleClassInfoDO.setTeacherName(studentId.getTeacherName());

cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());

cancleClassInfoDO.setId(studentId.getId());

cancleClassInfoMapper.insert(cancleClassInfoDO);

}

CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();

新建一个CancleClassInfoDO 实体类对象。

cancleClassInfoDO.setStudentId(studentId.getStudentId());

cancleClassInfoDO.setStudentName(studentId.getStudentName());

cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());

cancleClassInfoDO.setClassType(studentId.getClassType());

cancleClassInfoDO.setClassName(studentId.getClassName());

cancleClassInfoDO.setCourseName(studentId.getCourseName());

cancleClassInfoDO.setTeacherName(studentId.getTeacherName());

cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());

cancleClassInfoDO.setId(studentId.getId());

往数据库插入数据

cancleClassInfoMapper.insert(cancleClassInfoDO);

相关推荐
HuaHua的世界16 分钟前
说说 Vue 中 CSS scoped 的原理?
css·vue.js
H5开发新纪元32 分钟前
Vue 项目中 Loading 状态管理及页面切换 Bug 分析
前端·vue.js
JAVA百练成神2 小时前
深度理解spring——BeanFactory的实现
java·后端·spring
icefiresong242 小时前
如何让 Vue 组件自动清理 EventBus 监听器?告别内存泄漏!
vue.js
lllsure3 小时前
SpringCloud——负载均衡
服务器·网络·spring cloud
yuren_xia3 小时前
示例:Spring JDBC编程式事务
java·后端·spring
MerlinTheMagic4 小时前
Spring AI 核心概念
java·人工智能·spring
酷ku的森4 小时前
Spring Web MVC入门
spring·mvc
西洼工作室4 小时前
黑马商城-微服务笔记
java·笔记·spring·微服务
异常君4 小时前
Spring 定时任务执行一次后不再触发?5 大原因与解决方案全解析
java·后端·spring