数据库

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注解上传文件到数据库,下载,多文件上传的更多相关文章

  1. SpringMVC+Spring+Hibernate的小样例

    Strusts2+Spring+Hibernate尽管是主流的WEB开发框架,可是SpringMVC有越来越多的人使用了.确实也很好用.用得爽! 这里实现了一个SpringMVC+Spring+Hib ...

  2. Maven搭建springMVC+spring+hibernate环境

    这次不再使用struts2做控制器,采用spring自己的springMVC框架实现. 首先,改写pom.xml文件,不需要struts2的相关jar了. pom.xml <project xm ...

  3. SpringMVC+Spring+Hibernate整合开发

    最近突然想认真研究下java web常用框架,虽然现在一直在用,但实现的整体流程不是很了解,就在网上搜索资料,尝试自己搭建,以下是自己的搭建及测试过程. 一.准备工作: 1/安装并配置java运行环境 ...

  4. Springmvc+Spring+Hibernate搭建方法

    Springmvc+Spring+Hibernate搭建方法及example 前面两篇文章,分别介绍了Springmvc和Spring的搭建方法,本文再搭建hibernate,并建立SSH最基本的代码 ...

  5. Springmvc+Spring+Hibernate搭建方法及实例

    Springmvc+Spring+Hibernate搭建方法及实例  

  6. SpringMVC+Spring+Hibernate个人家庭财务管理系统

    项目描述 Hi,大家好,今天分享的项目是<个人家庭财务管理系统>,本系统是针对个人家庭内部的财务管理而开发的,大体功能模块如下: 系统管理模块 验证用户登录功能:该功能主要是验证用户登录时 ...

  7. spring(一)--spring/springmvc/spring+hibernate(mybatis)配置文件

    这篇文章用来总结一下spring,springmvc,spring+mybatis,spring+hibernate的配置文件 1.web.xml 要使用spring,必须在web.xml中定义分发器 ...

  8. SpringMVC+Spring+Hibernate框架整合原理,作用及使用方法

    转自:https://blog.csdn.net/bieleyang/article/details/77862042 SSM框架是spring MVC ,spring和mybatis框架的整合,是标 ...

  9. springMVC+spring+hibernate 框架整合实例

    先说一下流程思路: 流程讲解1:首先访问会先定位到控制器.这就用到了过滤器配置文件"spring-mvc.xml".这个文件负责定义控制器的包路径.视图的格式等.其次从" ...

随机推荐

  1. SQLServer 维护脚本分享(10)索引

    --可添加索引的字段 migs.user_seeks,migs.avg_total_user_cost,migs.avg_user_impact,migs.last_user_seek ,mid.st ...

  2. 【java 断点续传】

    模拟 断点续传 首先,先读取word文件的 一部分 package com.sxd.readLines; import java.io.File; import java.io.FileInputSt ...

  3. Android常用控件之GridView与ExpandableListView的用法

    概述 1.GridView:与ListView相比,可以显示多列,xml布局时其属性numColumns可以设置显示的列数. 2.ExpandableListView:与ListView相比,可以让每 ...

  4. 记一次小团队Git实践(上)

    公司规模不大,成立之初,选择了svn作为版本控制系统.这对于用惯了git的我来说,将就了一段时间后,极为不爽,切换到git-svn勉强能用.随后,因为产品需要发布不同的版本,而git-svn对远程分支 ...

  5. nefu 197 KMP

    Description 在信息检索系统中一个很重要的环节就是关键字符串的查找,从而很多对自己有用的信息.给你一个很长的一段文字, 和一个关键信息字符串,现在要你判断这段文字里面是否有关键字符串. In ...

  6. maven自建仓库 Return code : 405

    maven自建仓库jar包上传: jar包上传可以采用在自建仓库上系统上传以及通过配置maven setting.xml以及pom.xml上传. maven通过配置上传需要用户名密码以及maven仓库 ...

  7. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  8. shinydashboard包---为shiny提供BI框架

    1.安装 install.packages("shinydashboard") 2.基础知识 仪表盘有三个部分:标题.侧边栏,身体.下面是最最小的仪表面板页面的UI: ## ui. ...

  9. Android Fragment 生命周期及其API使用(建议使用自定义View替换Fragment)

    我为什么不主张使用Fragment Fragment:( Fragment就相当于一个有生命周期的View,它的生命周期被所在的Activity的生命周期管理 ) 生命周期回调说明: onAttach ...

  10. SpringMvc出现No mapping found for HTTP request with URI的终极解决办法

    No mapping found for HTTP request with URI 出现这个问题的原因是在web.xml中配置错了,如: <servlet> <servlet-na ...