1.使用Echarts柱状图显示收入统计信息-业务层和DAO层
(1)后台如何拼接对应的json字符串?
@Override
public String getBarData() {
//调用dao层获取收入数据(list)
IncomeDao icDao = new IncomeDaoImpl();
List<Object []> list = icDao.findStaticData();
//将list集合转成jsonStr
StringBuilder icTypeArr = new StringBuilder("["); //['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
StringBuilder amountArr = new StringBuilder("["); //[120, 200, 150, 80, 70, 110, 130]
for(int i=0;i<list.size();i++){
Object [] arr = list.get(i); //{项目开发,400}
if(i<list.size()-1){
icTypeArr.append("\""+arr[0]+"\",");
amountArr.append(arr[1]+",");
}else{
icTypeArr.append("\""+arr[0]+"\"]");
amountArr.append(arr[1]+"]");
}
}
//"[['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],[120, 200, 150, 80, 70, 110, 130]]";
String jsonStr = "["+icTypeArr.toString()+","+amountArr.toString()+"]";
//返回jsonStr
return jsonStr;
}
2.收支管理-财务添加支出
(1)当前审批人假如是财务,那么要进行什么操作,简述逻辑。
如果当前审批人是财务,要在支出表中添加支出记录以及在报销单表中修改报销单状态。
(2)截止到这里,审批报销单功能彻底完成,再次概述整个审批逻辑。
首先进行判断审核是否通过,如果审核没有通过则进行打回或者拒绝;如果审核通过,判断审批人是否是财务,如果是财务,则在支出表中添加支出记录以及修改报销单状态,如果不是财务,则判断报销金额是否较大,如果金额较小,则当前报销人的直接领导进行审批,审批之后添加审核记录以及修改报销单状态,然后交给下一审批人财务进行打款;如果金额较大,先进行判断当前审批人是否是总裁,如果是总裁,则添加审核记录及修改报销单状态,然后将此报销单交给财务进行审核及打款。如果不是总裁,则当前审核人审核之后再转交给当前审核人的上级领导,直至交到总裁那里进行审核,总裁审核之后交给财务进行打款。
3.收支管理-查看支出
(1)到这里,对于查看收支功能实现应该是不陌生了,重点就是查询收支的sql,请问这个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 to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getNowMonthBeginTime()+"'");
}else if(type ==2){
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getNowYearBeginTime()+"'");
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')<='"+DateUtil.getNowYearEndTime()+"'");
}else if(type ==3){
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getLastYearBeginTime()+"'");
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')<='"+DateUtil.getLastYearEndTime()+"'");
}
sql.append(" group by item.type");
sql.append(" order by item.type");
4.收支管理-使用饼图显示支出
(1)如何使用Echarts完成饼图展示?
使用ajax将当前选择的时间传入servlet中,在servlet中进行接收,然后调用service层,在service层进行业务处理,service层调用dao层,在dao层中进行数据库的交互,查询得到的是list集合,将集合返回给service层,在service层将list集合转成json字符串返回给servlet,在servlet中将结果返回给jsp页面,然后在jsp页面中将json字符串转成数组,然后使用Echarts插件将数组转成饼图进行展现出来。
(2)如何将后台查出来的集合转换成为json字符串?
@Override
public String getPieData(int type) {
//调用dao层获取收入数据(list)
PaymentDao pmDao = new PaymentDaoImpl();
List<Object []> list = pmDao.findStaticData(type);
//将list集合转成jsonStr
/*"[{value:335, name:'直接访问'},"
+ "{value:310, name:'邮件营销'},"
+ "{value:234, name:'联盟广告'},"
+ "{value:135, name:'视频广告'},"
+ "{value:1548, name:'搜索引擎'}"
+ "]"*/
StringBuilder jsonStr = new StringBuilder("[");
for(int i=0;i<list.size();i++){
Object [] arr = list.get(i);
jsonStr.append("{\"value\":"+arr[1]+",");
jsonStr.append("\"name\":"+"\""+arr[0]+"\"");
if(i<list.size()-1){
jsonStr.append("},");
}else{
jsonStr.append("}");
}
}
jsonStr.append("]");
//返回jsonStr
return jsonStr.toString();
}
5.收支管理-使用饼图显示指定时间段的支出
(1)如何在代码中加入逻辑:显示指定时间段的支出。
首先将指定时间的工具类导入项目中,然后将string类型的SQL语句转成StringBuilder型,在SQL语句后面使用append方法进行拼接,在需要指定时间的地方直接调用工具类即可。
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 to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getNowMonthBeginTime()+"'");
}else if(type ==2){
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getNowYearBeginTime()+"'");
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')<='"+DateUtil.getNowYearEndTime()+"'");
}else if(type ==3){
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')>'"+DateUtil.getLastYearBeginTime()+"'");
sql.append(" and to_char(paytime,'yyyy-MM-dd hh:mi:ss')<='"+DateUtil.getLastYearEndTime()+"'");
}
sql.append(" group by item.type");
sql.append(" order by item.type");
6.sxtoa项目总结
(1)项目中大量应用到请求转发和重定向,再次简述请求转发和重定向的区别。
request.getRequestDispatcher()是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;服务器内部转发,整个过程处于同一个请求当中。
response.sendRedirect()则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。不在同一个请求。重定向,实际上客户端会向服务器端发送两个请求。
转发中数据的存取可以用request作用域:request.setAttribute(), request.getAttribute(),重定向是取不到request中的数据的。只能用session。
forward()更加高效,在可以满足需要时,尽量使用RequestDispatcher.forward()方法。
RequestDispatcher是通过调用HttpServletRequest对象的getRequestDispatcher()方法得到的,是属于请求对象的方法。
sendRedirect()是HttpServletResponse对象的方法,即响应对象的方法,既然调用了响应对象的方法,那就表明整个请求过程已经结束了,服务器开始向客户端返回执行的结果。
重定向可以跨域访问,而转发是在web服务器内部进行的,不能跨域访问。
(2)简述MVC分层模式,并简述一下分层开发的优点。
优点:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义。
缺点:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
关于第一个缺点,可以通过系统的缓存机制来减小对性能的影响。第二个缺点,只能通过采用一些设计模式来得到改善。
(3)总结JSP的四个作用域。
application作用域 :
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。整个应用是指从应用启动,到应用结束。
Object getAttribute(String name) //从application中获取信息;
void setAttribute(String name,Object value) //向application作用域中设置信息。
session作用域:
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。
Object HttpSession.getAttribute(String name) //从session中获取信息。
void HttpSession.setAttribute(String name,Object value)//向session中保存信息。
HttpSessionHttpServletRequest.getSessio() //获取当前请求所在的session的对象。
session从浏览器发出第一个HTTP请求即可认为会话开始。但结束就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种方法判断:如果一定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为30分钟,但这个值也可以通过HttpSession的setMaxInactiveInterval()方法来设置:
void setMaxInactiveInterval(int interval)
如果想主动让会话结束,例如用户单击“注销”按钮的时候,可以使用 HttpSession 的 invalidate()方法,用于强制结束当前session:void invalidate()
Session删除的时间是:
- Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。
- 程序调用HttpSession.invalidate()
- 服务器关闭或服务停止
Request作用域:
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算。
请求转发:servlet. getRequestDispatcher(“new.jsp”).forward(req,resp);
pageContext作用域
page对象的作用范围仅限于用户请求的当前页面
request和pageContext的生命周期都是短暂的,它们之间的区别:一个request可以包含多个page页(include,forward及filter)。
(4)简述 ajax异步请求的步骤
1.第一步(得到XMLHttpRequest)
2.第二步(打开与服务器的连接)
xmlHttp.open():用来打开与服务器的连接,它需要三个参数:
请求方式:可以是GET或POST
请求的URL:指定服务器端资源
请求是否为异步:如果为true表示发送异步请求,否则同步请求!
xmlHttp.open(method, url, async);
3.第三步(发送请求)
xmlHttp.send(null):如果不给可能会造成部份浏览器无法发送!
参数:就是请求体内容!如果是GET请求,必须给出null。
4. 第四步
在xmlHttp对象的一个事件上注册监听器:onreadystatechange
xmlHttp对象一共有5个状态:
0状态:刚创建,还没有调用open()方法;
1状态:请求开始:调用了open()方法,但还没有调用send()方法
2状态:调用完了send()方法了;
3状态:服务器已经开始响应,但不表示响应结束了!
4状态:服务器响应结束!(通常我们只关心这个状态)
得到xmlHttp对象的状态:
var state = xmlHttp.readyState;//可能是0、1、2、3、4
得到服务器响应的状态码
var status = xmlHttp.status;//例如为200、404、500
得到服务器响应的内容
var content = xmlHttp.responseText;//得到服务器的响应的文本格式的内容
var content = xmlHttp.responseXML;//得到服务器的响应的xml响应的内容,它是Document对象
xmlHttp.onreadystatechange = function() {//xmlHttp的5种状态都会调用本方法
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//双重判断:判断是否为4状态,而且还要判断是否为200
// 获取服务器的响应内容
var text = xmlHttp.responseText;
}
};
(5)概述我们在项目中用到过哪些插件?
富文本编辑器插件、日期插件、Echarts插件;
jdbc连接工具类、验证码工具类、上传下载POI工具类以及指定日期工具类。
(6)项目整个做下来,最直观的感受是什么?
最最直观的感受就是受益良多,学到了很多新知识,同时巩固了以前学过的知识,将所学的知识灵活的运用起来。活学活用,不能太过于死板。遇到问题不能着急,在大脑中进行仔细的分析,找到突破点,慢慢修改。
(7)在做项目中经常伴随着各种各样的错误,对于程序出错,你有哪些收获?
首先学会如何去看懂bug,看懂bug之后才知道是哪里出现了问题,才可以准确的去寻找错误。
其次在编写代码之前要先把思路理清楚,理清思路之后再进行代码的编写,这样在编写代码的时候更加容易,思路更加清晰。
最后就是写代码的时候一定要细心。因为粗心大意导致的错误最难寻找。
7.分页意义和实现思路
(1)为什么需要分页?分页跟增删改查中的哪个操作有关系?
在正常的大型网站中,肯定会有很多的数据,如果在一页进行展示,看起来很不方便,而且给客户的感觉很不好。
分页和查询中的条件查询有关。
(2)简述分页的实现思路
使用条件查询将数据库中的数据查询出来之后,根据每页展示多少条数据,计算出共有多少页,然后将其存入jsp页面中,在jsp页面中进行浏览器端的展示。
8.理解PageBean
(1)PageBean中有哪些属性?作用是什么?
Size表示每页显示多少条记录
Index当前页号
totalCount记录总数
totalPageCount总页数
Numbers展示页数集合
List要展示到页面的数据集
9.基本分页的后台操作
(1)基本分页的后台操作控制层如何处理,业务层如何处理,数据访问层如何处理?
在控制层中接收从页面传过来的当前页码,然后将当前页码存放到PageBean中,然后调用业务层方法,将PageBean传入,最后将业务层返回来的数据传入到jsp页面中。
在业务层中 接收控制层传过来的数据,调用数据访问层获取记录总数,通过记录总数计算出PageBean中的其他属性;并且将开始记录数和结束记录数据传入到数据访问层,在数据访问层中将分页结果返回给业务层,最后将计算结果返回给控制层
在数据访问层中接收业务层中的数据,通过业务层传过来的数据查询数据库中的记录总数以及分页情况,然后将查询的结果返回给业务层。
10.基本分页的前台操作
(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){
location.href="show?index="+index;
}
function changeSize(size){
location.href="show?size="+size;
}
</script>
</head>
<body>
<!-- 显示所有学生 /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="${pb.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="/stu/show?operate=preupdate&sid=${stu.id}">更新</a></td>
<td><a href="/stu/show?operate=delete&sid=${stu.id}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="11" align="center">
<a href="show?index=1">首页</a>
<c:if test="${pb.index != 1 }">
<a href="show?index=${pb.index-1 }">上一页</a>
</c:if>
<c:if test="${pb.index == 1 }">
上一页
</c:if>
<c:forEach items="${pb.numbers }" var="num">
<c:if test="${num == pb.index }">
[<a href="show?index=${num }">${num }</a>]
</c:if>
<c:if test="${num != pb.index }">
<a href="show?index=${num }">${num }</a>
</c:if>
</c:forEach>
<c:if test="${pb.index != pb.totalPageCount}">
<a href="show?index=${pb.index+1 }">下一页</a>
</c:if>
<c:if test="${pb.index == pb.totalPageCount}">
下一页
</c:if>
<a href="show?index=${pb.totalPageCount}">末页</a>
每页
<select onchange="changeSize(this.value)">
<c:forEach begin="5" end="20" step="5" var="i">
<c:if test="${i == pb.size }">
<option value="${i }" selected="selected">${i }</option>
</c:if>
<c:if test="${i != pb.size }">
<option value="${i }" >${i }</option>
</c:if>
</c:forEach>
</select>
条记录
直接跳转到
<select onchange="changeIndex(this.value)">
<c:forEach begin="1" end="${pb.totalPageCount}" var="num">
<c:if test="${num == pb.index }">
<option value="${num }" selected="selected">${num }</option>
</c:if>
<c:if test="${num != pb.index }">
<option value="${num }">${num }</option>
</c:if>
</c:forEach>
</select>
页
共${pb.totalCount }条记录
</td>
</tr>
</table>
</body>
</html>
11.基本分页的完善
(1)本节课完善了分页的那些功能?是如何实现的,贴出前端代码,后端代码,并写出注释
<body>
<!-- 显示所有学生 /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="${pb.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="/stu/show?operate=preupdate&sid=${stu.id}">更新</a></td>
<td><a href="/stu/show?operate=delete&sid=${stu.id}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="11" align="center">
<a href="show?index=1&size=${pb.size }">首页</a>
<c:if test="${pb.index != 1 }">
<a href="show?index=${pb.index-1 }&size=${pb.size }">上一页</a>
</c:if>
<c:if test="${pb.index == 1 }">
上一页
</c:if>
<c:forEach items="${pb.numbers }" var="num">
<c:if test="${num == pb.index }">
[<a href="show?index=${num }&size=${pb.size }">${num }</a>]
</c:if>
<c:if test="${num != pb.index }">
<a href="show?index=${num }&size=${pb.size }">${num }</a>
</c:if>
</c:forEach>
<c:if test="${pb.index != pb.totalPageCount}">
<a href="show?index=${pb.index+1 }&size=${pb.size }">下一页</a>
</c:if>
<c:if test="${pb.index == pb.totalPageCount}">
下一页
</c:if>
<a href="show?index=${pb.totalPageCount}&size=${pb.size }">末页</a>
每页
<select onchange="changeSize(this.value)">
<c:forEach begin="5" end="20" step="5" var="i">
<c:if test="${i == pb.size }">
<option value="${i }" selected="selected">${i }</option>
</c:if>
<c:if test="${i != pb.size }">
<option value="${i }" >${i }</option>
</c:if>
</c:forEach>
</select>
条记录
直接跳转到
<select onchange="change(this.value,${pb.size })">
<c:forEach begin="1" end="${pb.totalPageCount}" var="num">
<c:if test="${num == pb.index }">
<option value="${num }" selected="selected">${num }</option>
</c:if>
<c:if test="${num != pb.index }">
<option value="${num }">${num }</option>
</c:if>
</c:forEach>
</select>
页
共${pb.totalCount }条记录
</td>
</tr>
</table>
</body>
public class ShowAllServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//1.1接收从页面传入的当前页码index
String sindex = request.getParameter("index");
int index = 1; //默认当前页码是1
try {
index = Integer.parseInt(sindex);
} catch (Exception e) {
e.printStackTrace();
}
//1.2接收从页面传入的每页的记录数
String ssize = request.getParameter("size");
int size = 5;
try {
size = Integer.parseInt(ssize);
} catch (Exception e) {
e.printStackTrace();
}
PageBean<Student> pb = new PageBean<Student>();
pb.setIndex(index);
pb.setSize(size);
StudentService ss = new StudentServiceImpl();
ss.findstu(pb);;
request.setAttribute("pb",pb);//!!!!!!!
request.getRequestDispatcher("/jsp/showAll.jsp").forward(request, response);
}
}
public class StudentServiceImpl implements StudentService {
private StudentDao sd = new StudentDaoImpl();
public List<Student> findAll() {
return this.sd.findAll();
}
public void findstu(PageBean<Student> pb) {
//查询数据库表获取记录总数
//int totalCount = this.sd.findAll().size();
int totalCount = this.sd.findCount();
System.out.println("count="+totalCount);
//使用记录总数计算PageBean中的其他属性(totalCount,totalPageCount,numbers),就差list属性
pb.setTotalCount(totalCount);
//int start = (pb.getIndex()-1)*pb.getSize();
//int end = pb.getIndex()*pb.getSize();
int start = pb.getStartRow();
int end = pb.getEndRow();
List<Student> list = this.sd.findStu(start,end);
pb.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> 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;
}
public int findCount() {
Connection conn =DBUtil.getConnection();
Statement stmt =null;
ResultSet rs =null;
List <Student> stuList = new ArrayList<Student>();
int count = 0;
try {
stmt =conn.createStatement();
rs = stmt.executeQuery("select count(*) from student");
rs.next();
count = rs.getInt(1);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return count;
}
}
12.带查询条件的分页
(1)带查询条件的分页跟不带查询条件的分页有什么区别?
不带查询条件的分页是查询所有数据,带查询条件的分页是查询满足条件的数据
(2)贴出带查询条件分页的前端代码,后端代码,并写出注释
public class ShowAllServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//1.1接收从页面传入的当前页码index
String sindex = request.getParameter("index");
int index = 1; //默认当前页码是1
try {
index = Integer.parseInt(sindex);
} catch (Exception e) {
e.printStackTrace();
}
//1.2接收从页面传入的每页的记录数
String ssize = request.getParameter("size");
int size = 5;
try {
size = Integer.parseInt(ssize);
} catch (Exception e) {
e.printStackTrace();
}
//1.3接收学生姓名
String name = request.getParameter("name");
//1.4接收最低分数
String sminScore = request.getParameter("minScore");
if(sminScore == null){
sminScore = "";
}
double minScore = 0;
try {
minScore = Double.parseDouble(sminScore);
} catch (Exception e) {
e.printStackTrace();
}
PageBean<Student> pb = new PageBean<Student>();
pb.setIndex(index);
pb.setSize(size);
StudentService ss = new StudentServiceImpl();
//List <Student> stuList =stuBiz.findAll();
//ss.findstu(pb); //不需要返回stuList,因为经过业务层处理,所有的数据都在PageBean中
ss.findstu(pb,name,minScore);;
request.setAttribute("pb",pb);//!!!!!!!
request.setAttribute("name", name);
request.setAttribute("minScore", sminScore);
request.getRequestDispatcher("/jsp/showAll.jsp").forward(request, response);
}
}
public class StudentServiceImpl implements StudentService {
public void findstu(PageBean<Student> pb, String name, double minScore) {
//查询数据库表获取符合查询条件的记录总数
int totalCount = this.sd.findCount(name,minScore);
System.out.println("count="+totalCount);
//使用记录总数计算PageBean中的其他属性(totalCount,totalPageCount,numbers),就差list属性
pb.setTotalCount(totalCount);
//调用Dao层获取指定页的学生数据,并放入PageBean中的list属性
int start = pb.getStartRow();
int end = pb.getEndRow();
List<Student> list = this.sd.findStu(start,end,name,minScore);
pb.setList(list);
}
}
public class StudentDaoImpl implements StudentDao {
public int findCount(String name, double minScore) {
Connection conn =DBUtil.getConnection();
Statement stmt =null;
ResultSet rs =null;
List <Student> stuList = new ArrayList<Student>();
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.createStatement();
rs = stmt.executeQuery(sql.toString());
rs.next();
count = rs.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return count;
}
public List<Student> findStu(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) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, stmt, conn);
}
return stuList;
}
}
<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){
location.href="show?index="+index;
}
function changeSize(size){
location.href="show?size="+size;
}
function change2(index,size){
//location.href="servlet/ShowAllServlet?index="+index+"&size="+size;
document.forms[0].action="show?index="+index+"&size="+size;
document.forms[0].submit();
}
function change(index,size){
document.forms[0].index.value = index;
//document.forms[0].size.value = size;
document.getElementById("size").value = size;
document.forms[0].submit();
}
</script>
</head>
<body>
<hr>
<form action="show" method="post" id="form1">
<table align="center">
<tr>
<td>姓名</td>
<td>
<input type="text" name="name" value="${name }">
<input type="hidden" name="index" value="">
<input type="hidden" id="size" name="size" value="">
</td>
<td>分数>=</td>
<td><input type="text" name="minScore" value="${minScore }"></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
<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="${pb.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="/stu/show?operate=preupdate&sid=${stu.id}">更新</a></td>
<td><a href="/stu/show?operate=delete&sid=${stu.id}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="11" align="center">
<a href="javascript:change(1,${pb.size })">首页</a>
<c:if test="${pb.index != 1 }">
<a href="javascript:change(${pb.index-1 },${pb.size })">上一页</a>
</c:if>
<c:if test="${pb.index == 1 }">
上一页
</c:if>
<c:forEach items="${pb.numbers }" var="num">
<c:if test="${num == pb.index }">
[<a href="javascript:change(${num },${pb.size })">${num }</a>]
</c:if>
<c:if test="${num != pb.index }">
<a href="javascript:change(${num },${pb.size })">${num }</a>
</c:if>
</c:forEach>
<c:if test="${pb.index != pb.totalPageCount}">
<a href="javascript:change(${pb.index+1 },${pb.size })">下一页</a>
</c:if>
<c:if test="${pb.index == pb.totalPageCount}">
下一页
</c:if>
<a href="javascript:change(${pb.totalPageCount},${pb.size })">末页</a>
每页
<select onchange="change(${pb.index},this.value)">
<c:forEach begin="5" end="20" step="5" var="i">
<c:if test="${i == pb.size }">
<option value="${i }" selected="selected">${i }</option>
</c:if>
<c:if test="${i != pb.size }">
<option value="${i }" >${i }</option>
</c:if>
</c:forEach>
</select>
条记录
直接跳转到
<select onchange="change(this.value,${pb.size })">
<c:forEach begin="1" end="${pb.totalPageCount}" var="num">
<c:if test="${num == pb.index }">
<option value="${num }" selected="selected">${num }</option>
</c:if>
<c:if test="${num != pb.index }">
<option value="${num }">${num }</option>
</c:if>
</c:forEach>
</select>
页
共${pb.totalCount }条记录
</td>
</tr>
</table>
</body>
</html>
13.完善带查询条件的分页
(1)完善了哪些功能?简述完善的思路.
输入年龄和分数后点击提交可以查询到指定的数据但是再单击每页多少条数据后,每页记住年龄和分数的值,有两种解决办法,第一种是在change事件中使用document.forms[0].submit();提交表单,同时使用document.forms[0].action的方法将当前页数和每页多少条数据传入。第二种方法是在姓名的input框下面使用hidden将input框隐藏起来,然后使用连接将size和index传入。同时在页面显示多少条记录的下拉框中的onchange事件将当前每页显示多少条数据的值传入。