给同事做一个下载的功能,将数据库关联查询后生产csv文件供下载,期间遇到的小问题,记录下。
1,数据库的关联查询
查询出来的数据结构是:一个表TABLE_A的部分数据,和TABLE_A的每条数据在TABLE_B表中的个数
mapper.xml文件 sql语句(下面的方式可能会引发一些问题,下面讲)
<resultMap id="aAndCount" type="com.model.AandCount">
<result column="follow_count" property="followCount" jdbcType="INTEGER">
<association column="a.id" property="dxzf" javaType="com.model.Dxzf">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
</association>
</resultMap>
<select id="queryAandCount" resultMap="aAndCount">
select count(a.id) follow_count , a.id id , a.name name
from TABLE_A a
inner join TABLE_B b on TABLE_A.id = TBALE_B.aId and TABLE_A.status = 1
group by aId
order by follow_count desc
limit 100
</select>
然后在aMapper.java中
List<AandCount> queryAandCount();
当用service调用这个mapper.queryAandCount()的时候,返回的数据与预想的不一样.
具体是:follow_count 字段没有重复的数据,即 只有唯一性的数据 14,13,12,11,... 而把sql放到客户端执行,真实数据是 14,13,13,12,12,11...
怀疑是把 follow_count 做了唯一性处理。
所以修改了 mapper.xml文件 sql语句 如下(因为 a表的id是返回的数据中唯一性的,将其添加到第一个返回值中)
<resultMap id="aAndCount" type="com.model.AandCount">
<result column="a_id" property="aId" jdbcType="INTEGER">
<result column="follow_count" property="followCount" jdbcType="INTEGER">
<association column="a.id" property="dxzf" javaType="com.model.Dxzf">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
</association>
</resultMap>
<select id="queryAandCount" resultMap="aAndCount">
select a.id a_id , count(a.id) follow_count , a.id id , a.name name
from TABLE_A a
inner join TABLE_B b on TABLE_A.id = TBALE_B.aId and TABLE_A.status = 1
group by aId
order by follow_count desc
limit 100
</select>
暂时这么解决了问题。
2,文件下载的实现
在nginx配置文件中添加了下载路径
server{
listen 80;
server_name test.abcd.com;
location ~ ^/csv # 下载csv文件的路径
{
root /opt/tomcat-abcd ; # 当访问到 test.abcd.com/csv 的时候将会查找服务器中的 /opt/tomcat-abcd/csv 里面的文件.
}
}
Controller.java 文件
@RequestMapping(value="/downloadCSV")
public String downloadCSV(Model model){
List<AandCount> list = service.queryAandCount();
String fileName = "./csv/date.csv";
createCSV(list,fileName);
// 跳转到下载链接
model.addAttribute("redirectUrl",fileName.replaceFirst(".",""));
return "forward:/home/operationRedirect";
}
3,csv的生成 createCSV(list,fileName);
public void createCSV(List<AandCount> list,String fileName){
XSSFWorkbook workbook = new XSSFWordbook();
XSSFWordbook sheet = workbook.createSheet("sheetName");
if(CollectionUtils.isNotEmpay(list)){
int index = 0;
foreach(AandCount a : list){
XSSFRow row = sheet.createRow(i);
XSSFCell cell = row.createCell(0,Cell.CELL_TYPE_STRING);
cell.setCellValue(a.getaId());
...
}
}
// 将csv写入服务器指定路径
FileOutputStream fos = null;
try{
fos = new FileOutputStream(fileName);
workbook.write(fos);
}catch(IOExecption e){
...
}finally{
if(fos != null){
try{
fos.close();
}catch(IOExecption e){
...
}
}
}
}