目录
1.背景
一段时间记录一些Java代码的基本操作,方便自己也方便其他人
环境:Win7 + IDEA + JDK1.8 + Springboot 2.1.8.RELEASE
2.片段
1)文件上传
上传文件前,需对上传文件的大小进行限制:在application.properties中添加配置项:
- spring.servlet.multipart.maxFileSize=200MB
- spring.servlet.multipart.maxRequestSize=200MB
/**
* 单个文件上传
*/
@PostMapping("/file/upload")
public String UploadFile(@RequestParam("file") MultipartFile file){
if (file.isEmpty()){
return "上传文件为空";
}
String fileName = file.getOriginalFilename();
Long startTs = System.currentTimeMillis(); // 获取当前时间戳,作为文件目录
String path = "D:/" + startTs; // 文件上传后保存的路径
File filePath = new File(path + "/" + fileName); // 文件的目录,包括文件名
if (!filePath.exists()) {
filePath.mkdirs();
}
try{
file.transferTo(filePath);
return "Success";
} catch (IllegalStateException e) {
return e.printStackTrace();
} catch (IOException e) {
return e.printStackTrace();
}
}
/**
* 多个文件上传
* */
@PostMapping("/files/upload")
public void FilesUpload(@RequestParam("file") List<MultipartFile> files){
if(files.isEmpty()){
return "false";
}
Long startTs = System.currentTimeMillis();
String path = "D:/" + startTs;
for (MultipartFile file: files) {
String fileName = file.getOriginalFilename();
File filePath = new File(path + "/" + fileName);
if(!filePath.getParentFile().exists()){ //判断文件父目录是否存在
filePath.getParentFile().mkdir();
}
try {
file.transferTo(filePath); //保存文件
} catch (IllegalStateException e) {
return e.getMessage();
} catch (IOException e) {
return e.getMessage();
}
}
return "上传完成";
}
2)文件下载
/**
* 文件下载
*/
@GetMapping("/file/download")
public String FileDownload(HttpServletResponse response) throws IOException {
String filePath = fileEntity.getFilePath(); // 文件的下载目录。上传时保存在了表中,格式如,D:\\1234567\\file.txt
if (filePath.isEmpty()) {
return "未找到指定文件的附件";
}
String files[] = file.split("\\\\");
String fileName = "";
if (files.length > 1) {
fileName = files[files.length - 1];
}
response.setContentType("application/octet-stream;charset=UTF-8");
// response.setContentType("application/force-download"); // 强制下载保存
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("UTF-8"), "iso-8859-1"));
byte[] buffer = new byte[1024];
FileInputStream fis = null; //文件输入流
BufferedInputStream bis = null;
try {
fis = new FileInputStream(filePath);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while(i != -1){
os.write(buffer, 0, i);
i = bis.read(buffer);
}
os.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null){
bis.close();
}
if (fis != null){
fis.close();
}
}
return null;
}
3)批量删除文件记录及对应的文件夹
/**
* 批量删除文件记录和对应的文件夹
*/
@DeleteMapping("/files/delete")
public String DeleteFiles(@RequestBody JSONObject jsonObject) {
if (jsonObject.isEmpty()) {
return "删除的请求体为空";
}
JSONArray ids = jsonObject.getJSONArray("ids");
if (ids.size() == 0) {
return "删除的id为空";
}
for (int id: ids) {
FileEntity fileEntity = fileService.getFileById(id);
String filePath = fileEntity.getFilePath();
String path = filePath.substring(0, filePath.lastIndexOf("\\")); // 文件路径格式如:D:\\1234567\file1.txt.这里取上一层即:D:\\1234567
File file = new File(path);
FileSystemUtils.deleteRecursively(file);
}
fileService.deleteFiles(ids);
return "删除成功";
}
mapper中:
<delete id="deleteFiles">
DELETE FROM tb_files
WHERE id in(
<foreach item="ids" collection="ids" sparator=",">
#{ids}
</foreach>
)
</delete>
foreach元素的属性主要有item,index,collection,open,separator,close。
- item:集合中元素迭代时的别名,该参数为必选。
- index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
- open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
- separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
- close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
- collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids".如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
- 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list .
- 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array .
- 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key.
针对最后一条,我们来看一下官方说法:
注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。
所以,不管是多参数还是单参数的list,array类型,都可以封装为map进行传递。如果传递的是一个List,则mybatis会封装为一个list为key,list值为object的map,如果是array,则封装成一个array为key,array的值为object的map,如果自己封装呢,则colloection里放的是自己封装的map里的key值。
4)mapper知识点
SQL语句:select * from tb_test where id = 1
<select id="test" resultType="testEntity">
SELECT * FROM TB_TEST
<WHERE>
<if test="id == 1">
id = #{id}
</if>
</WHERE>
</select>
-
id="test"与Dao中的数据库操作方法想对应。
-
resultType为返回结果的类型。对应的还有parameterType为传入参数类型
-
if对应sql语句中的where条件。多个条件则需要多个if。“test=”中为判断条件,要执行id=#{id}则需要满足test中的条件。例如,
当SQL语句写成:
- select * from tb_test where test_name like '%test%' and id = -1 # 以test_name为搜索条件,搜索出结果
- select * from tb_test where test_name like '%test%' and id = 5 # 以test_name和id为搜索条件,搜索出结果
<select id="test" resultType="testEntity">
SELECT * FROM TB_TEST
<WHERE>
<if test="testName != null and testName !=''">
test_name = #{testName}
</if>
<if test="id != -1">
AND id = #{id}
</if>
</WHERE>
</select>
即如果给了id就需满足test_name和id两个条件,没有给id默认为-1
5)Mapper中多个条件进行模糊查询
期望的是,一个输入框输入关键字,可以搜索name或者introduction中都包含有该关键字的记录。
注意: CONCAT(`name`,`introduction`)这里是反引号。
<if test="keywords != null and keywords != ''">
AND CONCAT(`name`,`introduction`) LIKE CONCAT ('%', #{keywords},'%')
</if>
6)Entity中定义表中不存在的字段
使用注解@Transient表示该属性并不是与数据库表中的列
3.参考资料
https://www.jianshu.com/p/be1af489551c -- Springboot文件上传下载操作
https://blog.csdn.net/love_moon821/article/details/80079474 -- 下载文件乱码
https://blog.csdn.net/weixin_30443747/article/details/99496200 -- Java打开Windows上的一些应用
https://zhidao.baidu.com/question/2057401189268471427.html -- 在Linux系统中,打开默认浏览器
https://blog.csdn.net/ranmudaofa/article/details/9750637?winzoom=1 -- Java使用默认浏览器打开连接的方法
https://www.cnblogs.com/caoyc/p/5574966.html -- mybatis中的where标签
https://www.cnblogs.com/fnlingnzb-learner/p/10566452.html -- mybatis中的foreach
https://www.cnblogs.com/chery-blogs/articles/11636478.html-- mybatis中多个条件的模糊查询