Upload 上传(图片/文件),回显(图片),下载(文件)

1.前端技术:V3 +  Ant Design Vue

2.后端技术:Java

图片上传/回显:

文件上传回显:

表结构:单文件/图片上传为A表对文件C表 (A表field字段 对应 C表id字段)

如图:A表中的 vehicle_driving_license  和 driver_license 存的是C表中的id字段

表结构:多文件/图片上传为A表对文件B表 中的Biz字段,B表中的file_id字段对应C表中的id字段,(B表的 Biz 字段和 file_id 字段是一对多的存在关系)

如图:A表中的 house_type_file_id 和 house_type_balcony_close_file_id 、house_type_balcony_bisect_file_id、house_type_shearwall_file_id 存的是B表中的Biz_id字段,B表中的 field_id 字段对应 C表中的 id 字段,(B表中的Biz_id字段 与 field_id 字段是一对多的关系)

上传:(上传功能不分单个多个)java后台代码(controller):

  @OperationLog@ApiOperation("上传文件")@PostMapping("/upload")public ApiResult<FileInfo> upload(@RequestParam MultipartFile file, HttpServletRequest request) {FileInfo result = null;try {String dir = getUploadDir();File upload = FileServerUtil.upload(file, dir, config.getUploadUuidName());String path = upload.getAbsolutePath().replace("\\", "/").substring(dir.length() - 1);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/upload");requestURL = "/api/file-info/file/";String requestURL2 = "/api/file-info";/*if(requestURL.contains("10.1.140.88")){requestURL = "https://10.1.140.88/api/file";}if(requestURL.contains("djshemei.com")){requestURL = "https://10.1.140.88/api/file";}*/String originalName = file.getOriginalFilename();result = new FileInfo();result.setId(SnowFlakeGenerator.nextId());String contentType = FileServerUtil.getContentType(upload);result.setFileType(contentType);result.setFileName(StrUtil.isBlank(originalName) ? upload.getName() : originalName);result.setFilePath(path);result.setUrlPath(requestURL+result.getId());result.setUrl(requestURL2 + "/" + path);//这个用户应该是这个找登录用户User loginUser = getLoginUser();result.setCreUserId(Long.valueOf(loginUser.getUserId()));result.setCreUserName(loginUser.getUsername());result.setCreateTime(LocalDateTime.now());fileInfoService.save(result);return success(result);} catch (Exception e) {e.printStackTrace();return fail("上传失败", result).setError(e.toString());}}

前端:api代码:

/*** 上传文件*/
export async function uploadFile(file, opt) {const formData = new FormData();formData.append('file', file);const res = await request.post('/community/file-info/upload', formData, opt);if (res.data.code === 0 && res.data.data) {return res.data.data;}return Promise.reject(new Error(res.data.message));
}

在页面引入使用

 <a-row><a-col :span="12"><a-form-item label="行驶证"><ele-image-uploadclass="imagestype":limit="1"v-model:value="form1.vehicleDrivingLicenseField"@upload="onUpload1"@remove="onRemove1"/></a-form-item></a-col><a-col :span="12"><a-form-item label="驾驶证"><ele-image-uploadclass="imagestype":limit="1"v-model:value="form1.driverLicenseField"@upload="onUpload2"@remove="onRemove2"/></a-form-item></a-col></a-row>

使用方法:

  const onUpload1 = ({ file }) => {uploadFile(file).then((data) => {console.log(data, 'data');form1.vehicleDrivingLicenseFieldId1 = data.id;}).catch((e) => {item.status = 'exception';message.error(e.message);});};

数据结构:

  // 图片const form1 = reactive({vehicleDrivingLicenseField: [],vehicleDrivingLicenseFieldId1: '',driverLicenseField: [],driverLicenseFieldId2: ''});

图片回显:java代码 (controller)

 @ApiOperation("查询文件")@GetMapping("/queryFile/{id}")public ApiResult<?> getFileInfoByRoomCar (@PathVariable("id") Long id, HttpServletRequest request ) {List<RoomCar>  roomCarServiceList = roomCarService.list(new QueryWrapper<RoomCar>().eq("car_id", id));if(roomCarServiceList.size() == 0){return success(new ArrayList<>());}else{List<FileInfo> fileIdList = fileInfoService.list(new QueryWrapper<FileInfo>().in("id",  roomCarServiceList.stream().map(RoomCar::getVehicleDrivingLicense).collect(Collectors.toList())));if (fileIdList.size() > 0) {String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/room-car/queryFile/"+id);for (FileInfo record : fileIdList) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/" + record.getFilePath());record.setUrl(requestURL + "/file-info/" + record.getFilePath());}}}List<FileInfo> fileIdList1 = fileInfoService.list(new QueryWrapper<FileInfo>().in("id",  roomCarServiceList.stream().map(RoomCar::getDriverLicense).collect(Collectors.toList())));if (fileIdList1.size() > 0) {String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/room-car/queryFile/"+id);for (FileInfo record : fileIdList1) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/" + record.getFilePath());record.setUrl(requestURL + "/file-info/" + record.getFilePath());}}}HashMap<String, List<FileInfo>> data = new HashMap<>();data.put("vehicleDrivingLicenseField", fileIdList);data.put("driverLicenseField", fileIdList1);return success(data);}}

前端api:

export async function  queryItem(id) {const res = await request.get('/community/decoration-manage/queryFile/' + id);if (res.data.code === 0) {return res.data;}return Promise.reject(new Error(res.data.message));
}

页面引入使用:

 watch(() => props.visible,(visible) => {if (visible) {if (props.data) {assignObject(form, {...props.data});isUpdate.value = true;showFile.value = true;changeRoomType(props.data.roomTypeId);// driverLicense// vehicleDrivingLicensequeryItem(props.data.carId).then((res) => {form1.vehicleDrivingLicenseField =res.data.vehicleDrivingLicenseField;form1.driverLicenseField = res.data.driverLicenseField;}).catch((e) => {message.error(e.message);});loadingData();} else {showFile.value = false;isUpdate.value = false;loadingData();}} else {form1.vehicleDrivingLicenseField = [];form1.driverLicenseField = [];resetFields();}});

 多文件上传跟单文件上传一样的,不一样的是显示的方式:

多文件回显后端 Java代码(controller):

 @ApiOperation("查询文件")@GetMapping("/queryFile/{id}")public ApiResult<?> getFileInfoByRegionalHouseTypeId(@PathVariable("id") Long id, HttpServletRequest request ) {BaseRegionalHouseType mainRec = baseRegionalHouseTypeService.getByIdRel(id);List<FileInfo> house_type_file = new ArrayList<>();List<FileInfo> house_type_balcony_close_file = new ArrayList<>();List<FileInfo> house_type_balcony_bisect_file = new ArrayList<>();List<FileInfo> house_type_shearwall_file = new ArrayList<>();Long bizId;bizId = mainRec.getHouseTypeFileId();if (bizId != null) {house_type_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeBalconyCloseFileId();if (bizId != null) {house_type_balcony_close_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_balcony_close_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeBalconyBisectFileId();if (bizId != null) {house_type_balcony_bisect_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_balcony_bisect_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeShearwallFileId();if (bizId != null) {house_type_shearwall_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_shearwall_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}HashMap<String, List<FileInfo>> data = new HashMap<>();data.put("house_type_file", house_type_file);data.put("house_type_balcony_close_file", house_type_balcony_close_file);data.put("house_type_balcony_bisect_file", house_type_balcony_bisect_file);data.put("house_type_shearwall_file", house_type_shearwall_file);return success(data);}

前端api:

export async function  queryHouse(id) {const res = await request.get('/community/base-regional-house-type/queryFile/' + id);if (res.data.code === 0) {return res.data;}return Promise.reject(new Error(res.data.message));
}

页面使用:

<template><ele-modal:width="1200":visible="visible":confirm-loading="loading"title="文件管理":body-style="{ paddingBottom: '8px' }"@update:visible="updateVisible"@ok="save"><div class="ele-body"><a-card :bordered="false"><div class="content"><div class="loudong"><div><divstyle="font-size: 18px; font-weight: 600; margin-bottom: 25px">文件上传</div><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(0)":class="btn == 0 ? 'btnColor' : ''"style="width: 150px">户型图</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(1)":class="btn == 1 ? 'btnColor' : ''"style="width: 150px">封闭阳台方案</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(2)":class="btn == 2 ? 'btnColor' : ''"style="width: 150px">封闭阳台剖面图</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(3)":class="btn == 3 ? 'btnColor' : ''"style="width: 150px">剪力墙标识图</a-button></a-col></a-row></div></div><div class="content-right"><div class="ele-body" style="margin-top: -40px"><div class="content"><div class="content-right"><div class="content-right-header" style="margin-top: 30px"><a-upload:show-upload-list="false":customRequest="onUploadCardf"><a-button type="primary" class="ele-btn-icon"><template #icon><upload-outlined /></template><span>上传</span></a-button></a-upload></div><!-- 表格 --><ele-pro-tableborderedref="tableRef"row-key="id":columns="columns":datasource="datasource":toolkit="false":scroll="{ x: 800 }"><template #bodyCell="{ column, record, index }"><template v-if="column.key === 'action'"><a-space><a:href="record.downloadUrl"target="_blank":disabled="record.downloadUrl != null ? disabled : true">下载</a><a-divider type="vertical" /><a-popconfirmplacement="topRight"title="确定要删除此文件吗?"@confirm="remove(record, index)"><a class="ele-text-danger">删除</a></a-popconfirm></a-space></template></template></ele-pro-table></div></div></div></div></div></a-card><!-- <spbuilding-editv-model:visible="showEdit":data="current"@done="reload"/><bar-code :data="barcodedata" v-model:visible="showBarcode" /> --></div></ele-modal>
</template>
<script setup>import { ref, watch, onMounted } from 'vue';import {getfileinfobybiz,uploadFile,removeFile} from '@/api/system/file-info';import useFormData from '@/utils/use-form-data';import { Form, message } from 'ant-design-vue/es';import { messageLoading } from 'ele-admin-pro/es';import {saveHouse,queryHouse} from '@/api/baseRegionalPark/base-regional-house-type';import { CloudUploadOutlined, FileTextOutlined } from '@ant-design/icons-vue';// import FileUpload from './file-upload.vue';const emit = defineEmits(['done', 'update:visible']);const useForm = Form.useForm;const props = defineProps({data: Object,visible: Boolean});// 表单const { form, resetFields, assignFields } = useFormData({regionalHouseTypeId: '',// 户型图idhouseTypeFileId: '',// 封闭阳台方案idhouseTypeBalconyCloseFileId: '',// 封闭阳台剖面图idhouseTypeBalconyBisectFileId: '',// 剪力墙标识图idhouseTypeShearwallFileId: '',house_type_file: [],house_type_balcony_close_file: [],house_type_balcony_bisect_file: [],house_type_shearwall_file: []});// 按钮颜色const btn = ref(0);// 确定数据const datas = ref({regionalHouseTypeId: '',house_type_file: [],house_type_balcony_close_file: [],house_type_balcony_bisect_file: [],house_type_shearwall_file: [],downloadUrl:"",// 户型图idhouseTypeFileId: '',// 封闭阳台方案idhouseTypeBalconyCloseFileId: '',// 封闭阳台剖面图idhouseTypeBalconyBisectFileId: '',// 剪力墙标识图idhouseTypeShearwallFileId: '',});const typeclick = (type) => {switch (type) {case 0:btn.value = 0;datasource.value = datas.value.house_type_file;        break;case 1:btn.value = 1;datasource.value = datas.value.house_type_balcony_close_file; break;case 2:btn.value = 2;datasource.value = datas.value.house_type_balcony_bisect_file; break;case 3:btn.value = 3;datasource.value = datas.value.house_type_shearwall_file; break;}    };const findPicIds = ref([]);// 表格实例const tableRef = ref(null);// 导入请求状态const loading = ref(false);const isAdmin = ref(false);// 保存按钮const save = () => {saveHouse(datas.value).then((res) => {if (res.code == 0) {message.success('保存成功');emit('done');emit('update:visible', false);} else {message.error(res.msg);}});};// 表格列配置const columns = ref([{title: '序号',key: 'index',width: 48,align: 'center',fixed: 'left',hideInSetting: true,customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)},{title: '文件名',dataIndex: 'fileName'},{title: '文件类型',dataIndex: 'fileType'},{title: '创建人',dataIndex: 'creUserName'},{title: '创建时间',dataIndex: 'createTime'},{title: '操作',key: 'action',width: 160,align: 'center',hideInSetting: true}]);//上传文件const onUploadCardf = (d) => {uploadFile(d.file, {onUploadProgress: (e) => {if (e.lengthComputable) {d.progress = (e.loaded / e.total) * 100;}}}).then((data) => {d.status = 'done';if (btn.value == 0) {        datas.value.house_type_file.push(data);} else if (btn.value == 1) {datas.value.house_type_balcony_close_file.push(data);} else if (btn.value == 2) {datas.value.house_type_balcony_bisect_file.push(data);} else if (btn.value == 3) {datas.value.house_type_shearwall_file.push(data);}message.success('上传成功');}).catch((e) => {message.error(e.message);});};//     /* 删除单个 */const remove = (row, index) => {const hide = message.loading('请求中..', 0);removeFile(row.id).then((msg) => {var arr = [];if(btn.value ==0 ){arr = datas.value.house_type_file.filter((d) => d.id != row.id);datas.value.house_type_file = arr;}if(btn.value ==1 ){arr = datas.value.house_type_balcony_close_file.filter((d) => d.id != row.id);datas.value.house_type_balcony_close_file = arr;}if(btn.value ==2 ){arr = datas.value.house_type_balcony_bisect_file.filter((d) => d.id != row.id);datas.value.house_type_balcony_bisect_file = arr;}if(btn.value ==3 ){arr = datas.value.house_type_shearwall_file.filter((d) => d.id != row.id);datas.value.house_type_shearwall_file = arr;}typeclick(btn.value);hide();message.success(msg);}).catch((e) => {hide();message.error(e.message);});};//   // 表格数据源const datasource = ref([]);/* 更新visible */const updateVisible = (value) => {emit('update:visible', value);};watch(() => props.visible,(visible) => {if (visible) {if (!props.data) {alert('数据为空,请确保传递正确数据');return;}console.log(props.data);datas.value.regionalHouseTypeId = props.data.regionalHouseTypeId;   queryHouse(datas.value.regionalHouseTypeId).then((res) => {datas.value.house_type_file = res.data.house_type_file;datas.value.house_type_balcony_close_file = res.data.house_type_balcony_close_file;datas.value.house_type_balcony_bisect_file = res.data.house_type_balcony_bisect_file;datas.value.house_type_shearwall_file = res.data.house_type_shearwall_file;// 默认选中第一个typeclick(0);});        }});
</script>
<style lang="less" scoped>// .ele-body {//   height: 100%;// }.btnColor {background-color: #f4fbf8;color: #1677ff;}.content {display: flex;.loudong {width: 280px;margin-right: 15px;padding: 15px;// height: 80vh;background: #fff;overflow: auto;box-sizing: border-box;}.search {width: 100%;padding: 20px 10px 0px 20px;background: #f6f5f5;margin-bottom: 5px;}.content-right {flex: 1;}}
</style>

还有一个小细节,java存储文件id的字段一定不要忽略修改的时候传来的null

 

用注解:

@TableField(updateStrategy = FieldStrategy.IGNORED)

就ok啦,暂时先做个笔记,后面有空再慢慢写注解

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel小技巧 (4) - 如何转换数字到人民币文字

选中数字&#xff0c;点击鼠标右键&#xff0c;《设置单元格式》 分类选中特殊&#xff0c;并选择中文大写数字 就转好了&#xff01; 再教一个小技巧&#xff0c;最近东南亚项目也多起来了&#xff0c;是不是需要打印invoice上有泰文的数字。 强大的Excel也有个公式

揭秘PostgreSQL:超越传统数据库的无限可能!

介绍&#xff1a;PostgreSQL是一个功能强大的开源对象关系数据库系统。以下是对PostgreSQL的详细介绍&#xff1a; 开源性&#xff1a;PostgreSQL是完全开源的&#xff0c;这意味着任何人都可以自由地获取、使用和修改它的源代码。 可定制性&#xff1a;它具有高度可定制性&…

傅里叶变换pytorch使用

参考视频&#xff1a;1 傅里叶变换原理_哔哩哔哩_bilibili 傅里叶变换是干嘛的&#xff1a; 傅里叶得到低频、高频信息&#xff0c;针对低频、高频处理能够实现不同的目的。 傅里叶过程是可逆的&#xff0c;图像经过傅里叶变换、逆傅里叶变换后&#xff0c;能够恢复到原始图像…

资料下载-嵌入式 Linux 入门

学习的第一步是去下载资料。 1. 有哪些资料 所有资料分 4 类&#xff1a; ① 开发板配套资料(原理图、虚拟机的映像文件、烧写工具等)&#xff0c;放在百度网盘 ② 录制视频过程中编写的文档、源码、图片&#xff0c;放在 GIT 仓库 ③ u-boot、linux 内核、buildroot 等比较大…

SpringBoot学习之自定义注解和AOP 切面统一保存操作日志(二十九)

一、定义一个注解 这个注解是用来控制是否需要保存操作日志的自定义注解(这个类似标记或者开关) package com.xu.demo.common.anotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; i…

llc如何实现开关管ZVS(零电压)导通

对于LLC而言最大的优势就是实现原边开关管 ZVS开通以及副边二极管ZCS关断来提高效率的&#xff0c;我们可以先来看如何实现开关管 ZVS开通 稳态下的分析 上图是LLC谐振腔中的大致电压与电流波形&#xff0c;我们可以在这个波形上来分析 MOS是如何实现ZVS开通的 注意&#xff…

原生JavaScript,根据后端返回JSON动态【动态列头、动态数据】生成表格数据

前期准备&#xff1a; JQ下载地址&#xff1a; https://jquery.com/ <!DOCTYPE html> <html><head><meta charset"utf-8"><title>JSON动态生成表格数据,动态列头拼接</title><style>table {width: 800px;text-align: cen…

谷粒商城【成神路】-【10】——缓存

目录 &#x1f9c2;1.引入缓存的优势 &#x1f953;2.哪些数据适合放入缓存 &#x1f32d;3.使用redis作为缓存组件 &#x1f37f;4.redis存在的问题 &#x1f9c8;5.添加本地锁 &#x1f95e;6.添加分布式锁 &#x1f95a;7.整合redisson作为分布式锁 &#x1f697…

php调用guzzlehttp库时出现Segmentation fault的解决方案

先说结论&#xff0c;这个问题的原因是因为php7.4与openssl3不兼容产生的&#xff0c;解决方案如下&#xff1a; 输入openssl version -a查看openssl版本&#xff0c;如果是3以上的版本与php7.4不兼容&#xff0c;7.4以下的没测试过&#xff0c;估计也有问题。我最终是安装上了…

深入理解Vue.js中的nextTick:实现异步更新的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

微信小程序开发系列(二十)·wxml语法·setData()修改对象类型数据、ES6 提供的展开运算符、delete和rest的用法

目录 1. 新增单个、多个属性 1.1 新增单个属性 1.2 新增多个属性 2. 修改单个、多个属性 2.1 修改单个属性 2.2 修改多个属性 3. 优化 3.1 ES6 提供的展开运算符 3.2 Object.assign()将多个对象合并为一个对象 4. 删除单个、多个属性 4.1 删除单个属性 …

【Redis】RedisTemplate序列化传输数据

使用自定义的序列化器 使用RedisTemplate默认的序列化器发送数据&#xff0c;会将key全都当成Object处理&#xff0c;从而按照对象的方式转成json格式发送到服务器&#xff0c;这样会导致两个问题。一是不方便阅读&#xff0c;二是会大大浪费内存。因此&#xff0c;建议自定义…

MySQL常见的索引类型介绍

我将为您详细讲解 MySQL 中常见的索引类型&#xff0c;以及它们的使用场景、特点、区别和优势。索引是提高数据库查询性能的关键工具&#xff0c;它可以加速数据检索速度&#xff0c;减少服务器的负担。在 MySQL 中&#xff0c;索引类型主要包括 B-Tree 索引、哈希索引、全文索…

分库分表浅析原理

数据库存放数据大了&#xff0c;查询等操作就会存在瓶颈&#xff0c;怎么办&#xff1f; 1. 如果是单张表数据大了&#xff0c;可以在原有库上新建几张表table_0、table_1、table_2、.....table_n 写程序对数据进行分表&#xff1a; --这里提供一种一种分表策略,这里只需维护…

【C++】设计模式:观察者、策略、模板

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍设计模式&#xff1a;观察者、策略、模板。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xf…

Python办公自动化之PDF(二)

Python操作PDF二 1、PyMuPDF简介2、 1、PyMuPDF简介 PyMuPDF&#xff08;也称Fitz&#xff09;开源&#xff0c;提供了一整套用于处理PDF文件的综合工具。使用PyMuPDF&#xff0c;用户可以高效地执行打开PDF、提取文本、图像和表格、操作旋转和裁剪等页面属性、创建新PDF文档以…

微服务day06-Docker

Docker 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性问题 开发、测试、生产环境有差异 1.什么是Docker? 大型项目组件很多&#xff0c;运行环境复杂&#xff0c;部署时会遇到各种…

sql注入基础学习

1.常用SQL语句 01、显示数据库 show databases&#xff1b; 02、打开数据库 use db name&#xff1b; 03、显示数据表 show tables&#xff1b; 04、显示表结构 describe table_name&#xff1b; 05、显示表中各字段信息&#xff0c;即表结构 show columns from table_nam…

大数据开发 hadoop集群 2.hadoop框架入门

自从我学会了寻找&#xff0c;我就已经找到 ——史铁生 —— 24.3.10 内容简介 Hadoop入门&#xff1a; ①概念 ②环境准备 ③hadoop生产集群搭建 ④常见错误的解决方案 ①概念&#xff1a;1.Hadoop是什么 2.Hadoop发展历史 3.Hadoop…

菜品检测,基于YOLOV8

菜品检测&#xff0c;基于YOLOV8NANO&#xff0c;训练得到模型PT&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C/PYTHON/ANDROID开发菜品检测&#xff0c;基于YOLOV8&#xff0c;能检测五种菜品&#xff0c;水豆腐、豆腐干、空心菜、豆芽菜、茄子