springMVC+spring+hibernate注解上传文件到数据库,下载,多文件上传
数据库
CREATE TABLE `annex` ( `id` bigint() NOT NULL AUTO_INCREMENT, `realName` varchar() DEFAULT NULL, `fileContent` mediumblob, `handId` bigint() DEFAULT NULL, `customerId` bigint() DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_id` (`handId`), CONSTRAINT `fk_id` FOREIGN KEY (`handId`) REFERENCES `handprocess` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `handprocess` ( `id` bigint() NOT NULL DEFAULT ', `handTime` bigint() DEFAULT NULL, `handName` varchar() DEFAULT NULL, `reason` varchar() DEFAULT NULL, `annexStr` varchar() DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
处理过程(handprocess)和附件表(annex)一对多关系,一条处理过程可以有多个附件
除了springmvc+hibernate+spring的jar,还需要
commons-fileupload-1.3.1.jar
commons-io-2.0.1.jar
数据库保存上传文件内容使用mediumblob类型
mysql保存数据库二进制文件使用blob类型,其大小如下
TinyBlob 最大 Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G
springmvc中需添加配置文件
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="></property> <!-- byte --> <property name="defaultEncoding" value="utf-8" /> </bean>
其中maxUploadSizes的大小是上传文件大小,单位:字节
实体:
package com.h3c.zgc.upload; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; /** * 附件 和处理过程多对一 * @author GoodLuck * */ @Entity @Table(name="annex",catalog="itac") public class Annex { @Id @Column(name="id") private Long id; //上传文件的名称 @Column(name="realName") private String realName; //上传文件的内容 @Column(name="fileContent") private byte[] fileContent; //处理过程的id @Column(name="handId") private Long handId; //客户id @Column(name="customerId") private Long customerId; //getter and setter ... }
package com.h3c.zgc.upload; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; @Entity @Table(name="handprocess",catalog="itac") public class HandProcess { @Id @Column(name="id") private Long id; @Column(name="handTime") private Long handTime; @Column(name="handName") private String handName; @Column(name="reason") private String reason; @Column(name="annexStr") private String annexStr; @Transient private String handTimeStr; //getter and setter ... }
dao层
package com.h3c.zgc.upload; import java.io.Serializable; import java.util.List; import javax.annotation.Resource; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.transform.Transformers; import org.springframework.orm.hibernate4.support.HibernateDaoSupport; import org.springframework.stereotype.Repository; @Repository public class UploadDownDao extends HibernateDaoSupport{ @Resource public void set(SessionFactory sessionFactory){ this.setSessionFactory(sessionFactory); } public Session getSession(){ return this.getSessionFactory().openSession(); } /** * 获取附件id最大值 */ public Long getMaxIdOfAnnex(){ List l = this.getHibernateTemplate().find("select max(id) from Annex"); System.out.println(l); &&l.)!=null){ ); } return 0L; } /** * 获取处理过程id最大值 * @return */ public Long getMaxIdOfHandProcess(){ List l = this.getHibernateTemplate().find("select max(id) from HandProcess"); System.out.println(l); &&l.)!=null){ ); } return 0L; } /** * 保存附件 * @param annex * @return */ public Serializable saveAnnex(Annex annex){ return this.getHibernateTemplate().save(annex); } /** * 保存处理过程 * @param hp * @return */ public Serializable saveHandProcess(HandProcess hp){ return this.getHibernateTemplate().save(hp); } /** * 获取处理过程列表,左连接查询 * @return */ public List getHandProcessList(){//有没有可能没有附件,附件annex,处理过程handprocess SQLQuery query = this.getSession().createSQLQuery("select h.id handprocessId,h.annexStr annexStr,a.id annexId,a.realName realName,h.handTime handTime,h.handName handName,h.reason reason from handprocess h left join annex a on a.handId=h.id"); query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); List list = query.list(); return list; } /** * 根据id获取附件信息 * @param annexId * @return */ public Annex getAnnexById(Long annexId){ return this.getHibernateTemplate().get(Annex.class, annexId); } /** * 修改处理过程 * @param hp */ public void updateHandProcess(HandProcess hp){ this.getHibernateTemplate().update(hp); } }
service层
package com.h3c.zgc.upload; import java.io.Serializable; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.transaction.Transactional; import org.springframework.stereotype.Service; @Service public class UploadDownService { @Resource private UploadDownDao uploadDownDao; public Long getMaxIdOfAnnex(){ return this.uploadDownDao.getMaxIdOfAnnex(); } public Long getMaxIdOfHandProcess(){ return this.uploadDownDao.getMaxIdOfHandProcess(); } @Transactional public Serializable saveAnnex(Annex annex){ return this.uploadDownDao.saveAnnex(annex); } @Transactional public Serializable saveHandProcess(HandProcess hp){ return this.uploadDownDao.saveHandProcess(hp); } public Annex getAnnexById(Long annexId){ return this.uploadDownDao.getAnnexById(annexId); } public List<Map<String,Object>> getHandProcessList(){ return this.uploadDownDao.getHandProcessList(); } @Transactional public void updateHandProcess(HandProcess hp){ this.uploadDownDao.updateHandProcess(hp); } }
controller层
package com.h3c.zgc.upload; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; @Controller public class UploadDownFileController { @Resource private UploadDownService uploadDownService; //单文件上传到数据库,MultipartFile中封装了上传文件的信息 @RequestMapping("upload") public String upload(HandProcess hp, HttpServletRequest request, @RequestParam("uploadFile1") MultipartFile uploadFile1) throws IOException, ParseException { InputStream is = uploadFile1.getInputStream(); byte[] buffer = this.inputStrean2ByteArr(is); /** * 保存处理过程信息 */ // get max id then ++1 Long hpMaxId = this.uploadDownService.getMaxIdOfHandProcess(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); hp.setHandTime(df.parse(hp.getHandTimeStr()).getTime()); hp.setId(hpMaxId + ); //保存处理过程 Serializable hpId = this.uploadDownService.saveHandProcess(hp); /** * 保存附件 */ Annex annex = new Annex(); annex.setCustomerId(1L); annex.setHandId((Long) hpId); annex.setRealName(uploadFile1.getOriginalFilename()); annex.setFileContent(buffer); //查找附件id最大值 annex.setId(); Serializable aid = this.uploadDownService.saveAnnex(annex); /** * 获取处理过程列表 */ List<Map<String, Object>> as = this.uploadDownService .getHandProcessList(); for (Map<String, Object> map : as) { map.put("handTime", df.format(map.get("handTime"))); } request.setAttribute("as", as); return "annex/annexList"; } /** * 多文件上传 * @param hp 处理过程 * @param request * @param uploadFile1 上传文件 * @return * @throws IOException * @throws ParseException */ @RequestMapping("uploadOneMore") public String uploadOneMore(HandProcess hp, HttpServletRequest request, @RequestParam("uploadFile1") MultipartFile[] uploadFile1) throws IOException, ParseException { /** * 保存处理过程信息 */ // get max id then ++1 Long hpMaxId = this.uploadDownService.getMaxIdOfHandProcess(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); hp.setHandTime(df.parse(hp.getHandTimeStr()).getTime()); hp.setId(hpMaxId + ); // Serializable hpId = this.uploadDownService.saveHandProcess(hp); //保存改工单下的所有附件 ; i < uploadFile1.length; i++) { InputStream is = uploadFile1[i].getInputStream(); byte[] buffer = this.inputStrean2ByteArr(is); /** * 保存附件 */ Annex annex = new Annex(); annex.setCustomerId(1L); annex.setHandId((Long) hpId); annex.setRealName(uploadFile1[i].getOriginalFilename()); annex.setFileContent(buffer); annex.setId(); Serializable annexId = this.uploadDownService.saveAnnex(annex); } //多文件上传,一个处理过程下面要有多个附件,在页面中显示的时候,一个处理过程后面要显示多个附件 //更新表handprocess this.uploadDownService.updateHandProcess(hp); List<Map<String, Object>> as = this.uploadDownService .getHandProcessList(); request.setAttribute("as", as); return "annex/annexList"; } /** * 文件下载 * @param response * @param annexId * @throws IOException */ @RequestMapping("download") public void download(HttpServletResponse response, Long annexId) throws IOException { Annex a = this.uploadDownService.getAnnexById(annexId); byte[] b = a.getFileContent(); response.setContentType("application/octet-stream;charset=UTF-8"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + new String(a.getRealName().getBytes("gbk"),"iso-8859-1")); //防止文件乱码 BufferedOutputStream bos = new BufferedOutputStream( response.getOutputStream()); bos.write(b); bos.close(); } /** * inputstream转成byte数组 * @param inStream * @return * @throws IOException */ public byte[] inputStrean2ByteArr(InputStream inStream) throws IOException { ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); ]; ; , )) > ) { swapStream.write(buff, , rc); } byte[] in2b = swapStream.toByteArray(); return in2b; } }
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="${pageContext.request.contextPath }/resources/js/jquery-1.11.1.js"></script> </head> <body> <a href="${pageContext.request.contextPath }/getAllStudent">查找所有用户</a> <a href="${pageContext.request.contextPath }/savePerson">单独保存Person</a> <a href="${pageContext.request.contextPath }/savePersonHouse">保存Person和House</a> <br/> <form action="${pageContext.request.contextPath }/getArr" > <input type="text" name="workSheetId"/><br/> <input type="submit" value="search"/> </form> <br/><br/><br/> <form action="<c:url value="/upload"/>" method="post" enctype="multipart/form-data"> 处理时间:<input type="text" name="handTimeStr"/><br> 处理人:<input type="text" name="handName"/><br/> 原因:<input type="text" name="reason"/><br/> 选择文件:<input type="file" name="uploadFile1"/><br/> <input type="submit" value="submit"/> </form> <br/> upload one more <form action="<c:url value="/uploadOneMore"/>" method="post" enctype="multipart/form-data"> 处理时间:<input type="text" name="handTimeStr"/><br> 处理人:<input type="text" name="handName"/><br/> 原因:<input type="text" name="reason"/><br/> 选择文件:<input type="file" name="uploadFile1"/><br/> 选择文件:<input type="file" name="uploadFile1"/><br/> 选择文件:<input type="file" name="uploadFile1"/><br/> <input type="submit" value="submit"/> </form> </body> </html>
annexList.jsp 显示处理过程已经处理过程下附件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="${pageContext.request.contextPath }/resources/js/jquery-1.11.1.js"></script> </head> <body> <table> <c:forEach items="${as }" var="ah" varStatus="status"> <tr> <td>${ah['handprocessId'] }</td> <td>${ah['handName'] }</td> <td>${ah['reason'] }</td> <td id="id${status.index }">${ah['handTime'] }</td> <td> ${ah['annex']['realName'] } <a href="<c:url value="/download?annexId=${ah['annexId'] }"/>">${ah['realName'] }</a> </td> </tr> </c:forEach> </table> </body> <script type="text/javascript"> </script> </html>
springMVC+spring+hibernate注解上传文件到数据库,下载,多文件上传的更多相关文章
- SpringMVC+Spring+Hibernate的小样例
Strusts2+Spring+Hibernate尽管是主流的WEB开发框架,可是SpringMVC有越来越多的人使用了.确实也很好用.用得爽! 这里实现了一个SpringMVC+Spring+Hib ...
- Maven搭建springMVC+spring+hibernate环境
这次不再使用struts2做控制器,采用spring自己的springMVC框架实现. 首先,改写pom.xml文件,不需要struts2的相关jar了. pom.xml <project xm ...
- SpringMVC+Spring+Hibernate整合开发
最近突然想认真研究下java web常用框架,虽然现在一直在用,但实现的整体流程不是很了解,就在网上搜索资料,尝试自己搭建,以下是自己的搭建及测试过程. 一.准备工作: 1/安装并配置java运行环境 ...
- Springmvc+Spring+Hibernate搭建方法
Springmvc+Spring+Hibernate搭建方法及example 前面两篇文章,分别介绍了Springmvc和Spring的搭建方法,本文再搭建hibernate,并建立SSH最基本的代码 ...
- Springmvc+Spring+Hibernate搭建方法及实例
Springmvc+Spring+Hibernate搭建方法及实例
- SpringMVC+Spring+Hibernate个人家庭财务管理系统
项目描述 Hi,大家好,今天分享的项目是<个人家庭财务管理系统>,本系统是针对个人家庭内部的财务管理而开发的,大体功能模块如下: 系统管理模块 验证用户登录功能:该功能主要是验证用户登录时 ...
- spring(一)--spring/springmvc/spring+hibernate(mybatis)配置文件
这篇文章用来总结一下spring,springmvc,spring+mybatis,spring+hibernate的配置文件 1.web.xml 要使用spring,必须在web.xml中定义分发器 ...
- SpringMVC+Spring+Hibernate框架整合原理,作用及使用方法
转自:https://blog.csdn.net/bieleyang/article/details/77862042 SSM框架是spring MVC ,spring和mybatis框架的整合,是标 ...
- springMVC+spring+hibernate 框架整合实例
先说一下流程思路: 流程讲解1:首先访问会先定位到控制器.这就用到了过滤器配置文件"spring-mvc.xml".这个文件负责定义控制器的包路径.视图的格式等.其次从" ...
随机推荐
- SQLServer 维护脚本分享(10)索引
--可添加索引的字段 migs.user_seeks,migs.avg_total_user_cost,migs.avg_user_impact,migs.last_user_seek ,mid.st ...
- 【java 断点续传】
模拟 断点续传 首先,先读取word文件的 一部分 package com.sxd.readLines; import java.io.File; import java.io.FileInputSt ...
- Android常用控件之GridView与ExpandableListView的用法
概述 1.GridView:与ListView相比,可以显示多列,xml布局时其属性numColumns可以设置显示的列数. 2.ExpandableListView:与ListView相比,可以让每 ...
- 记一次小团队Git实践(上)
公司规模不大,成立之初,选择了svn作为版本控制系统.这对于用惯了git的我来说,将就了一段时间后,极为不爽,切换到git-svn勉强能用.随后,因为产品需要发布不同的版本,而git-svn对远程分支 ...
- nefu 197 KMP
Description 在信息检索系统中一个很重要的环节就是关键字符串的查找,从而很多对自己有用的信息.给你一个很长的一段文字, 和一个关键信息字符串,现在要你判断这段文字里面是否有关键字符串. In ...
- maven自建仓库 Return code : 405
maven自建仓库jar包上传: jar包上传可以采用在自建仓库上系统上传以及通过配置maven setting.xml以及pom.xml上传. maven通过配置上传需要用户名密码以及maven仓库 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- shinydashboard包---为shiny提供BI框架
1.安装 install.packages("shinydashboard") 2.基础知识 仪表盘有三个部分:标题.侧边栏,身体.下面是最最小的仪表面板页面的UI: ## ui. ...
- Android Fragment 生命周期及其API使用(建议使用自定义View替换Fragment)
我为什么不主张使用Fragment Fragment:( Fragment就相当于一个有生命周期的View,它的生命周期被所在的Activity的生命周期管理 ) 生命周期回调说明: onAttach ...
- SpringMvc出现No mapping found for HTTP request with URI的终极解决办法
No mapping found for HTTP request with URI 出现这个问题的原因是在web.xml中配置错了,如: <servlet> <servlet-na ...