===========
本次的学生管理系统只有简单的查询学生,还有分页查询学生(分页查询的页数有点bug,但是不用在意,这只是初级版)
采用的是MVC模式
目录结构
index.jsp里
我们先不写Servlet和web.xml,而是先写Dao
<h3><a href="StudentListServlet">显示所有学生列表</a></h3>
<br/>
<h3><a href="StudentListPageServlet?currentPage=1">分页显示所有学生列表</a><h3>
在Dao里
现在我们只需要findAll方法
public interface StudentDao
{
public int PAGE_SIZE=5;
public List<Student> findAll() throws SQLException;
public void insert(Student student) throws SQLException;
public void delete(int sid) throws SQLException;
public Student findStudentById(int sid) throws SQLException;
public void update(Student student) throws SQLException;
public List<Student> search(String sname,String sex) throws SQLException;
public List<Student> findStudentByPage(int currentPage) throws SQLException;
public int findCount() throws SQLException;
}
把这种类写在Bean里
public class Student
{
public int getSid()
{
return sid;
}
public void setSid(int sid)
{
this.sid = sid;
}
public String getSname()
{
return sname;
}
public void setSname(String sname)
{
this.sname = sname;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getInfo()
{
return info;
}
public void setInfo(String info)
{
this.info = info;
}
private int sid;
private String sname;
private String sex;
private String info;
public void setAll(String sid, String sname, String sex, String info)
{
this.sid=Integer.parseInt(sid);
this.sname=sname;
this.sex=sex;
this.info=info;
}
}
然后写实现类,现在只需要写一个findAll方法,其余的不管
在findAll方法里用到了改造后的JDBCUtil (详情见013) 直接获取dataSource即可,然后既然使用dataSource
那么就需要引入c3p0的配置文件了 (013复制过来即可)
注意一下这里的异常应该直接抛出去
public class StudentDaoImp implements StudentDao
{
//我们不在这里捕获异常,而是抛出去先(注意接口处也要定义这个异常),现在我们是在数据访问层,也就是Dao里面
//需要把异常抛给业务逻辑层然后抛给servlet
public List<Student> findAll() throws SQLException
{
//JDBCUtil.getDataSource写了创建ComboPooledDataSource,只要new了这个Combo
//那么就会自动加载固定名称配置文件
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="select * from stu";
//返回一个Student的List集合,这需要Student无参的构造函数
return runner.query(sql, new BeanListHandler<Student>(Student.class));
}
//数据的添加
public void insert(Student student) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="insert into stu values(null,?,?,?)";
runner.update(sql,student.getSname(),student.getSex(),student.getInfo());
}
public void delete(int sid) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="delete from stu where sid=?";
runner.update(sql,sid);
}
public Student findStudentById(int sid) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="select * from stu where sid=?";
return runner.query(sql,new BeanHandler<Student>(Student.class),sid);
}
public void update(Student student) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="update stu set sname=?,sex=?,info=? where sid=?";
runner.update(sql,student.getSname(),student.getSex(),student.getInfo(),student.getSid());
}
public List<Student> search(String sname,String sex) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="select * from stu where 1=1";
List<String>list=new ArrayList<String>();
//如果选了字符串和性别,也能够将sql串联起来
//如果都没选,也能够搜索全部,这个List可以换成StringBuilder
//如果搜索栏里填写了字符
if (sname!=null && sname!="")
{
sql=sql+" and sname like ?";
list.add("%"+sname+"%");
}
//如果选择了性别
if (sex!=null && sex!="")
{
sql=sql+" and sex=?";
list.add(sex);
}
//最后一个是可变参数,需要变成字符串数组
return runner.query(sql,new BeanListHandler<Student>(Student.class),list.toArray());
}
public List<Student> findStudentByPage(int currentPage) throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="select * from stu limit ? offset ?";
//第一个?是一页显示多少个数据,第二个?是从哪里位置开始,比如现在是第1页,1-1*5=0,那么就显示5个,从位置0开始
return runner.query(sql,new BeanListHandler<Student>(Student.class),PAGE_SIZE,(currentPage-1)*PAGE_SIZE);
}
public int findCount() throws SQLException
{
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
Long num=(Long)runner.query("select count(*) from stu",new ScalarHandler());
return num.intValue();
}
}
现在我们写完了Dao,还需要再写一个业务逻辑层service,用于处理这些Dao返回过来的数据进行逻辑处理,而不是直接在Servlet写
这样的好处就是能集中处理单一逻辑,一个Dao只做一件事情,然后sevice(服务)就是将无数个单一事情组合起来,变成复杂的功能
service也是一个接口一个实现类
public interface StudentService
{
public List<Student> findAll() throws SQLException;
public void insert(Student student) throws SQLException;
public void delete(int sid) throws SQLException;
public Student findStudentById(int sid) throws SQLException;
public void update(Student student) throws SQLException;
public List<Student> search(String sname,String sex) throws SQLException;
public PageBean<Student> findStudentByPage(int currentPage) throws SQLException;
}
看findAll方法即可,因为只有一个查询所有学生的业务,所以直接调用Dao的方法即可
public class StudentServiceImp implements StudentService
{
public List<Student> findAll() throws SQLException
{
StudentDao dao=new StudentDaoImp();
return dao.findAll();
}
public void insert(Student student) throws SQLException
{
StudentDao dao=new StudentDaoImp();
dao.insert(student);
}
public void delete(int sid) throws SQLException
{
StudentDao dao=new StudentDaoImp();
dao.delete(sid);
}
public Student findStudentById(int sid) throws SQLException
{
StudentDao dao=new StudentDaoImp();
return dao.findStudentById(sid);
}
public void update(Student student) throws SQLException
{
StudentDao dao=new StudentDaoImp();
dao.update(student);
}
public List<Student> search(String sname,String sex) throws SQLException
{
StudentDao dao=new StudentDaoImp();
return dao.search(sname, sex);
}
public PageBean<Student> findStudentByPage(int currentPage) throws SQLException
{
PageBean<Student> pageBean=new PageBean<Student>();
//当前所在页
pageBean.setCurrentPage(currentPage);
//一页的数量
pageBean.setPageSize(StudentDao.PAGE_SIZE);
//设置一页学生的集合对象
StudentDao dao=new StudentDaoImp();
List<Student> list=dao.findStudentByPage(currentPage);
pageBean.setList(list);
int count=dao.findCount();
pageBean.setTotal(count);
//计算总的页数,这个需要考虑如果不是整除怎么办,那么就+1页
int pageSize=StudentDao.PAGE_SIZE;
int totalPage=(int) (count%pageSize==0? count/pageSize :count/pageSize+1);
pageBean.setTotalPage(totalPage);
return pageBean;
}
}
现在写StudentListServlet 用于查询所有学生
public class StudentListServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
//创建业务层
StudentService service=new StudentServiceImp();
//从数据库查询出所有的学生保存到集合中
List<Student> list=service.findAll();
//把集合对象存放在request作用域中,只要还是这个请求对象,那么这个作用域里的数值就不会丢失
//所有要注意谨慎使用重定向
request.setAttribute("list", list);
//跳转页面
request.getRequestDispatcher("list.jsp").forward(request, response);
} catch (SQLException e)
{
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
然后写的是web.xml,xml没有什么特殊的写法,这里有所有的servlet映射
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>example_002_StudentManngerFinal</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>StudentListServlet</display-name>
<servlet-name>StudentListServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentListServlet</servlet-name>
<url-pattern>/StudentListServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentAddServlet</display-name>
<servlet-name>StudentAddServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentAddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentAddServlet</servlet-name>
<url-pattern>/StudentAddServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentDeleteServlet</display-name>
<servlet-name>StudentDeleteServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentDeleteServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentDeleteServlet</servlet-name>
<url-pattern>/StudentDeleteServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentEditServlet</display-name>
<servlet-name>StudentEditServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentEditServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentEditServlet</servlet-name>
<url-pattern>/StudentEditServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentUpdateServlet</display-name>
<servlet-name>StudentUpdateServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentUpdateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentUpdateServlet</servlet-name>
<url-pattern>/StudentUpdateServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentSearchServlet</display-name>
<servlet-name>StudentSearchServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentSearchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentSearchServlet</servlet-name>
<url-pattern>/StudentSearchServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentListPageServlet</display-name>
<servlet-name>StudentListPageServlet</servlet-name>
<servlet-class>com.Test.servlet.StudentListPageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentListPageServlet</servlet-name>
<url-pattern>/StudentListPageServlet</url-pattern>
</servlet-mapping>
</web-app>
上面我们跳转到的是list页面,现在写list.jsp即可
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function doDelete(sid)
{
var flag=confirm("是否确定删除?");
if(flag)
{
//重定向跳转
window.location.href="StudentDeleteServlet?sid="+sid;
}
}
</script>
<style>
table tr td {
border-color: blue;
}
</style>
</head>
<body>
<form action="StudentSearchServlet" method="post">
<table width="75%" border="1px" align="center" cellspacing="0">
<tr align="center">
<td colspan="5">按姓名查询: <input type="text" name="sname" />
按性别查询: <select name="sex">
<option value="">--请选择--
<option value="男">男
<option value="女">女
</select> <input type="submit" value="查询" />
<a href="add.jsp">添加</a>
</td>
</tr>
<tr align="center" bordercolor="blue">
<td>编号</td>
<td>姓名</td>
<td>性别</td>
<td>简介</td>
<td>操作</td>
</tr>
//现在注意这里即可,这里是使用list,后面的更新删除稍后讲解
<c:forEach items="${list}" var="stu">
<tr align="center" bordercolor="blue">
<td>${stu.sid}</td>
<td>${stu.sname}</td>
<td>${stu.sex}</td>
<td>${stu.info}</td>
<td><a href="StudentEditServlet?sid=${stu.sid}">更新</a> <a
href="#" onclick="doDelete(${stu.sid})">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="5">
</td>
</tr>
</table>
</form>
</body>
</html>
下面是list.jsp编写方式
先写2行8列,一行写字段名称,还有一行写数据示例,然后用JSTL动态创建剩下的行
记得给table加个边框
上面是查询所有学生的功能(后面还有搜索学生),下面是添加学生的功能
在list.jsp里,直接跳转到添加学生的页面add.jsp,其实应该跳到servlet,然后再跳到add.jsp,现在还是初级,简单的写下就行
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style>
table tr td {
border-color: blue;
}
</style>
</head>
<body>
<h2>添加学生界面</h2>
<form method="post" action="StudentAddServlet">
<table border="1px" width="50%" cellspacing="0">
<tr>
<td>姓名</td>
<td>
<input type="text" name="sname" />
</td>
</tr>
<tr>
<td>性别</td>
<td><input type="radio" name="sex" value="男">男 </input> <input
type="radio" name="sex" value="女">女 </input></td>
</tr>
<tr>
<td>简介</td>
<td><textarea rows="5" cols="30" name="info"></textarea></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交" />
</td>
</tr>
</table>
</form>
</body>
</html>
然后是写Dao的insert方法(最上面把所有DaoImp的代码都写出来了)
StudentAddServlet
在student里面写一个构造方法,把我们从页面获取的数据都搞成一个对象
从网页过来的都是String类型,而我们的数据不全是String类型,所以必须要格式化转换
这里还要注意一下,这个getParameter只能获取一个数据,假如我们写了hobby,兴趣有好几个
但是只能取到第一个,所以一般这种情况要用request.getParameterValues
public class StudentAddServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
//因为是网页过来的(添加用户信息界面),所以最好编码一下
request.setCharacterEncoding("utf-8");
//获取网页过来的参数
String sname = request.getParameter("sname");
String sex = request.getParameter("sex");
String info = request.getParameter("info");
//添加数据到数据库
Student student = new Student();
student.setSname(sname);
student.setSex(sex);
student.setInfo(info);
StudentService service = new StudentServiceImp();
service.insert(student);
//这个跳转需要注意,不能直接跳到list.jsp里,因为这是请求转发,直接跳转到list.jsp,那么集合里的数据还是之前数据库的数据
//所以直接跳到StudentListServlet
//跳转到servlet,也就是一开始获取全部信息的servlet
request.getRequestDispatcher("StudentListServlet").forward(request, response);
} catch (Exception e)
{
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
删除功能,需要写js来弹出是否删除对话框(详情上面list.jsp里),还需要写DeleteServlet(Dao里已经写了)
public class StudentDeleteServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
//接受sid
int sid = Integer.parseInt(request.getParameter("sid"));
//执行删除
StudentService service = new StudentServiceImp();
service.delete(sid);
//跳转到列表页
request.getRequestDispatcher("StudentListServlet").forward(request, response);;
} catch (Exception e)
{
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
然后是更新的操作,上面的已经把stu的信息放到作用域了,然后更新操作的时候,就把原先的信息放入
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>更新学生界面</h2>
<form method="post" action="StudentUpdateServlet">
<input type="hidden" name="sid" value="${stu.sid}"/>
<table border="1px" width="50%" cellspacing="0">
<tr>
<td>姓名</td>
<td>
<input type="text" name="sname" value="${stu.sname}"/>
</td>
</tr>
<tr>
<td>性别</td>
<td>
<input type="radio" name="sex" value="男"
<c:if test="${stu.sex=='男'}">
checked
</c:if>> 男
</input>
<input type="radio" name="sex" value="女"<c:if test="${stu.sex=='女'}">checked </c:if>> 女 </input>
</td>
</tr>
<tr>
<td>简介</td>
<td><textarea rows="5" cols="30" name="info"> ${stu.info}</textarea></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="更新" />
</td>
</tr>
</table>
</form>
</body>
</html>
如果有复选框,就只能用包含函数,使用jstl的包含函数,需要加上function这个标签库,别名默认是fn
然后就是提交的时候,跳转到updateServlet里
public class StudentUpdateServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
//设置下编码
request.setCharacterEncoding("utf-8");
//获取提交过来的新的数据,然后更新到数据库
String sid=request.getParameter("sid");
String sname=request.getParameter("sname");
String sex=request.getParameter("sex");
String info=request.getParameter("info");
Student student=new Student();
student.setAll(sid, sname, sex, info);
StudentService service=new StudentServiceImp();
service.update(student);
//跳转到首页显示数据
request.getRequestDispatcher("StudentListServlet").forward(request, response);
} catch (SQLException e)
{
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
上面实现了删除,添加,更新的功能,下面就是模糊查询学生和分页查询,这2个Dao都已经写了, 详情看上面,下面是SearchServlet
public class StudentSearchServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
request.setCharacterEncoding("utf-8");
try
{
//取到关键的数据
String sname=request.getParameter("sname");
String sex=request.getParameter("sex");
//找到service去查询
StudentService service=new StudentServiceImp();
List<Student>list=service.search(sname, sex);
System.out.println(list);
for (Student student : list)
{
System.out.println(student.getSname());
}
//把得到的结果集合通过作用域传递到首列表界面去,让它去显示那些结果
//所以这个属性名一定要是list
request.setAttribute("list",list);
//跳转到首页面
request.getRequestDispatcher("list.jsp").forward(request, response);
} catch (Exception e)
{
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
}
下面是分页查询
修改主页index.html
写servlet
写servlet之前先要写Dao和service
这个page_size是等于5,写在Dao的接口里的,下面的是接口的实现
要实现显示那些数据,就必须要再写一个javaBean
这里写泛型是因为如果以后有一个teacher的类就可以直接传入teacher了
而不是写死Student
那么现在应该在service写业务了,这个和之前不一样了,不能直接new然后调用方法了
而是要自己写业务逻辑了,下面的 new Studentdaoimpl(). findstudentbypage(currentpage);这个是Dao层的实现类
功能是存储某页学生的信息.现在我们依然在findstudentbypage这个函数里,只不过是在service层了
还需要获取总的记录数,也就是总的个数,还有总的页数
获取总的数据量,用ScalarHandler
写下剩余的service层代码
最后就是在StudentListPageServlet 写代码了
下面是要写的跳转到的页面,这个页面和list页面样,需要修改几个地方