OA系统之分页查询

  1. 使用Echarts柱状图显示收入统计信息-业务层和DAO层
    (1) 后台如何拼接对应的json字符串?
    StringBuilder typeArr=new StringBuilder("[");
    StringBuilder amountArr=new StringBuilder("[");
    List list=incomeDao.selInCome();
    //[[‘Mon’, ‘Tue’, ‘Wed’, ‘Thu’, ‘Fri’, ‘Sat’, ‘Sun’],[120, 200, 150, 80, 70, 110, 130]]
    for (Object[] obj : list) {
    typeArr.append("""+obj[0]+"",");
    amountArr.append(obj[1]+",");
    }
    String jsonStr="["+typeArr.substring(0,typeArr.length()-1)+"],"+amountArr。substring(0, amountArr.length()-1)+"]]";

  2. 收支管理-财务添加支出
    (1) 当前审批人假如是财务,那么要进行什么操作,简述逻辑。
    需要向支出表写入支出信息,调用dao层对象,想支出表插入数据。

    (2) 截止到这里,审批报销单功能彻底完成,再次概述整个审批逻辑。
    首先判断审核是否通过,拒绝或打回,则添加审核记录,修改报销单的状态,通过则判断是否是财务,是财务则添加支出信息,修改报销单状态,不是财务则判断报销金额是否大于2500,小于2500则添加审核记录,修改报销单状态,交给财务审核,金额大于2500,则判断当前审核人是否为总裁,是总裁则添加审核记录,修改报销单状态,交给财务审核,不是总裁,则则添加审核记录,修改报销单状态,交给总裁审核。

  3. 收支管理-查看支出
    (1) 到这里,对于查看收支功能实现应该是不陌生了,重点就是查询收支的sql,请问这个sql怎么编写呢?

String sql="select * from (select rownum r,d.* from (\r\n" +
"select *\r\n" +
"from income ic\r\n" +
"join employee emp on emp.empid=ic.userid where ";
for (String key : map.keySet()) {
if(!map.get(key).equals("null")) {
if(key.equals("beginTime")) {
sql+=" icdate >= to_date('"+map.get(key)+"','yyyy-mm-dd') and ";
continue;
}else if(key.equals("endTime")) {
sql+=" icdate <= to_date('"+map.get(key)+"','yyyy-mm-dd') and ";
continue;
}else if(key.equals("icType")) {
sql+=" ictype='"+map.get(key)+"' and ";
continue;
}
}
}
sql+="1=1 order by ic.icid desc) d where rownum<=?) where r>?";
  1. 收支管理-使用饼图显示支出
    (1) 如何使用Echarts完成饼图展示?

    1. 引入echarts的js文件。
    2. 创建一个具有高宽的div作为echarts容器
    3. 基于容器初始化echarts
    4. 指定图表的配置项和数据,设置图标为饼图
    5. 使用配置项和数据显示图表

    (2) 如何将后台查出来的集合转换成为json字符串?
    使用StringBuffer将字符字符串拼接成符合规范的json字符串。

    public String showOut(int i) {
    		String[] type= {"通信费用","办公室耗材","住宿费用","房租水电","其他"};//1  通信费用    2  办公室耗材   3   住宿费用    4   房租水电     5   其他
    	PaymentDao paymentDao=new PaymentDaoImpl();
    	StringBuilder typeArr=new StringBuilder("[");
    	StringBuilder Arr=new StringBuilder("[");
    	List<Object[]> list=paymentDao.selPayment(i);
    	System.out.println(list);
    	//[['通信费用','办公室耗材','住宿费用','房租水电','其他'],
    //    [{value:335, name:'通信费用'},{value:310, name:'办公室耗材'},{value:234, name:'住宿费用'},{value:135, name:'房租水电'},{value:1548, name:'其他'}]
    //]
    	for (Object[] obj : list) {
    		typeArr.append("\""+type[Integer.parseInt((String) obj[0])-1]+"\",");
    		Arr.append("{value:"+obj[1]+",name:\""+type[Integer.parseInt((String) obj[0])-1]+"\"},");
    	}
    	String jsonStr="["+typeArr.substring(0, typeArr.length()-1)+"],"+Arr.substring(0, Arr.length()-1)+"]]";
    	//System.out.println(jsonStr);
    	return jsonStr;
    }
    
  2. 收支管理-使用饼图显示指定时间段的支出
    (1) 如何在代码中加入逻辑:显示指定时间段的支出。
    使用下拉框显示不同时间段,添加change事件,当触发事件时向后台发送ajax请求,请求该时间段内的支出数据,并拼接成规定格式的json字符串。再次初始化饼图。显示不同时间段的数据。

  3. sxtoa项目总结
    (1) 项目中大量应用到请求转发和重定向,再次简述请求转发和重定向的区别。
    重定向:服务器向浏览器响应,要求浏览器访问另一个页面,地址栏会变。
    请求转发,在服务器内部,请求被转发到另一个servlet,最后返回给浏览器,浏览器不知道请求被转发,地址栏不变。

    (2) 简述MVC分层模式,并简述一下分层开发的优点

    1. 松耦合
    2. 高内聚
    3. 便于开发
    4. 便于测试

    (3) 总结JSP的四个作用域。

    1. Page 只在当前页面起作用。
    2. Request 在当前请求被起作用 ,用于解决不同servlet的数据流转问题
    3. Session 在当前会话内起作用,解决不同请求的数据流转问题
    4. applicationContext 在整个项目中都起作用。

    (4) 简述 ajax异步请求的步骤

    1. 创建ajax对象
    2. 创建监听器,设置回调函数
    3. 创建请求,设置为异步请求
    4. 发送请求。

    (5) 概述我们在项目中用到过哪些插件?
    富文本编辑器、日历插件、echarts图表插件

    (6) 项目整个做下来,最直观的感受是什么?
    一个完整的项目所涉及的知识点非常全,很容易发现自身的薄弱点,我们需要在自身薄弱的地方多下功夫,补漏补差。

    (7) 在做项目中经常伴随着各种各样的错误,对于程序出错,你有哪些收获?
    学会了debug调试,使用输出语句输出关键信息。

  4. 分页意义和实现思路
    (1) 为什么需要分页?分页跟增删改查中的哪个操作有关系?
    分页可以有效提高界面的交互性,有大量数据时,一个页面不便显示全部数据,进行分页符合人民的日常习惯,便于交互。
    和查操作有关。

    (2) 简述分页的实现思路
    查询数据时使用limit子句设置查询数据的条数,将查询到的有限的数据封装成一个既带有页数信息(总页数,当前页数等)有带有数据的对象,将该对象发送到浏览器,实现数据的分页显示。

  5. 理解PageBean
    (1) PageBean中有哪些属性?作用是什么?
    int size = 5; //每页显示记录
    int index = 1; // 当前页号
    int totalCount = 0; // 记录总数
    int totalPageCount = 1; // 总页数
    int[] numbers; //展示页数集合
    List list; //要显示到页面的数据集

  6. 基本分页的后台操作
    (1) 基本分页的后台操作控制层如何处理,业务层如何处理,数据访问层如何处理?
    控制层:
    接受查询数据的请求,接收参数,调用服务层对象获取查询结果,将查询结果转换为json字符串发送给浏览器
    控制层:
    根据需要查询的页码和每页的数据量调用dao层查询数据、数据总条数,封装成PageBean对象,返回给控制层
    Dao层:
    查询查询结果的所有数据量和查询结果

  7. 基本分页的前台操作
    (1) 基本分页的前台操作,如何处理?贴出代码,并解释代码的含义

<script type="text/javascript">
			/* page存储当前页 */
			var page;
			$(document).ready(function(){
				getData(1);
				getDept();
				$("#sel").on("click",function(){
					getData(1);
				});
				$("#export").on("click",function(){
				var url="duty?method=export&data="+$("#form").serialize();
					window.location.href=url;
				});
			});
			/*获取部门信息,向查询条件列表插入数据*/
			function getDept(){
				$.get("dept",{method:"deptList"},function(data){
					eval("var dept="+data);
					var str=null;
					for(var i in dept){
						str+="+dept[i].deptName+"";
					}
					$("#deptList").append(str);
				});
			}
			/*  发送ajax获取查询数据
				参数为需要获取的页数
			*/
			function getData(pageindex){
				$.get("duty",{method:"dutyList",page:pageindex,data:$("#form").serialize()},function(data){
					eval("page="+data);
					
					$("#tbody").empty();
					var str;/*存放查询结果的html代码*/
					for(var i in page.list){
						str+=""+
						""+page.list[i].emp.empid+""+
						""+page.list[i].emp.realname+""+
						""+page.list[i].emp.dept.deptName+""+
						""+page.list[i].dtDate+""+
						""+page.list[i].signinTime+""+
						""+page.list[i].signoutTime+"";
					}
					$("#tbody").append(str);/*将查询结果的html代码追加到对于的div*/
					
					$("#num").text(page.totalCount);
					$("#page").text(page.Index);
					
					$("#pageList").empty();
					var str="
  • "
    ; for(var i in page.numbers){ str+="
  • "+page.numbers[i]+"
  • "
    ; } str+=""; $("#pageList").append(str); $("#page").text(page.index); $("#"+page.index).addClass("current"); $("#"+page.index).attr("href","javascript:return false;"); }); }; /*前一页*/ function pre(){ if(page.index!=1){ getData(page.index-1); } } /*后一页*/ function next(){ if(page.index!=page.totalPageCount){ getData(page.index+1); } } </script>
    1. 基本分页的完善
      (1) 本节课完善了分页的那些功能?是如何实现的,贴出前端代码,后端代码,并写出注释
    
    <html>
      <head>
         <base href="<%=basePath%>"> 
        
        <title>查询并显示所有学生信息title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	
    	
    	<script type="text/javascript">
    		function changeIndex(index){
    			window.location.href="servlet/ShowAllServlet?index="+index;
    		}
    		
    		function changeSize(size){
    			//alert(size);
    			window.location.href="servlet/ShowAllServlet?size="+size;
    		}
    		
    		function change(index,size){
    			window.location.href="servlet/ShowAllServlet?index="+index+"&size="+size;
    		}
    	script>
      head>
      
      <body> 
        
        <table align="center" border="1" width="60%">
        	<tr>
        		<th>学生 编号th>
        		<th>学生姓名th>
        		<th>学生年龄th>
        		<th>学生成绩th>
        		<th>vs.indexth>
        		<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="7" align="center">
        			<a href="servlet/ShowAllServlet?index=1&size=${pageBean.size }">首页a> 
        			
        			<c:if test="${pageBean.index !=1 }">
        				<a href="servlet/ShowAllServlet?index=${pageBean.index-1 }&size=${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="servlet/ShowAllServlet?index=${num }&size=${pageBean.size }">${num}a> ]
        			 	c:if>
        			 		<c:if test="${num !=pageBean.index }">
        			 		<a href="servlet/ShowAllServlet?index=${num }&size=${pageBean.size }">${num}a> 
        			 	c:if>
        			c:forEach>
        			 
        			 <c:if test="${pageBean.index !=pageBean.totalPageCount }">
        				<a href="servlet/ShowAllServlet?index=${pageBean.index+1 }&size=${pageBean.size }">下一页 a>  
        			c:if>
        			<c:if test="${pageBean.index ==pageBean.totalPageCount }">
        				下一页
        			c:if>
        			<a href="servlet/ShowAllServlet?index=${pageBean.totalPageCount}&size=${pageBean.size }">末页a> 	
        			
        			每页
        			<select  onchange="changeSize(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 begin="1" end="${pageBean.totalPageCount }" var="num">
        					<c:if test="${num ==pageBean.index }">
        						<option value="${num }" selected="selected">${num }option>
        					c:if>
        					<c:if test="${num !=pageBean.index }">
        						<option value="${num }" >${num }option>
        					c:if>
        				c:forEach>
        			select>
        			页  
        			
        			共${pageBean.totalCount}条记录
        		
        		td>
        	tr>
        	
        table>
       
      body>
    html>
    
    Servlet
    public class ShowAllServlet extends HttpServlet {
    
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		//response.setCharacterEncoding("text/html; charset=utf-8");	
    		request.setCharacterEncoding("utf-8");
    		//1.1、接收视图层传来的当前页码(处理在空值情况)
    		String sindex=request.getParameter("index");
    		int index=1;//如果index为空值  默认页数为1
    		try {
    			index=Integer.parseInt(sindex);
    		} catch (NumberFormatException e) {
    			e.printStackTrace();
    		}
    		//1.2、接收视图层显示的每页显示的记录数
    		String sszie=request.getParameter("size");
    		int size=5;
    		try {
    			size=Integer.parseInt(sszie);
    		} catch (NumberFormatException e) {
    			e.printStackTrace();
    		}
    		//1.3 接收视图层的姓名信息
    		String name= request.getParameter("name");
    		
    		//1.4 接收视图层的分数信息
    		String sminScore =request.getParameter("minScore");
    		double minScore=0;
    		if (sminScore ==null) {//java.lang.NullPointerException的解决
    			sminScore="";
    		}
    		
    		try {
    			minScore =Double.parseDouble(sminScore);
    		} catch (NumberFormatException e) {
    			
    			e.printStackTrace();
    		}
    		
    		//2、给工具类赋值当前页数 
    		PageBean<Student> pageBean = new PageBean<Student>();
    		pageBean.setIndex(index);
    		
    		pageBean.setSize(size);
    		
    		  StudentService stu = new StudentServiceImpl();
    		  //List  stuList =stuBiz.findAll();	
    		  //stu.findStu(pageBean);
    		  stu.findStu(pageBean,name,minScore);
    		  
    		 request.setAttribute("pageBean",pageBean);//!!!!!!!
    		 request.setAttribute("name", name);
    		 request.setAttribute("minScore", minScore);
    		 
    		//3 
    		request.getRequestDispatcher("/jsp/showAll.jsp").forward(request, response); 
    	}
    
    	
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		this.doGet(request, response);
    	}
    
    }
    ServiceImpl
    public class StudentServiceImpl implements StudentService {
    
    	private StudentDao stuDao = new StudentDaoImpl();	
    
    	public List<Student> findAll() {		
    		return this.stuDao.findAll();
    	}
    
    	public void findStu(PageBean<Student> pageBean) {
    		//1、获取数据库记录中的总数
    		//int totalCount=stuDao.findAll().size();//效率低下,因为会先查数据再改条数
    		int totalCount=stuDao.findtotalCount();
    		//System.out.println("totalCount:"+totalCount);
    		
    		//2、使用记录计算pagebean中的其他属性(totalCount,totalPageCount,numbers),还剩list属性
    		pageBean.setTotalCount(totalCount);
    		
    		//3、调用到层来获取指定页的学生数据,并放入pagebeande 的list属性
    		int start=pageBean.getStartRow();
    		int end=pageBean.getEndRow();
    		List<Student> stuList=stuDao.findStu(start,end);
    		pageBean.setList(stuList);
    		
    		
    	}
    
    	public void findStu(PageBean<Student> pageBean, String name, double minScore) {
    		//1、获取数据库记录中的总数	
    				int totalCount=stuDao.findtotalCount(name,minScore);
    				System.out.println("totalCount:"+totalCount);
    				
    				//2、使用记录计算pagebean中的其他属性(totalCount,totalPageCount,numbers),还剩list属性
    				pageBean.setTotalCount(totalCount);
    				
    				//3、调用到层来获取指定页的学生数据,并放入pagebeande 的list属性
    				int start=pageBean.getStartRow();
    				int end=pageBean.getEndRow();
    				//List stuList=stuDao.findStu(start,end);
    				List<Student> stuList=stuDao.findStu(start,end,name,minScore);
    				pageBean.setList(stuList);
    		
    	}
    
    }
    DaoImpl
    public class StudentDaoImpl   implements StudentDao {
    	public int findtotalCount() {
    		Connection conn =DBUtil.getConnection();
    		Statement stmt =null;
    		ResultSet rs =null;
    		int totalCount=0;
    		try {
    			stmt =conn.createStatement();
    			rs = stmt.executeQuery("select count(*) from student");
    			
    			rs.next();
    			totalCount=rs.getInt(1);
    			
    		} catch (SQLException e) {
    			
    			e.printStackTrace();
    		}finally{
    			DBUtil.closeAll(rs, stmt, conn);
    		}
    		return totalCount;
    	}
    	
    	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> findStu(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;
    	}
    
    1. 带查询条件的分页
      (1) 带查询条件的分页跟不带查询条件的分页有什么区别?
      区别:条件查询分页需要拼接sql语句,不带条件的不需要

      (2) 贴出带查询条件分页的前端代码,后端代码,并写出注释
      Jsp页面

      
      
      <html>
        <head>
       <base href="<%=basePath%>"> 
      
      <title>查询并显示所有学生信息title>
      
      <meta http-equiv="pragma" content="no-cache">
      <meta http-equiv="cache-control" content="no-cache">
      <meta http-equiv="expires" content="0">    
      <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
      <meta http-equiv="description" content="This is my page">
      
      
      <script type="text/javascript">
      	function changeIndex(index){
      		window.location.href="servlet/ShowAllServlet?index="+index;
      	}
      	
      	function changeSize(size){
      		//alert(size);
      		window.location.href="servlet/ShowAllServlet?size="+size;
      	}
      	
      	function change(index,size){
      		//window.location.href="servlet/ShowAllServlet?index="+index+"&size="+size;
      	/* 如何让 点击页码提交超链接的同时提交表单呢?forms[0]:代表第一个form表单 */
      	document.forms[0].action="servlet/ShowAllServlet?index="+index+"&size="+size;
      	document.forms[0].submit();
      	}
      script>
      

    姓名 分数>=

    
    
    		
    学生 编号 学生姓名 学生年龄 学生成绩 vs.index 更新操作 删除操作
    ${stu.id } ${stu.name } ${stu.age } ${stu.score } ${vs.index } 更新 删除
    首页 上一页 上一页 [${num} ] ${num} 下一页 下一页 末页 每页 条记录 直接跳转到 页 共${pageBean.totalCount}条记录
    ```
    1. 完善带查询条件的分页

    (1) 完善了哪些功能?简述完善的思路.
    提交表单后并传入当前页号
    删除后仍跳转到当前页,而不是第一页
    选择每页几条记录变更后,没有机组当前页号
    思路:
    在提交相关变更时,传入当前页号和每页显示几条记录的信息

    分享/讲解/扩展思考
    点名提问从第一节课到最后一节课分别学到了什么,直到同学们把所有的知识点都说出来并且保证无误。

    你可能感兴趣的:(j2ee)