MVC模式
1.JSP的开发模式
2.三层架构
3.学生信息管理系统
3.1数据库&Student类准备
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20),
gender VARCHAR(5),
phone VARCHAR(20),
hobby VARCHAR(50),
birthday DATE,
synopsis VARCHAR(50),
info VARCHAR(200)
)
public class Student {
private int sid;
private String sname;
private String gender;
private String phone;
private String hobby;
private String synopsis;
private Date birthday;
private String info;
public Student() {
super();
}
//这里要把sid给删掉,因为sid并不是添加Student时给定的,而是数据库表自增的
public Student(String sname, String gender, String phone, String hobby, String synopsis, Date birthday,String info) {
super();
this.sname = sname;
this.gender = gender;
this.phone = phone;
this.hobby = hobby;
this.synopsis = synopsis;
this.birthday = birthday;
this.info = info;
}
//将更新后的其它内容和sid重新封装成一个新的Student对象,更新数据库时是根据sid更新的,所以要有一个包含sid的构造方法
public Student(int sid,String sname, String gender, String phone, String hobby, String synopsis, Date birthday,String info) {
super();
this.sid=sid;
this.sname = sname;
this.gender = gender;
this.phone = phone;
this.hobby = hobby;
this.synopsis = synopsis;
this.birthday = birthday;
this.info = info;
}
......get/set
}
3.2查询
3.2.1查询所有学生
3.2.1.1不带分页
-
index.jsp
<h3><a href="StuListServlet">显示所有学生</a></h3>
-
StuListServlet接收请求,调用Service,再由Service调用Dao
- StudentServiceImpl
public class StudentServiceImpl implements StudentService { public List<Student> findAll() throws SQLException { StudentDao dao=new StudentDaoImpl(); return dao.findAll(); } }
- StudentDaoImpl
public class StudentDaoImpl implements StudentDao { public List<Student> findAll() throws SQLException {//实现类的方法想要抛异常,接口的方法也要抛异常 QueryRunner qr=new QueryRunner(JDBCUtilsConfigPro.getDataSource()); String sql="select * from stu"; List<Student> list=qr.query(sql, new BeanListHandler<Student>(Student.class)); return list; } }
- StuListServlet
//负责查询所有的学生信息,显示到stuList.jsp上 public class StuListServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //1.查询出所有的学生 StudentService service=new StudentServiceImpl(); List<Student> list=service.findAll(); //2. 把数据存储到作用域中 request.setAttribute("list", list); //3. 跳转到学生列表显示页面 request.getRequestDispatcher("stuList.jsp").forward(request, response); } catch (SQLException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
stuList.jsp显示数据
<table border="1" width="700px"> <tr align="center"> <td>编号</td> <td>姓名</td> <td>性别</td> <td>电话</td> <td>生日</td> <td>爱好</td> <td>简介</td> <td>操作</td> </tr> <c:forEach items="${list }" var="stu"> <tr align="center"> <td>${stu.sid }</td> <td>${stu.sname }</td> <td>${stu.gender }</td> <td>${stu.phone }</td> <td>${stu.birthday }</td> <td>${stu.hobby }</td> <td>${stu.synopsis }</td> </tr> </c:forEach> </table>
3.2.1.2带分页
-
在index.jsp页面,点击“分页显示学生”时,向StuPageServlet发送请求,当前页currentPage设置为1,即查询第一页学生数据
<h3><a href="StuPageServlet?currentPage=1">分页显示学生</a></h3>
-
StuPageServlet调用Service获取分页数据,传递到stuPageList.jsp
- StuPageServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //1.获取要显示的页码数 int currentPage= Integer.parseInt(request.getParameter("currentPage")); //2.获取该页的数据 StudentService service=new StudentServiceImpl(); PageBean pageBean=service.pageQuery(currentPage); request.setAttribute("pageBean", pageBean); //3.跳转界面 request.getRequestDispatcher("stuPageList.jsp").forward(request, response); } catch (SQLException e) { e.printStackTrace(); } }
- PageBean
/** * 这是用于封装分页的数据: * 该页的学生集合数据 * 当前页数 * 总页数 * 每页显示的记录数 * 总的记录数 */ public class PageBean<T> { //private List<Student> list;//该页的学生集合数据 private List<T> list; //使用泛型是为了提高代码的复用性,因为以后可能会有其他类,如Teacher,Staff等 private int currentPage;//当前页数 private int totalPage;//总页数 private int totalSize;//总的记录数 //private int pageSize;//每页显示的记录数 //可在这里设置为固定值 public static final int pageSize=10; get/set ... }
- stuPageList.jsp
<c:forEach items="${pageBean.list }" var="stu"><!--request域中存的是pageBean,通过pageBean获取list--> <tr align="center"> <td>${stu.sid }</td> <td>${stu.sname }</td> <td>${stu.gender }</td> <td>${stu.phone }</td> <td>${stu.birthday }</td> <td>${stu.hobby }</td> <td>${stu.synopsis }</td> <td>${stu.info}</td> </tr> </c:forEach> <tr> <td colspan="8"> 第${pageBean.currentPage } / ${pageBean.totalPage } 页 每页 ${pageBean.pageSize } 条 共 ${pageBean.totalSize } 条 <!-- 第一页时不显示“首页|上一页” --> <c:if test="${pageBean.currentPage !=1 }"> <a href="StuPageServlet?currentPage=1">首页</a> | <a href="StuPageServlet?currentPage=${pageBean.currentPage-1} ">上一页</a> </c:if> <c:forEach begin="1" end="${pageBean.totalPage }" var="i"> <!-- 当前页时,这个页数不能点击 --> <c:if test="${pageBean.currentPage==i }"> ${i } </c:if> <c:if test="${pageBean.currentPage!=i }"> <a href="StuPageServlet?currentPage=${i }">${i }</a> </c:if> </c:forEach> <!-- 最后一页时不显示“下一页|尾页” --> <c:if test="${pageBean.currentPage !=pageBean.totalPage }"> <!-- <a href="StuPageServlet?currentPage="+${PageBean.currentPage+1}>下一页</a> 这样写居然是错的!!! --> <a href="StuPageServlet?currentPage=${pageBean.currentPage+1 }">下一页</a> | <a href="StuPageServlet?currentPage=${pageBean.totalPage }">尾页</a> </c:if> </td> </tr>
3.2.1.2.1分页功能
-
物理分页(真分页)
只到数据库中查询一页的数据就返回。
- 优点:内存中的数据量不会太大
- 缺点:对数据库的访问比较频繁
-
逻辑分页(假分页)
把所有数据都查询出来,然后放到内存中。
- 优点:访问速度快
- 缺点:数据量大,可能导致内存溢出
3.2.2模糊查询
输入模糊查询条件后,调用FuzzyQueryServlet
- stuList.jsp
<form action="FuzzyQueryServlet" method="post">
<table border="1" width="700px">
<tr>
<td colspan="8">
按姓名查询:<input type="text" name="sname"/>
按性别查询:<select name="gender">
<option value="">--请选择--
<option value="男">男
<option value="女">女
</select>
<input type="submit" value="查询"/>
<a href="addStu.jsp">添加</a>
</td>
</tr>
</table>
- FuzzyQueryServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//模糊查询提交上来的条件有中文
request.setCharacterEncoding("UTF-8");
//1.获取模糊查询的条件
String sname=request.getParameter("sname");
String gender=request.getParameter("gender");
//2.调用service执行查询
StudentService service=new StudentServiceImpl();
List<Student> list=service.fuzzyQuery(sname, gender);
request.setAttribute("list", list);
//3.跳转到stuList.jsp
request.getRequestDispatcher("stuList.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
}
}
- StudentDaoImpl
需要考虑的情况:1.只有姓名;2.只有性别;3.既有姓名,也有性别;4.姓名输入框可能输入空格
public List<Student> fuzzyQuery(String sname, String gender) {
List<Student> list=null;
String sql="select * from stu where sname like '%"+sname.replace(" ","")+"%'";
//去掉sname中可能存在的空格
try {
QueryRunner queryRunner=new QueryRunner();
Connection connection = JDBCUtils.getConn();
if(!gender.equals("")){
sql+="and gender=?";
list = queryRunner.query(connection, sql, new BeanListHandler<Student>(Student.class),gender);
}else{
list = queryRunner.query(connection, sql, new BeanListHandler<Student>(Student.class));
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
3.3增加
-
在stuList.jsp页面点击"添加"跳转到addStu.jsp页面
<a href="addStu.jsp">添加</a>
- addStu.jsp
<body> <h3>添加学生页面</h3> <form method="post" action="AddStuServlet"> <table border="1" width="700"> <tr> <td>姓名</td> <td><input type="text" name="sname"/></td> </tr> <tr> <td>性别</td> <td> <input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" />女 </td> </tr> <tr> <td>电话</td> <td><input type="text" name="phone" /></td> </tr> <tr> <td>生日</td> <td><input type="text" name="birthday" /></td> </tr> <tr> <td>爱好</td> <td> <input type="checkbox" name="hobby" value="游泳"/>游泳 <input type="checkbox" name="hobby" value="跑步"/>跑步 <input type="checkbox" name="hobby" value="听音乐"/>听音乐 <input type="checkbox" name="hobby" value="看书"/>看书 <input type="checkbox" name="hobby" value="爬山"/>爬山 </td> </tr> <tr> <td>简介</td> <td><textarea name="synopsis" rows="3" cols="30" ></textarea></td> </tr> <tr> <td colspan="2"><input type="submit" value="添加" /></td> </tr> </table> </form> </body>
-
点击"添加"后,数据提交到AddStuServlet,将学生信息添加到数据库后跳转到StuListServlet,查询出所有学生后跳转到StuList.jsp
- AddStuServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); //1.获取系统提交上来的数据 String sname=request.getParameter("sname"); String gender=request.getParameter("gender"); String phone=request.getParameter("phone"); String birthday=request.getParameter("birthday"); //String hobby=request.getParameter("hobby");//hobby可能有多项,这样只能得到第一项 String[] hobbies=request.getParameterValues("hobby"); String hobby=Arrays.toString(hobbies);//如:[跑步,游泳,爬山] hobby=hobby.substring(1,hobby.length()-1);//如:跑步,游泳,爬山 String synopsis=request.getParameter("synopsis"); try { //2.添加到数据库 Date birthday2 = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);//String--Date, 构造方法中birthday为Date类型 Student student=new Student(sname, gender, phone, hobby, synopsis, birthday2); StudentService service=new StudentServiceImpl(); service.insert(student); //3.跳转到stuList.jsp页面 //先跳到StuListServlet,查询出所有学生后跳转到stuList.jsp request.getRequestDispatcher("StuListServlet").forward(request, response); } catch (Exception e) { e.printStackTrace(); } }
3.4删除
-
在stuList.jsp和stuPage.jsp添加删除按钮
<a href="#" onclick="doDelete(${stu.sid})">删除</a>
点击删除后,弹出对话框询问是否删除,如是,把sid传递到DeleteStuServlet
<!-- 脚本代码,实现弹出对话框 --> <script type="text/javascript"> function doDelete(sid){ var flag=confirm("是否确定删除?"); if(flag){ //点击确定,访问DelteStuServlet //window.location.href="DeleteStuServlet?sid="+sid;//在当前标签页打开超链接 location.href="DeleteStuServlet?sid="+sid; } } </script>
-
DeleteStuServlet接收到sid后,执行删除,然后跳转到StuListServlet,再跳转到学生列表页
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //1.接收sid int sid=Integer.parseInt(request.getParameter("sid")); StudentService service=new StudentServiceImpl(); //2.执行删除 service.delete(sid); //3.跳转到列表页 request.getRequestDispatcher("StuListServlet").forward(request, response); } catch (SQLException e) { e.printStackTrace(); } }
3.5修改
-
在stuList.jsp添加更新按钮
<a href="EditStuServlet?sid=${stu.sid}">修改</a>
-
点击修改按钮后,跳转到EditStuServlet,根据传过来的sid查询出用户信息并放到作用域中,然后跳转到editStu.jsp页面展示
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sid = request.getParameter("sid"); StudentService studentService=new StudentServiceImpl(); Student student=studentService.findBySid(sid); request.setAttribute("stu",student); request.getRequestDispatcher("editStu.jsp").forward(request,response); }
-
editStu.jsp展示信息如下
比较难的是性别和爱好,这两个该如何展示?
-
性别
用c:if标签来判断是否checked
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<tr> <td>性别</td> <td> <input type="radio" name="gender" value="男" <c:if test="${stu.gender=='男'}">checked</c:if> >男 <input type="radio" name="gender" value="女" <c:if test="${stu.gender=='女'}">checked</c:if> >女 </td> </tr>
-
爱好
爱好可能有很多个,所以用包含关系来判断。
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<tr> <td>爱好</td> <td> <input type="checkbox" name="hobby" value="游泳" <c:if test="${fn:contains(stu.hobby,'游泳')}">checked</c:if> >游泳 <input type="checkbox" name="hobby" value="篮球" <c:if test="${fn:contains(stu.hobby,'篮球' )}">checked</c:if> >篮球 ...... </td> </tr>
- 用户点击提交后,提交上来的表单中是不包含sid的,所以要在editStu.jsp中手动创建一个隐藏的输入框,在这里面给定sid的值,以便提交表单时带上sid
<input type="hidden" name="sid" value="${stu.sid }"/>
- UpdateStuServlet接收提交上的数据并添加到数据库中,然后跳转到StuListServlet,再跳转到StuList.jsp
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
try {
//1.获取updateStu.jsp提交上来的数据
int sid=Integer.parseInt(request.getParameter("sid"));
String sname=request.getParameter("sname");
String gender=request.getParameter("gender");
String phone=request.getParameter("phone");
String synopsis=request.getParameter("synopsis");
String[] hobbies=request.getParameterValues("hobby");
String birthday=request.getParameter("birthday");
Date date=new SimpleDateFormat("yyyy-mm-dd").parse(birthday);
String hobby=Arrays.toString(hobbies);
hobby=hobby.substring(1, hobby.length()-1);
//2.添加到数据库
//注意:这里的新建的student是带有sid的
Student student=new Student(sid,sname, gender, phone, hobby, synopsis, date);
StudentService service=new StudentServiceImpl();
service.update(student);
//3.跳转界面
request.getRequestDispatcher("StuListServlet").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}