1.使用Echarts柱状图显示收入统计信息-业务层和DAO层
(1)后台如何拼接对应的json字符串?
List<Object []> data=expDao.selPieData();
StringBuilder jsonStr=new StringBuilder("[");
for (int i = 0; i < data.size(); i++) {
Object[] arr = data.get(i);
jsonStr.append("{");
jsonStr.append("\"value\":"+arr[1]+",");
jsonStr.append("\"name\":\""+arr[0]+"\"");
if(i<data.size()-1){
jsonStr.append("},");
}else{
jsonStr.append("}");
}
/* if (i<data.size()-1) {
jsonStr.append("{value:"+arr[0]+",");
jsonStr.append("name:\""+arr[1]+"\"},");
}else{
jsonStr.append("name:\""+arr[1]+"\"}");
}
}*/
}
jsonStr.append("]");
return jsonStr.toString();
List<Object []> data=expDao.selPieDataByType(type);
StringBuilder jsonStr=new StringBuilder("[");
for (int i = 0; i < data.size(); i++) {
Object[] arr = data.get(i);
/*jsonStr.append("{");
jsonStr.append("\"value\":"+arr[1]+",");
jsonStr.append("\"name\":\""+arr[0]+"\"");
if(i<data.size()-1){
jsonStr.append("},");
}else{
jsonStr.append("}");
}*/
if (i<data.size()-1) {
jsonStr.append("{value:"+arr[1]+",");
jsonStr.append("name:\""+arr[0]+"\"},");
}else{
jsonStr.append("{value:"+arr[1]+",");
jsonStr.append("name:\""+arr[0]+"\"}");
}
}
jsonStr.append("]");
return jsonStr.toString();
}
2.收支管理-财务添加支出
(1)当前审批人假如是财务,那么要进行什么操作,简述逻辑。
通过审核,并将报销单的相关数据插入到数据库支出表中,并修改报销单状态
(2)截止到这里,审批报销单功能彻底完成,再次概述整个审批逻辑。
当有报销单需要报销时,首先判断报销金额,如果金额小于2500,则由该报销人的直接上级报销,然后交由财务部门,财务进行批准,并修改报销单的状态,如果金额大于2500,该报销人 的直接上级审核过后,还要经过总裁进行审核,最终交由财务部门,添加支出,并修改报销单状态,如果不通过或者拒绝,都是发回该报销人
标题3.收支管理-查看支出
(1)到这里,对于查看收支功能实现应该是不陌生了,重点就是查询收支的sql,请问这个sql怎么编写呢?
//创建SQL命令
StringBuilder sql=new StringBuilder("select item.itemid,item.type,item.amount,item.itemdesc,"
+ "pm.paytime,exp.expid,emp.realname,emp2.realname"
+ " from payment pm join expense exp on pm.expid=exp.expid"
+ " join expenseitem item on exp.expid=item.expid join employee emp "
+ "on pm.payempid=emp.empid join employee emp2 on exp.empid=emp2.empid "
+ "where 1=1 ");
//创建SQL命令对象
ps=conn.prepareStatement(sql.toString());
4.收支管理-使用饼图显示支出
(1)如何使用Echarts完成饼图展示?
第一步:初始化饼图实例对象
第一步:获取数据
第三步:将其放在容器中
(2)如何将后台查出来的集合转换成为json字符串?
List<Object []> data=expDao.selPieDataByType(type);
StringBuilder jsonStr=new StringBuilder("[");
for (int i = 0; i < data.size(); i++) {
Object[] arr = data.get(i);
/*jsonStr.append("{");
jsonStr.append("\"value\":"+arr[1]+",");
jsonStr.append("\"name\":\""+arr[0]+"\"");
if(i<data.size()-1){
jsonStr.append("},");
}else{
jsonStr.append("}");
}*/
if (i<data.size()-1) {
jsonStr.append("{value:"+arr[1]+",");
jsonStr.append("name:\""+arr[0]+"\"},");
}else{
jsonStr.append("{value:"+arr[1]+",");
jsonStr.append("name:\""+arr[0]+"\"}");
}
}
jsonStr.append("]");
return jsonStr.toString();
}
5.收支管理-使用饼图显示指定时间段的支出
(1)如何在代码中加入逻辑:显示指定时间段的支出。
//创建SQL命令
StringBuilder sql=new StringBuilder("select item.type,sum(item.amount) from payment pm "
+ "join expense exp on pm.expid=exp.expid "
+ "join expenseitem item on exp.expid=item.expid "
+ "where 1=1 ");
if (type==1) {
sql.append("and paytime>=to_date('"+DateUtil.getNowMonthBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
}
if (type==2) {
sql.append("and paytime>=to_date('"+DateUtil.getLastMonthBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
sql.append("and paytime<to_date('"+DateUtil.getNowMonthBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
}
if (type==3) {
sql.append("and paytime>=to_date('"+DateUtil.getRecentTMBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
}
if (type==4) {
sql.append("and paytime>=to_date('"+DateUtil.getNowYearBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
sql.append("and paytime<to_date('"+DateUtil.getFHYearEndTime()+"','yyyy-MM-dd hh24:mi:ss')");
}
if (type==5) {
sql.append("and paytime>=to_date('"+DateUtil.getLastYearBeginTime()+"','yyyy-MM-dd hh24:mi:ss')");
sql.append("and paytime<to_date('"+DateUtil.getLastYearEndTime()+"','yyyy-MM-dd hh24:mi:ss')");
}
sql.append("group by item.type order by item.type ");
6.sxtoa项目总结
(1)项目中大量应用到请求转发和重定向,再次简述请求转发和重定向的区别。
1、请求次数:重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;
2、地址栏不同:重定向地址栏会发生变化,转发地址栏不会发生变化;
3、是否共享数据:重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);
4、跳转限制:重定向可以跳转到任意URL,转发只能跳转本站点资源;
5、发生行为不同:重定向是客户端行为,转发是服务器端行为;
(2)简述MVC分层模式,并简述一下分层开发的优点。
视图层(view)
代表用户交互界面,对于web应用来说,可以概括为html,jsp界面,有可能为XHTML、XML、Apple。
模型层
业务流程\状态处理以及业务规则的制定。模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心。
业务模型还有一个很重要的模型那就是数据模型。数据模型主要指实体对象的数据保存(持续化)。比如将一张订单保持到数据库,从数据库获取订单。我们可以将这个模型单独列出,所有有关数据库的操作只限制在该模型中。
控制层
可以理解为从用户接受请求,将模型与视图配在一起,共同完成用户请求。
(3)总结JSP的四个作用域。
Request,session,page,application
(4)简述 ajax异步请求的步骤
创建ajax对象
绑定监听事件
创建请求
发送请求
(5)概述我们在项目中用到过哪些插件?
Poi导出,Echarts插件,富文本编辑器,日历插件
(6)项目整个做下来,最直观的感受是什么?
了解了mvc模式 的工作流程,以及他们之间的调用,还有就是他们各自分工,职责,曾经接触java,一点也不懂,对于他们之间的调用关系都是迷糊的,特别是在学se知识的时候,那真的就是守,步骤或者代码都和老师一样的,许多时候是不明白为啥要这样写的。只能先跟着敲,现在学完,对于一个web项目几乎是了解了,而且也能自己写了
(7)在做项目中经常伴随着各种各样的错误,对于程序出错,你有哪些收获?
程序出错,真的是经常的事,虽然想着自己严谨一些,任何代码的编写以及流程都做到小心仔细,争取做到无任何错误就能直接实现,但有时候还是无法避免,但现在自己学会了修改bug,也是觉得有些长进,许多bug自己都是可以找出来的,现在真正需要问老师的一般都不是代码的错误,而是说不出来的bug。最重要的是百度用的也不错。
7.分页意义和实现思路
(1)为什么需要分页?分页跟增删改查中的哪个操作有关系?
对于数据量大的时候,我们很难让所有数据一页显示完,而且也不太好,提高访问速度,降低宽带使用,所以就出现了分页,主要是查询有关系
(2)简述分页的实现思路
控制层:获取当前页,将当前页号给pagebean,传递pagebean到业务层,业务层:获取记录总数,使用记录总数计算pagebean其他属性值,调用数据访问层获取当前页数据并给pagebean,
数据访问层:分页查询
8.理解PageBean
(1)PageBean中有哪些属性?作用是什么?
Size:每页几条数据,可以有默认值5
当前页号index:可以有默认值
记录总数totalcount:没有默认值,需要查询数据库获取真正的记录总数
一共多少页:totalPageCount=totalCount/size+1
上一页:index-1
下一页:index+1
9.基本分页的后台操作
(1)基本分页的后台操作控制层如何处理,业务层如何处理,数据访问层如何处理?
控制层:获取当前页,将当前页号给pagebean,传递pagebean到业务层,业务层:获取记录总数,使用记录总数计算pagebean其他属性值,调用数据访问层获取当前页数据并给pagebean,
数据访问层:分页查询
10.基本分页的前台操作
(1)基本分页的前台操作,如何处理?贴出代码,并解释代码的含义
<tr>
<td colspan="11" align="center">
<a href="javascript:change(1,${ pagebean.size})">首页</a>
<c:if test="${pagebean.index!=1 }">//判断是否是第一页
<a href="javascript:change(${pagebean.index-1},${ pagebean.size})">上一页</a>
</c:if>
<c:if test="${pagebean.index==1 }">
上一页
</c:if>
<c:forEach items="${pagebean.numbers }" var="num">
<c:if test="${num==pagebean.index }">
[<a href="javascript:change(${num},${ pagebean.size})">${num}</a>]
</c:if>
<c:if test="${num!=pagebean.index }">
<a href="javascript:change(${num},${ pagebean.size})">${num}</a>
</c:if>
</c:forEach>
<c:if test="${pagebean.index!=pagebean.totalPageCount }">
<a href="javascript:change(${pagebean.index+1},${ pagebean.size})">下一页</a>
</c:if>
<c:if test="${pagebean.index==pagebean.totalPageCount }">
下一页
</c:if>
<a href="javascript:change(${pagebean.totalPageCount},${ pagebean.size})">末页</a>
每页
<select onchange="javascript:change(${pagebean.index},this.value)">
<c:forEach begin="5" end="25" step="5" var="i">
<c:if test="${i==pagebean.size }">
<option value="${i }" selected="selected">${i }</option>
</c:if>
<c:if test="${i!=pagebean.size }">
<option value="${i }">${i }</option>
</c:if>
</c:forEach>
</select>
条记录
直接跳到第
<select onchange="change(this.value,${ pagebean.size})">
<c:forEach items="${pagebean.numbers }" var="num">
<c:if test="${pagebean.index==num }">
<option value="${num }" selected="selected">${num}</option>
</c:if>
<c:if test="${pagebean.index!=num }">
<option value="${num }" >${num}</option>
</c:if>
</c:forEach>
</select>
页
共${pagebean.totalCount}条记录
</td>
</tr>
11.基本分页的完善
(1)本节课完善了分页的那些功能?是如何实现的,贴出前端代码,后端代码,并写出注释
<script type="text/javascript">
function changeIndex(val) {
location.href="servlet/ShowAllServlet?index="+val;
}
function changeSize(val) {
location.href="servlet/ShowAllServlet?size="+val;
}
function change(val,size) {
/* document.forms[0].action="servlet/ShowAllServlet?index="+val+"&size="+size; */
document.forms[0].index.value=val;
document.forms[0].size.value=size;
document.forms[0].submit();
}
</script>
<body>
<hr>
<hr>
<!-- 显示所有学生 /stumanager/ -->
<table align="center" border="1" width="60%">
<tr>
<th>学生 编号</th>
<th>学生姓名</th>
<th>学生年龄</th>
<th>学生成绩</th>
<th>vs.index</th>
<th>更新操作</th>
<th>删除操作</th>
</tr>
<c:forEach items="${pagebean.list}" var="stu" varStatus="vs">
<tr>
<td>${stu.id }</td>
<td>${stu.name }</td>
<td>${stu.age }</td>
<td>${stu.score }</td>
<td>${vs.index }</td>
<td><a href="/stumanager/servlet/StudentServlet?operate=preupdate&sid=${stu.id}">更新</a></td>
<td><a href="/stumanager/servlet/StudentServlet?operate=delete&sid=${stu.id}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="11" align="center">
<a href="javascript:change(1,${ pagebean.size})">首页</a>
<c:if test="${pagebean.index!=1 }">
<a href="javascript:change(${pagebean.index-1},${ pagebean.size})">上一页</a>
</c:if>
<c:if test="${pagebean.index==1 }">
上一页
</c:if>
<c:forEach items="${pagebean.numbers }" var="num">
<c:if test="${num==pagebean.index }">
[<a href="javascript:change(${num},${ pagebean.size})">${num}</a>]
</c:if>
<c:if test="${num!=pagebean.index }">
<a href="javascript:change(${num},${ pagebean.size})">${num}</a>
</c:if>
</c:forEach>
<c:if test="${pagebean.index!=pagebean.totalPageCount }">
<a href="javascript:change(${pagebean.index+1},${ pagebean.size})">下一页</a>
</c:if>
<c:if test="${pagebean.index==pagebean.totalPageCount }">
下一页
</c:if>
<a href="javascript:change(${pagebean.totalPageCount},${ pagebean.size})">末页</a>
每页
<select onchange="javascript:change(${pagebean.index},this.value)">
<c:forEach begin="5" end="25" step="5" var="i">
<c:if test="${i==pagebean.size }">
<option value="${i }" selected="selected">${i }</option>
</c:if>
<c:if test="${i!=pagebean.size }">
<option value="${i }">${i }</option>
</c:if>
</c:forEach>
</select>
条记录
直接跳到第
<select onchange="change(this.value,${ pagebean.size})">
<c:forEach items="${pagebean.numbers }" var="num">
<c:if test="${pagebean.index==num }">
<option value="${num }" selected="selected">${num}</option>
</c:if>
<c:if test="${pagebean.index!=num }">
<option value="${num }" >${num}</option>
</c:if>
</c:forEach>
</select>
页
共${pagebean.totalCount}条记录
</td>
</tr>
</table>
</body>
public class ShowAllServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置编码格式
request.setCharacterEncoding("utf-8");
//接收数据
String sindex=request.getParameter("index");
int index=1;
try {
index=Integer.parseInt(sindex);
} catch (NumberFormatException e) {
e.printStackTrace();
}
String ssize=request.getParameter("size");
int size=5;
try {
size=Integer.parseInt(ssize);
} catch (NumberFormatException e) {
e.printStackTrace();
}
//接收姓名信息
String name=request.getParameter("name");
System.out.println(name);
//接收分数数据
String sminScore=request.getParameter("minScore");
if(sminScore==null){
sminScore="";
}
double minScore=0;
try {
minScore=Double.parseDouble(sminScore);
} catch (NumberFormatException e) {
e.printStackTrace();
}
request.setAttribute("name", name);
request.setAttribute("minScore", sminScore);
//2
PageBean<Student> pagebean=new PageBean<Student>();
pagebean.setIndex(index);
pagebean.setSize(size);
StudentService stuBiz = new StudentServiceImpl();
stuBiz.findByIndex(pagebean,name,minScore);
request.setAttribute("pagebean",pagebean);//!!!!!!!
//3com.bjsxt
request.getRequestDispatcher("/jsp/showAll.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
public class StudentServiceImpl implements StudentService {
private StudentDao stuDao = new StudentDaoImpl();
public List<Student> findAll() {
return this.stuDao.findAll();
}
public void findByIndex(PageBean<Student> pagebean) {
//获取数据库的总数
int totalCount=this.stuDao.findAll().size();
pagebean.setTotalCount(totalCount);
int start=pagebean.getStartRow();
int end =pagebean.getEndRow();
List<Student> list=stuDao.selStu(start,end);
pagebean.setList(list);
}
}
public class StudentDaoImpl implements StudentDao {
public List<Student> findAll() {
//声明变量
Connection conn =DBUtil.getConnection();
Statement stmt =null;
ResultSet rs =null;
List <Student> stuList = new ArrayList<Student>();
try {
stmt =conn.createStatement();
rs = stmt.executeQuery("select * from student");
while(rs.next()){
//封装对象
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
stu.setScore(rs.getDouble("score"));
stuList.add(stu);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return stuList;
}
public List<Student> selStu(int start, int end) {
Connection conn =DBUtil.getConnection();
Statement stmt =null;
ResultSet rs =null;
List <Student> stuList = new ArrayList<Student>();
try {
stmt =conn.createStatement();
String sql = "select * from (select rownum rn,stu2.* "
+ "from (select stu.* from student stu order by score desc ) stu2 "
+ "where rownum <="+end+" ) "
+ "where rn >"+start;
rs = stmt.executeQuery(sql);
while(rs.next()){
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
stu.setScore(rs.getDouble("score"));
stuList.add(stu);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return stuList;
}
public int findCount(String name, double minScore) {
Connection conn =DBUtil.getConnection();
PreparedStatement stmt =null;
ResultSet rs =null;
int count=0;
try {
StringBuilder sql=new StringBuilder("select count(*) from student where 1=1");
if (name!=null&&!"".equals(name)) {
sql.append("and name like '%"+name+"%'");
}
if (minScore>0) {
sql.append("and score>="+minScore);
}
stmt =conn.prepareStatement(sql.toString());
rs=stmt.executeQuery();
rs.next();
count=rs.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return count;
}
12.带查询条件的分页
(1)带查询条件的分页跟不带查询条件的分页有什么区别?
待查询条件的相当于筛选,而不带查询条件返回结果是全部
(2)贴出带查询条件分页的前端代码,后端代码,并写出注释
public List<Student> selStu(int start, int end, String name, double minScore) {
Connection conn =DBUtil.getConnection();
Statement stmt =null;
ResultSet rs =null;
List <Student> stuList = new ArrayList<Student>();
try {
stmt =conn.createStatement();
StringBuilder sql=new StringBuilder("select stu.* from student stu where 1=1");
if (name!=null&&!"".equals(name)) {
sql.append("and name like '%"+name+"%'");
}
if (minScore>0) {
sql.append("and score>="+minScore);
}
sql.append("order by score desc");
String sql2 = "select * from (select rownum rn,stu2.* "
+ "from ("+sql.toString()+" ) stu2 "
+ "where rownum <="+end+" ) "
+ "where rn >"+start;
rs = stmt.executeQuery(sql2);
while(rs.next()){
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
stu.setScore(rs.getDouble("score"));
stuList.add(stu);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return stuList;
}
}
public void findByIndex(PageBean<Student> pagebean, String name,
double minScore) {
//获取数据库的总数
int totalCount=this.stuDao.findCount(name,minScore);
System.out.println(totalCount);
pagebean.setTotalCount(totalCount);
int start=pagebean.getStartRow();
int end =pagebean.getEndRow();
List<Student> list=stuDao.selStu(start,end,name,minScore);
pagebean.setList(list);
}
<form action="servlet/ShowAllServlet" method="post" id="form1">
<table align="center">
<tr>
<td>姓名</td>
<td>
<input type="text" name="name" value="${name }" id="name">
<input type="hidden" name="index" value="">
<input type="hidden" id="size" name="size">
</td>
<td>分数>=</td>
<td><input type="text" name="minScore" value="${minScore }" id="score"></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
13.完善带查询条件的分页
(1)完善了哪些功能?简述完善的思路.
完善了呆查询条件的实现,当提交当前页数,并提交表单数据。
function change(val,size) {
/* document.forms[0].action="servlet/ShowAllServlet?index="+val+"&size="+size; */
document.forms[0].index.value=val;
document.forms[0].size.value=size;
document.forms[0].submit();
}
现在form表单中添加隐藏域,里面添加上我们index和size数据,然后再提交表单