Java代码小片段(二)

目录

1.背景

2.片段

1)文件上传

2)文件下载

3)批量删除文件记录及对应的文件夹

4)mapper知识点

5)Mapper中多个条件进行模糊查询

6)Entity中定义表中不存在的字段

3.参考资料


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中多个条件的模糊查询

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值