此例為maven項目展辞,實現(xiàn)學(xué)生模塊中簡歷的上傳操作洽腺。所用框架為SSM框架。
此處將下載文件、刪除文件的方法統(tǒng)一展示,因為這是上傳配套的功能霹购,不作另外闡述旭咽。
AjaxFileUpload.js文件可在百度自行下載轿塔,下載后放入項目中,并在頁面中引用即可。
1.JSP 構(gòu)建一個隱藏的文件域兜畸,當點擊上傳簡歷時煞躬,模擬點擊文件域昭雌,彈窗文件選擇框佛纫;下載文件僅是做了一個超鏈接,指向后臺下載請求地址,同時將fileId作為參數(shù)傳向后臺即可蜈漓。
<a href="javascript:void(0)" class="easyui-linkbutton" id="uploadFile" iconCls="icon-import" plain="true">上傳簡歷</a>
<input type="file" id="fileElement" name="fileElement" style="filter:alpha(opacity=0);opacity:0;width: 0;height: 0;"/>
<a href='../file/demoStudentFile/downloadFile?fileId=文件ID"++"' style='color:blue' >"+下載“文件名”+"</a>
2.JS
/**
* 頁面初始化
*/
$(document).ready(function () {
$("#uploadFile").on("click",uploadFile); //上傳文件綁定事件
}
/**
* 上傳附件
* @returns
*/
function uploadFile(){
var rows = $('#studentGrid').datagrid('getChecked');
if (rows==null||rows.length==0) {
ts("未選中數(shù)據(jù)"); //ts 顯示信息
return;
}else if (rows.length>1){
ts("請選擇一條數(shù)據(jù)");
return;
}else{
//獲取當前數(shù)據(jù)對應(yīng)的附件ID
var fkFileId = rows[0].fkFileId;
//導(dǎo)入表格url
var url = "../file/demoStudentFile/uploadFile";
//文件域ID
var fileId = "fileElement";
//文件類型名稱有额,用于提示信息
var fileTypeName = " doc,docx,xls,xlsx,ppt,pptx ";
//文件類型,用于判斷文件后綴是否有效
var fileType = "doc;docx;xls;xlsx;ppt;pptx";
//組裝向后臺傳輸?shù)臄?shù)據(jù)格式
var d = {
stuId : rows[0].stuId,
fileId : fkFileId
};
if(fkFileId!=null&&fkFileId.trim().length!=0){
//已經(jīng)上傳過附件
$.messager.confirm('提示', '確定要覆蓋之前上傳的文件腻菇?', function (r) {
if (!r) {return;}
importUtil(url,d,fileId,fileTypeName,fileType);
});
}else{
importUtil(url,d,fileId,fileTypeName,fileType);
}
}
}
/** 以下為公用JS中的公用方法,所有導(dǎo)入或上傳文件均可直接調(diào)用,將文件域ID舍扰,文件類型等傳遞到方法中即可 **/
/**
* 點擊導(dǎo)入或上傳按鈕个束,綁定文件域事件获洲,模擬點擊,打開文件選擇框
* @param url
* @param fileId 文件域ID
* @param fileTypeName 上傳的文件類型名稱(Word烂叔、Excel、PPT...),用于提示信息
* @param fileType 要求上傳的文件類型叶沛,各個類型間用英文;隔開 (xls;xlsx),用于判斷文件后綴是否有效
* @returns
*/
function importUtil(url,d,fileId,fileTypeName,fileType){
//Excel文件域綁定改變事件
$("#"+fileId).change( function() {
importFileUtil(url,d,fileId,fileTypeName,fileType);
});
$("#"+fileId).trigger("click");
}
/**
* 傳輸文件
* @param url
* @param fileId 文件域ID
* @param fileTypeName 上傳的文件類型名稱(Word溉箕、Excel寡痰、PPT...),用于提示信息
* @param fileType 要求上傳的文件類型剩岳,各個類型間用英文;隔開 (xls;xlsx),用于判斷文件后綴是否有效
* @returns
*/
function importFileUtil(url,d,fileId,fileTypeName,fileType){
if(checkFileType(fileId,fileTypeName,fileType)){
$.ajaxFileUpload({
url: url,
secureuri: false, //是否需要安全協(xié)議,一般設(shè)置為false
fileElementId: fileId, //文件上傳域的ID
dataType:"JSON",
data : d,
success: function (data, status){ //服務(wù)器成功響應(yīng)處理函數(shù)
var result = $.parseJSON(data);
$("#"+fileId).val("");
$.messager.show({ title: '提示', msg: result.msg, timeout: 1000, style: {} });
},
error: function (data, status, e){ //服務(wù)器響應(yīng)失敗處理函數(shù)
alert("導(dǎo)入失敗");
}
});
return false;
}
}
/**
* 校驗文件類型
* @param fileId 文件域ID
* @param fileTypeName 上傳的文件類型名稱(Word卢肃、Excel疲迂、PPT...),用于提示信息
* @param fileType 要求上傳的文件類型,各個類型間用英文;隔開 (xls;xlsx),用于判斷文件后綴是否有效
* @returns
*/
function checkFileType(fileId,fileTypeName,fileType){
var fileDir = $("#"+fileId).val();
if("" == fileDir){
ts("請選擇有效的"+fileTypeName+"文件莫湘!");
return false;
}
var suffix = fileDir.substr(fileDir.lastIndexOf(".")+1);
var fileTypes = fileType.split(";");
if(fileTypes.indexOf(suffix)==-1){
ts("請選擇有效的"+fileTypeName+"文件!");
return false;
}
return true;
}
3.實體類 DemoStudent.java
package com.project.entity.demo;
import com.project.entity.BaseEntity;
/**
* @author hmz 2017年12月25日 下午5:05:03 學(xué)生實體類
*/
@SuppressWarnings("serial")
public class DemoStudent extends BaseEntity {
private String stuId;// 學(xué)生id
private String name;// 學(xué)生姓名
private String sex;// 學(xué)生性別
private String phone;// 學(xué)生電話
private String address;// 學(xué)生地址
private String message;// 學(xué)生自我評價
private String fkFileId;// 附件ID
private String fkFileName;// 附件名稱
public String getStuId() {
return stuId;
}
public void setStuId(String stuId) {
this.stuId = stuId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFkFileId() {
return fkFileId;
}
public void setFkFileId(String fkFileId) {
this.fkFileId = fkFileId;
}
public String getFkFileName() {
return fkFileName;
}
public void setFkFileName(String fkFileName) {
this.fkFileName = fkFileName;
}
}
4.實體類 DemoFile.java
package com.project.entity.demo;
import javax.validation.constraints.Size;
import com.project.entity.BaseEntity;
/**
* 上傳文件Entity
* @author HMZ
* @version 2017年10月6日上午11:36:15
*/
@SuppressWarnings("serial")
public class DemoFile extends BaseEntity {
/**
* 附件ID.
*/
@Size(max = 36, min = 0, message = "附件ID長度為36位")
private String fileId;
/**
* 附件名稱.
*/
@Size(max = 50, min = 0, message = "附件名稱長度為50位")
private String fileName;
/**
* 附件后綴.
*/
@Size(max = 50, min = 0, message = "附件名稱長度為50位")
private String fileExt;
/**
* 附件地址.
*/
@Size(max = 100, min = 0, message = "附件地址長度為100位")
private String fileUrl;
public String getFileExt() {
return fileExt;
}
public void setFileExt(String fileExt) {
this.fileExt = fileExt;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileUrl() {
return fileUrl;
}
public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
}
5.Controller層 DemoStudentFileController.java 主要用于獲取文件并調(diào)用Service中方法
package com.project.controller.demo;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.project.entity.demo.DemoStudent;
import com.project.service.demo.DemoStudentService;
import com.project.util.cipher.CipherTransport;
/**
* @ClassName: DemoStudentFileController
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午3:49:22
*/
@Controller
@CipherTransport
@RequestMapping("/file/demoStudentFile")
public class DemoStudentFileController {
@Autowired
private DemoStudentService demoStudentService;
/**
* 上傳附件
* @Title: uploadFile
* @Description: TODO
* @param file
* @param stuId 學(xué)生id
* @param request
* @param response
* @throws IOException
* @return: void
*/
@ResponseBody
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public void uploadFile(@RequestParam("fileElement") MultipartFile file, String stuId, String fileId, HttpServletRequest request, HttpServletResponse response) throws IOException {
JSONObject obj = demoStudentService.uploadFile(file, stuId, fileId, request);
response.getWriter().print(obj.toString());
}
/**
* 下載附件
* @Title: downloadFile
* @Description: TODO
* @param fileId
* @param response
* @throws UnsupportedEncodingException
* @return: void
*/
@ResponseBody
@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
public void downloadFile(@RequestParam("fileId") String fileId, HttpServletResponse response) throws UnsupportedEncodingException {
demoStudentService.downloadFile(fileId, response);
}
}
6.Service層 DemoStudentService.java 主要處理業(yè)務(wù)邏輯
package com.project.service.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.project.entity.demo.DemoStudent;
import com.project.mapper.demo.DemoStudentMapper;
import com.project.util.ConstUtil;
import com.project.util.file.ExportExcelUtil;
import com.project.util.file.FileConstUtil;
import com.project.util.file.FileValidateUtil;
import com.project.util.file.ImportExcelUtil;
/**
* @ClassName: DemoStudentService
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午3:52:03
*/
@Service
public class DemoStudentService {
@Autowired
private DemoStudentMapper demoStudentMapper;
@Autowired
private DemoFileService demoFileService;
/**
* 上傳附件
* @Title: uploadFile
* @Description: TODO
* @param file
* @param stuId
* @param request
* @return
* @return: JSONObject
*/
@Transactional
public JSONObject uploadFile(MultipartFile file, String stuId, String fileId, HttpServletRequest request) {
JSONObject obj = new JSONObject();
// 驗證附件的有效性,其中大小是固定的,第二個參數(shù)為可上傳的文件類型集合
obj = FileValidateUtil.validateFile(file, FileConstUtil.FileMessage.EXTS);
// 文件驗證不通過涵亏,直接返回錯誤信息
if (obj.has("state")) {
return obj;
}
// 生成隨機數(shù)作為附件ID
String fkFileId = UUID.randomUUID().toString();
// 上傳附件
boolean flag = demoFileService.uploadFile(file, fkFileId, request);
// 說明上傳成功
Map<String, String> params = new HashMap<String, String>();
params.put("stuId", stuId);
params.put("fkFileId", fkFileId);
// 文件上傳成功
if (flag) {
flag = demoStudentMapper.updateFkFileId(params);
if (flag) {
// 數(shù)據(jù)更新成功
if (fileId != null && fileId.trim().length() != 0) {
// 刪除上一次上傳的文件
demoFileService.delete(fileId);
}
obj.put("msg", FileConstUtil.FileMessage.SUCCESS_MESSAGE);
} else {
// 數(shù)據(jù)更新失敗艾君,刪除文件
demoFileService.delete(fkFileId);
obj.put("msg", FileConstUtil.FileMessage.ERROR_MESSAGE);
}
}
return obj;
}
}
/**
* 下載附件
* @Title: downloadFile
* @Description: TODO
* @param fileId
* @param response
* @throws UnsupportedEncodingException
* @return: void
*/
@Transactional
public void downloadFile(String fileId, HttpServletResponse response) throws UnsupportedEncodingException {
if (fileId == null || fileId.trim().length() == 0) {
throw new UnsupportedEncodingException();
} else {
demoFileService.downloadFile(fileId, response);
}
}
7.Service層 DemoFileService.java 主要將文件上傳至服務(wù)器中,并插入文件表中記錄吹埠,該Service中為上傳文件的公用代碼,所有上傳均調(diào)用該方法即可實現(xiàn)文件的上傳和文件表信息的插入省骂,至于上傳文件模塊的其他邏輯茂翔,理應(yīng)寫在自己的Service層中,比如第6條DemoStudentService中逢勾。
package com.project.service.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.project.entity.demo.DemoFile;
import com.project.mapper.demo.DemoFileMapper;
/**
* 上傳文件Service
* @ClassName: DemoFileService
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年3月2日 上午9:15:43
*/
@Service
public class DemoFileService {
@Autowired
private DemoFileMapper demoFileMapper;
/**
* 上傳附件信息
* @Title: uploadFile
* @Description: TODO
* @param file
* @param fileId
* @param request
* @return
* @return: boolean
*/
@Transactional
public boolean uploadFile(MultipartFile file, String fileId, HttpServletRequest request) {
try {
// 得到項目的WEB-INF目錄
String base = request.getServletContext().getRealPath("WEB-INF");
// 將上傳文件名更新為當前時間+文件名塌碌,以保證文件名的唯一性
String name = System.currentTimeMillis() + file.getOriginalFilename();
// 這里將上傳得到的文件保存至file目錄
FileUtils.copyInputStreamToFile(file.getInputStream(), new File(base + "/file/", name));
DemoFile item = new DemoFile();
item.setFileId(fileId);
item.setFileName(file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")));
item.setFileExt(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1));
item.setFileUrl(base + "/file/" + name);
boolean flag = demoFileMapper.insert(item);
return flag;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 下載附件
* @Title: downloadFile
* @Description: TODO
* @param fileId
* @param response
* @return: void
*/
@Transactional
public void downloadFile(String fileId, HttpServletResponse response) {
DemoFile item = demoFileMapper.findById(fileId);
String fileUrl = item.getFileUrl();
// path是指欲下載的文件的路徑遗座。
File file = new File(fileUrl);
if (file.exists()) {
String filename = item.getFileName() + "." + item.getFileExt();
// 設(shè)置響應(yīng)頭和客戶端保存文件名
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + filename);
// 用于記錄以完成的下載的數(shù)據(jù)量,單位是byte
try {
// 打開本地文件流
InputStream inputStream = new FileInputStream(fileUrl);
// 激活下載操作
OutputStream os = response.getOutputStream();
// 循環(huán)寫入輸出流
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
}
os.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 刪除附件信息
* @param fileIds
*/
@Transactional
public void delete(String fileIds) {
if (fileIds == null || "".equals(fileIds)) {
return;
}
String[] fileId = fileIds.split(",");
List<String> ids = new ArrayList<String>();
for (String id : fileId) {
if (id != null && id.trim().length() != 0) {
ids.add(id);
}
}
// 獲取附件地址
List<DemoFile> itemList = demoFileMapper.findByIds(ids);
for (DemoFile item : itemList) {
File file = new File(item.getFileUrl());
// 刪除服務(wù)器中附件信息
if (file.exists()) {
file.delete();
}
}
demoFileMapper.delete(ids);
}
}
8.常量類 FileConstUtil.java 主要定義上傳文件中的一些常量们拙,比如文件類型稍途、提示信息等等
package com.project.util.file;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @ClassName: FileConstUtil
* @Description: TODO文件信息常量類
* @author: HeMengZhu
* @date: 2018年2月28日 下午4:23:43
*/
public class FileConstUtil {
public static class FileMessage {
/**
* 文件不存在提示信息
*/
public static final String FILE_EXISTS = "文件不存在";
/**
* 上傳附件支持的后綴格式
*/
public static final List<String> EXTS = Arrays.asList("doc", "docx", "xls", "xlsx", "ppt", "pptx");
/**
* 文件類型不正確提示信息
*/
public static final String FILE_EXT_ERROR = "請選擇正確的文件('doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx')";
/**
* 文件的最大長度
*/
public static final long FILE_SIZE = 1073741824;
/**
* 文件超過設(shè)定大小后提示信息
*/
public static final String FILE_SIZE_LONG = "文件過大";
/**
* 上傳成功提示信息
*/
public static final String SUCCESS_MESSAGE = "上傳成功";
/**
* 上傳失敗提示信息
*/
public static final String ERROR_MESSAGE = "上傳失敗";
}
}
8.文件驗證類 FileValidateUtil.java 用于驗證用戶上傳文件的有效性
/**
* @Title: FileValidateUtil.java
* @Prject: gypt
* @Package: com.project.util.file
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年3月1日 下午4:31:11
* @version: V1.0
*/
package com.project.util.file;
import java.util.List;
import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.web.multipart.MultipartFile;
/**
* @ClassName: FileValidateUtil
* @Description: TODO 驗證上傳附件的有效性
* @author: HeMengZhu
* @date: 2018年3月1日 下午4:31:11
*/
public class FileValidateUtil {
/**
* 驗證上傳附件的文件類型,大小等
* @Title: validateFile
* @Description: TODO
* @param file
* @return
* @return: JSONObject
*/
public static final JSONObject validateFile(MultipartFile file, List<String> exts) {
JSONObject obj = new JSONObject();
if (file.isEmpty()) {
// 文件不存在
obj.put("state", FileConstUtil.FileMessage.FILE_EXISTS);
} else if (!exts.contains(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1))) {
// 文件類型不滿足
obj.put("state", FileConstUtil.FileMessage.FILE_EXT_ERROR);
} else if (file.getSize() > FileConstUtil.FileMessage.FILE_SIZE) {
obj.put("state", FileConstUtil.FileMessage.FILE_SIZE_LONG);
}
return obj;
}
}
9.Mapper層 DemoStudentMapper.java 接口砚婆,與XML文件相對應(yīng)械拍,實現(xiàn)對數(shù)據(jù)庫的訪問和操作
package com.project.mapper.demo;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.project.entity.demo.DemoStudent;
/**
* @author hmz 2018年02月27日 下午8:01:00 示例-測試學(xué)生Mapper
*/
@Repository
public interface DemoStudentMapper {
/**
* 修改附件ID
* @Title: updateFkFileId
* @Description: TODO
* @param params
* @return: boolean
*/
boolean updateFkFileId(Map<String, String> params);
}
10.Mapper層 DemoStudentMapper.xml 主要包含數(shù)據(jù)庫字段和實體類的映射關(guān)系和對數(shù)據(jù)庫執(zhí)行的SQL語句
<?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.project.mapper.demo.DemoStudentMapper">
<!-- 上傳附件保存附件ID -->
<update id="updateFkFileId" parameterType="java.util.Map" >
UPDATE demo_student
SET fk_file_id = #{fkFileId}
WHERE stu_id = #{stuId} LIMIT 1 ;
</update>
</mapper>
11.Mapper層 DemoStudentMapper.java 接口,與XML文件相對應(yīng)装盯,實現(xiàn)對數(shù)據(jù)庫的訪問和操作
package com.project.mapper.demo;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.project.entity.demo.DemoFile;
/**
* @ClassName: DemoFileMapper
* @Description: TODO 上傳文件Mapper
* @author: HeMengZhu
* @date: 2018年3月1日 下午4:01:10
*/
@Repository
public interface DemoFileMapper {
/**
* 上傳附件信息
* @param item
* @return
*/
boolean insert(DemoFile item);
/**
* 根據(jù)ID查找附件信息
* @param fileId
* @return
*/
DemoFile findById(@Param("fileId") String fileId);
/**
* 根據(jù)ID查找附件信息
* @Title: findByIds
* @Description: TODO
* @param fileIds
* @return
* @return: List<DemoFile>
*/
List<DemoFile> findByIds(@Param("fileIds") List<String> fileIds);
/**
* 刪除附件信息
* @param fileIds
*/
void delete(@Param("fileIds") List<String> fileIds);
}
12.Mapper層 DemoFileMapper.xml 主要包含數(shù)據(jù)庫字段和實體類的映射關(guān)系和對數(shù)據(jù)庫執(zhí)行的SQL語句
<?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.project.mapper.demo.DemoFileMapper">
<resultMap id="fileResultMap" type="com.project.entity.demo.DemoFile">
<id property="fileId" column="file_id"/>
<result property="fileName" column="file_name"/>
<result property="fileExt" column="file_ext"/>
<result property="fileUrl" column="file_url"/>
</resultMap>
<insert id="insert" parameterType="com.project.entity.demo.DemoFile">
INSERT INTO demo_file ( file_id, file_name, file_ext, file_url )
VALUES (#{fileId}, #{fileName}, #{fileExt}, #{fileUrl});
</insert>
<select id="findById" resultType="com.project.entity.demo.DemoFile" parameterType="String">
SELECT a.file_id as fileId, a.file_name as fileName, a.file_ext as fileExt,a.file_url as fileUrl FROM demo_file a
where a.file_id = #{fileId}
LIMIT 1 ;
</select>
<select id="findByIds" parameterType="String" resultMap="fileResultMap">
SELECT a.file_url as fileUrl
FROM demo_file a
WHERE a.file_id in (
<foreach collection="fileIds" item="fileId" separator=" ,">
#{fileId}
</foreach>
);
</select>
<delete id="delete" parameterType="String">
DELETE FROM demo_file
WHERE file_id in (
<foreach collection="fileIds" item="fileId" separator=" ,">
#{fileId}
</foreach>
);
</delete>
</mapper>