数据库
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>