现在我们来做一个文件上传与下载的综合案例。
创建MVC架构的Web项目
首先,在Eclipse中新建一个day18_upload的项目,然后导入项目所需要的开发包(jar包),创建项目所需要的包,在Java Web开发中,架构的层次是以包的形式体现出来的。
以上就是根据该项目的实际需求创建的组织程序的包,当然了,还可视情况酌情添加。接下来,我们就要为该项目创建相应的库和表了。数据库比较好建,就是:
create database day18 character set utf8 collate utf8_general_ci;
use day18;
可能比较有点难度的就是这个表该怎么建了,我们做的可是一个较简陋的文件上传与下载系统哟,上传的自然就是一个个文件了,那我们就要想文件的哪些信息应该保存到表里面去,想清楚这点,表就不难建了,下面直接给出建表SQL语句:
create table upfile
(
id varchar(40) primary key,
uuidname varchar(100) not null unique,
filename varchar(100) not null,
savepath varchar(255) not null,
uptime datetime not null,
description varchar(255),
username varchar(40) not null
);
大家有没发现这点,主键列往往都是用UUID算法生成的,可我们从来都没说过其原因,在这里解惑。主键列用UUID算法生成的原因:用UUID算法有一个好处,就是将来数据库做移植比较方便,用UUID算法生成的主键列全球唯一,将来我这个表和别的表合在一起的话,就不会有主键冲突的问题。使用UUID算法最主要的原因就是考虑到将来系统的扩展。但是,用UUID算法有一个坏处:生成的全球唯一的字符串太长,有36位。
分层架构的代码编写
分层架构的代码是按照【域模型层(domain)】→【数据访问层(dao、dao.impl)】→【业务逻辑层(service、service.impl)】→【表现层(web.controller、web.UI、web.filter、web.listener)】的顺序进行编写的,另外【工具类(util)】、【测试类(junit.test)】的编写穿插其中。
开发domain层
在cn.liayun.domain包下创建一个Upfile类,该类的具体代码如下:
package cn.liayun.domain;
import java.util.Date;
public class Upfile {
private String id;
private String uuidname; //上传文件的名称,文件的uuid名
private String filename; //上传文件的真实名称
private String savepath; //记住文件的位置
private Date uptime; //文件的上传时间
private String description; //文件的描述
private String username; //上传人
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUuidname() {
return uuidname;
}
public void setUuidname(String uuidname) {
this.uuidname = uuidname;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getSavepath() {
return savepath;
}
public void setSavepath(String savepath) {
this.savepath = savepath;
}
public Date getUptime() {
return uptime;
}
public void setUptime(Date uptime) {
this.uptime = uptime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
开发数据访问层(dao、dao.impl)
为了提升程序的数据库访问性能,我们通常在项目开发中使用C3P0数据源。所以应在类目录下加入C3P0的配置文件:c3p0-config.xml。
c3p0-config.xml配置文件的内容如下:
<c3p0-config>
<!--
C3P0的缺省(默认)配置,
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源
-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day18</property>
<property name="user">root</property>
<property name="password">liayun</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property><!-- 最大空闲时间 -->
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
<property name="maxStatements">200</property>
</default-config>
<!--
C3P0的命名配置,
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("mysql");”这样写就表示使用的是name为mysql的配置信息来创建数据源
-->
<named-config name="mysql">
<property name="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000</property>
<!-- intergalactoApp adopts a different approach to configuring statement
caching -->
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
<named-config name="oracle">
<property name="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000</property>
<!-- intergalactoApp adopts a different approach to configuring statement
caching -->
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
也是为了简化JDBC的开发,我们使用Apache组织提供的一个开源JDBC工具类库——commons-dbutils-1.6.jar。然后在cn.liayun.utils包下创建一个JdbcUtils工具类,用于读取C3P0的xml配置文件创建数据源。
package cn.liayun.utils;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils {
private