结对作业(2/2)
这个作业属于哪个课程 | 2021春软件工程实践|W班(福州大学) |
---|---|
这个作业要求在哪里 | 结对第二次作业 |
这个作业的目标 | 实现论文管理平台 |
其他参考文献 | CSDN |
目录
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 35 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 35 |
Development | 开发 | 2150 | 2650 |
• Analysis | • 需求分析 (包括学习新技术) | 420 | 600 |
• Design Spec | • 生成设计文档 | 20 | 20 |
• Design Review | • 设计复审 | 10 | 10 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
• Design | • 具体设计 | 20 | 30 |
• Coding | • 具体编码 | 1580 | 1800 |
• Code Review | • 代码复审 | 30 | 50 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 55 | 70 |
• Test Repor | • 测试报告 | 30 | 40 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 15 | 20 |
合计 | 2235 | 2755 |
Github仓库地址及代码规范
云服务器访问链接
成品展示
首页
分页
搜索结果
论文删除
热词变化趋势
关键词图谱
点击关键词跳转到搜索界面
结对讨论过程描述
- 刚开始两个人都不知道要怎么开始这个项目,因为两个人其实web的基础都不是很好,看到题目都挺懵的。后面和其他同学交流,就打算使用jsp进行这个项目。我们主要通过QQ进行交流,当代码有问题的时候会一起出来对代码进行检查。
- 因为我比较菜,主要是靠队友给我指导,让我知道该往哪个方向思考
- 一起讨论问题
设计实现过程
- 数据库表设计:两张表:academics、keywords
-
后端:
使用java语言对数据库进行交互
设计Paper类,HotWord类对需要的数据进行封装
设计Base类提供静态方法,对数据库进行连接
设计ArticleDao类提供静态方法,提供数据接口,使其能够调用
通过servlet来调用接口将数据注入页面 -
前端:
使用html设计页面,使用css对页面进行布局
展示论文列表
实现论文的删除功能
实现论文的搜索功能
展示论文的搜索结果
实现列表的分页功能 -
功能结构图:
关键代码说明
- 利用JSTL标准标签库来实现foreach功能,使从数据库获得的数据可以全部展示在页面。
<c:forEach var="p" items="${paperList}">
<div class="block">
<a class="title_a">标题:
</a>${p.title}<br>
<a class="conclude">摘要:</a>
<div class=conclude_content>${p.abstractString}</div>
<a class="keyword">关键词:</a>
<div class="word">
${p.keywords.size()>0?p.keywords.get(0):null},
${p.keywords.size()>1?p.keywords.get(1):null},
${p.keywords.size()>2?p.keywords.get(2):null}
</div>
</div>
</c:forEach>
- 通过给servlet传递参数来改变请求的数据库内容来实现分页功能,减少加载页面的时间。
<div class="page">
共${tsum}条记录,当前在${cpage}/${tpage}页
<a class="btn_page" href="DoUserSelect?cp=1">首页</a>
<a class="btn_page" href="DoUserSelect?cp=${cpage>1?cpage-1:1}">上一页</a>
<a class="btn_page" href="DoUserSelect?cp=${cpage>tpage-1?tpage:cpage+1}">下一页</a>
<a class="btn_page" href="DoUserSelect?cp=${tpage}">尾页</a>
</div>
- 利用js和java结合来向页面写入内容。
for(HotWord hw : list)
{
%>
obj.name = ("<%=hw.getMeetingName()%>");
obj.type = 'line';
obj.data = <%=hw.getNumList()%>;
arr.push(Object.assign({},obj));
obj1.name = ("<%=hw.getMeetingName()%>_");
obj1.type = 'line';
<%
for(String string : hw.getWordList())
{
%>
detail.push('<%=string%>');
<%
}
%>
console.log("detail", detail);
obj1.data = detail.concat();
arr.push(Object.assign({},obj1));
detail.splice(0);
<%
}
- 通过修改echarts的tooltip参数来实现移动到统计曲线的点显示该点的数目以及该点的词。
formatter: function (params, ticket, callback) {
var htmlStr = '';
for(var i=0;i<params.length;i++){
var param = params[i];
var xName = param.name;//x轴的名称
var seriesName = param.seriesName;//图例名称
var value = param.value;//y轴值
var color = param.color;//图例颜色
if(i===0){
htmlStr += xName + '<br/>';//x轴的名称
}
htmlStr +='<div>';
if(seriesName === 'ICCV_'){
htmlStr += 'ICCV: ' + value;
}
else if(seriesName === 'ECCV_'){
htmlStr += 'ECCV: ' + value;
}
else if(seriesName === 'CVPR_'){
htmlStr += 'CVPR: ' + value;
}else{
htmlStr += '<span style="margin-right:5px;display:inline-block;width:10px;height:10px;border-radius:5px;background-color:'+color+';"></span>';
htmlStr += seriesName + ':' + value ;
}
htmlStr += '</div>';
}
return htmlStr;
}
- 通过condition参数来传递要进行搜索的关键词,从而实现在关键词图谱界面点击关键词就可以直接到达搜索界面并展示搜索对应的结果。
condition = (String) request.getParameter("condition");
if(!condition.equals(null) && !condition.equals("")) {
list = ArticleDao.selectSpecial(condition,cpage,count);
total = ArticleDao.searchTotal(condition);
}
else {
list.clear();
total = 0;
}
request.setAttribute("condition", condition);
request.setAttribute("paperList", list);
request.setAttribute("tsum", total);
request.setAttribute("tpage", total/count+1);
request.setAttribute("cpage", cpage);
request.getRequestDispatcher("Search.jsp").forward(request, response);
后端获取全部论文,使用sql语句对数据库进行全部查找,返回论文集即可
public static ArrayList<Paper> selectAll(int cpage,int count) {
String sqlString = "select * from academics limit ?,?";
return list;
}
后端搜索指定论文,对标题和关键词进行模糊查询,同时对两表进行查询,加快了效率,之前是分两次分别对各个表进行查询,导致效率低下
public static ArrayList<Paper> selectSpecial(String conditionString,int cpage,int count) {
String sqlString = "select * from academics where title like '%"+conditionString+"%' "+ "or academicNum in (select academicNum from keywords where keyword like '%"+conditionString+"%') limit ?,?";
return list;
}
后端获取每年每个顶会前十关键词,使用之前WordCount的排序功能对关键字频率进行排序,返回每年每个顶会的热词结果集
public static HotWord selectYearData(String year,String meeting) {
String sqlString = "select keyword from keywords where academicNum in " + " (select academicNum from academics where year ='"+year+"' and academicNum <= "+max+" and academicNum>="+min+")";
//对关键字进行排序
wordList = new ArrayList<Map.Entry<String,Integer>>(wordMap.entrySet());
Collections.sort(wordList, new Comparator<Map.Entry<String,Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o2.getValue()==o1.getValue()){
return o1.getKey().compareTo(o2.getKey());
}
return o2.getValue().compareTo(o1.getValue());
}
});
return hotWord;
}
public static ArrayList<HotWord> getMeetingList(String year) {
ArrayList<HotWord> meetingHotWord = new ArrayList<HotWord>();
HotWord hotWord1 = selectYearData(year, "CVPR");
HotWord hotWord2 = selectYearData(year, "ICCV");
HotWord hotWord3 = selectYearData(year, "ECCV");
meetingHotWord.add(hotWord1);
meetingHotWord.add(hotWord2);
meetingHotWord.add(hotWord3);
return meetingHotWord;
}
后端获取所有论文中前十的关键字,使用sql语句读取所有关键字,对关键字进行次数累计,同样是使用之前的排序功能进行次数排序,返回结果集
public static ArrayList<String> selectKeyWords() {
String sqlString = "select * from keywords";
List<Map.Entry<String, Integer>> wordList;
Map<String,Integer> wordMap = new HashMap<String, Integer>();
for (int i = 0; i < keywordList.size(); i++) {
String keywordString = keywordList.get(i);
Integer countInteger = wordMap.get(keywordString);
if (countInteger == null) {
countInteger = 1;
}
else {
countInteger++;
}
wordMap.put(keywordString, countInteger);
}
wordList = new ArrayList<Map.Entry<String,Integer>>(wordMap.entrySet());
//对关键字进行排序
Collections.sort(wordList, new Comparator<Map.Entry<String,Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o2.getValue()==o1.getValue()){
return o1.getKey().compareTo(o2.getKey());
}
return o2.getValue().compareTo(o1.getValue());
}
});
ArrayList<String> top10 = new ArrayList<String>();
//选取前10关键字
int i = 1;
for (Map.Entry<String,Integer> entry:wordList)
{
if (i>10) {
break;
}
top10.add(entry.getKey());
i++;
}
return top10;
}
心路历程和收获
-
铭震:对java的数据库操作更加熟悉;一开始是完全没有接触过JSP的,不知道如何进行前后端交互,和队友一起交流沟通,逐渐熟悉了JSP,能够写一部分Servlet;前端也学会了echart的使用,在这次结对的过程中锻炼了自己的沟通能力和合作能力。
-
灿宇:本次编程其实也是我第一次学习java前后端的实践,使用了jsp的框架来编写此次作业。让我巩固了前端的代码,也学会了serlvet的传参方法。后端上也巩固了利用java代码对数据库操作的方法,我觉得本次结对过程提升了我的代码水平和与人交流的能力。
队友评价:
-
铭震:全程都是灿宇在指导我,因为自己编程方面不算很强,很多新知识都是灿宇在教我,而且他学习新技术比我快,当我遇到困难,他也非常乐意帮助我。而且他很负责任,明确了分工,需要哪些接口都讲的很清楚。
-
灿宇:铭震同学的执行力很强,每次后端接口代码写得又快又好,让我想拖延的机会都没有,很快的完成了这次作业的编写。在对具体功能的实现上,他也有很多独到的见解,让我们迅速的确立了需求。和他的合作让我很舒服,也很满意。