JavaWeb学习案例——学生管理系统
引入jar包:
1、 c3p0-0.9.1.2.jar // 第三方数据库连接池
2、commons-dbutils-1.4.jar // 第三方数据库操作方法封装
3、jstl.jar // jsp中jstl语法引入
4、mysql-connector-java-5.1.7-bin // sql 数据库
bean对象
public class Student {
private int sid;
private String sname;
private String gender;
private String phone;
private String hobby;
private String info;
private Date birthday;
}
// 分页的学生数据列表
public class PageBean<T> {
private int currentPage; //当前页
private int totalPage;//总页数
private int pageSize;//每页的记录数
private int totalSize; //总的记录数
private List<T> list; //当前页的学生集合
}
jdbc数据库连接池方法封装
public class JDBCUtil {
static ComboPooledDataSource dataSource = null;
static{
dataSource = new ComboPooledDataSource();}
public static DataSource getDataSource(){
return dataSource;}
/**
* 获取连接对象
* @return
* @throws SQLException
*/
public static Connection getConn() throws SQLException{
return dataSource.getConnection();}
/**
* 释放资源
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn , Statement st , ResultSet rs){
closeRs(rs);
closeSt(st);
closeConn(conn);}
public static void release(Connection conn , Statement st){
closeSt(st);
closeConn(conn);}
private static void closeRs(ResultSet rs){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}}
private static void closeSt(Statement st){
try {
if(st != null){
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
}
private static void closeConn(Connection conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
针对数据内容数据库查询方法封装
/**
* 这是StudentDao的实现。 针对前面定义的规范,做出具体的实现。
* @author xiaomi
*/
public class StudentDaoImpl implements StudentDao {
/**
* 查询所有学生
* @throws SQLException
*/
@Override
public List<Student> findAll() throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
List<Student> query = runner.query("select * from stu", new BeanListHandler<Student>(Student.class));
return runner.query("select * from stu", new BeanListHandler<Student>(Student.class)); }
@Override
public void insert(Student student) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
runner.update("insert into stu values(null , ?,?,?,?,?,?)" ,
student.getSname(),
student.getGender(),
student.getPhone(),
student.getBirthday(),
student.getHobby(),
student.getInfo()
);}
@Override
public void delete(int sid) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
runner.update("delete from stu where sid=?" ,sid);
}
@Override
public Student findStudentById(int sid) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
return runner.query("select * from stu where sid = ?", new BeanHandler<Student>(Student.class) ,sid);}
@Override
public void update(Student student) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
runner.update("update stu set sname=? , gender=? , phone=? , birthday=? , hobby=? , info=? where sid = ?",
student.getSname(),
student.getGender(),
student.getPhone(),
student.getBirthday(),
student.getHobby(),
student.getInfo(),
student.getSid());}
@Override
public List<Student> searchStudent(String sname, String sgender) throws SQLException {
System.out.println("现在要执行模糊查询了,收到的name ="+sname + "==genser=="+sgender);
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
//String sql = "select * from stu where sname=? or sgender=?";
/*
* 这里要分析一下:
* 如果只有姓名 ,select * from stu where sname like ? ;
* 如果只有性别 , select * from stu where gender = ?
* 如果两个都有 select * from stu where sname like ? and gender=?
* 如果两个都没有就查询所有。
*/
String sql = "select * from stu where 1=1 ";
List<String> list = new ArrayList<String> ();
//判断有没有姓名, 如果有,就组拼到sql语句里面
if(!TextUtils.isEmpty(sname)){
sql = sql + " and sname like ?";
list.add("%"+sname+"%");
}
//判断有没有性别,有的话,就组拼到sql语句里面。
if(!TextUtils.isEmpty(sgender)){
sql = sql + " and gender = ?";
list.add(sgender);
}
Object[] objects = list.toArray();
return runner.query(sql , new BeanListHandler<Student>(Student.class) ,list.toArray() );
}
@Override
public List<Student> findStudentByPage(int currentPage) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
//第一个问号,代表一页返回多少条记录 , 第二个问号, 跳过前面的多少条记录。
//5 0 --- 第一页 (1-1)*5
//5 5 --- 第二页 (2-1)*5
//5 10 --- 第三页
return runner.query("select * from stu limit ? offset ?",
new BeanListHandler<Student>(Student.class) , PAGE_SIZE , (currentPage-1)*PAGE_SIZE);
}
@Override
public int findCount() throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
//用于处理 平均值 、 总的个数。
Long result = (Long) runner.query("SELECT COUNT(*) FROM stu" , new ScalarHandler() );
return result.intValue();
}
}
针对实际业务封装的服务类
注意与DAO层进行区分
/**
* 这是学生业务实现
* @author xiaomi
*
*/
public class StudentServiceImpl implements StudentService {
@Override
public List<com.itheima.domain.Student> findAll() throws SQLException {
StudentDao dao = new StudentDaoImpl();
List<Student> all = dao.findAll();
return dao.findAll();}
@Override
public void insert(com.itheima.domain.Student student) throws SQLException {
StudentDao dao = new StudentDaoImpl();
dao.insert(student);}
@Override
public void delete(int sid) throws SQLException {
StudentDao dao = new StudentDaoImpl();
dao.delete(sid);}
@Override
public com.itheima.domain.Student findStudentById(int sid) throws SQLException {
StudentDao dao = new StudentDaoImpl();
return dao.findStudentById(sid);}
@Override
public void update(com.itheima.domain.Student student) throws SQLException {
StudentDao dao = new StudentDaoImpl();
dao.update(student);}
@Override
public List<com.itheima.domain.Student> searchStudent(String sname, String sgender) throws SQLException {
return new StudentDaoImpl().searchStudent(sname, sgender);}
@Override
public PageBean findStudentByPage(int currentPage) throws SQLException {
//封装分页的该页数据
PageBean<Student> pageBean = new PageBean<Student>();
int pageSize = StudentDao.PAGE_SIZE ;
pageBean.setCurrentPage(currentPage); //设置当前页
pageBean.setPageSize(pageSize); //设置每页显示多少记录
StudentDao dao = new StudentDaoImpl() ;
List<Student> list =dao.findStudentByPage(currentPage);
pageBean.setList(list); //设置这一页的学生数据
//总的记录数, 总的页数。
int count = dao.findCount();
pageBean.setTotalSize(count); //设置总的记录数
//200 , 10 ==20 201 , 10 = 21 201 % 10 == 0 ?201 / 10 :201 % 10 + 1
pageBean.setTotalPage(count % pageSize==0 ? count / pageSize : (count / pageSize) + 1); //总页数
return pageBean;
}
}
JSP和Servlet 业务层面代码
链接servlet注册文件:Web.xml
和android的页面注册文件非常类似,对于页面的url需要提前注册。
<servlet>
和<servlet-mapping>
需要一一对应
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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.hhh.servlet.StudentListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentListServlet</servlet-name>
<url-pattern>/StudentListServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>AddServlet</display-name>
<servlet-name>AddServlet</servlet-name>
<servlet-class>com.hhh.servlet.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddServlet</servlet-name>
<url-pattern>/AddServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>DeleteServlet</display-name>
<servlet-name>DeleteServlet</servlet-name>
<servlet-class>com.hhh.servlet.DeleteServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DeleteServlet</servlet-name>
<url-pattern>/DeleteServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>EditServlet</display-name>
<servlet-name>EditServlet</servlet-name>
<servlet-class>com.hhh.servlet.EditServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EditServlet</servlet-name>
<url-pattern>/EditServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>UpdateServlet</display-name>
<servlet-name>UpdateServlet</servlet-name>
<servlet-class>com.hhh.servlet.UpdateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UpdateServlet</servlet-name>
<url-pattern>/UpdateServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>SearchStudentServlet</display-name>
<servlet-name>SearchStudentServlet</servlet-name>
<servlet-class>com.hhh.servlet.SearchStudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SearchStudentServlet</servlet-name>
<url-pattern>/SearchStudentServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>StudentListPageServlet</display-name>
<servlet-name>StudentListPageServlet</servlet-name>
<servlet-class>com.hhh.servlet.StudentListPageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentListPageServlet</servlet-name>
<url-pattern>/StudentListPageServlet</url-pattern>
</servlet-mapping>
</web-app>
index.jsp 起始页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3><a href="StudentListServlet">显示所有学生列表</a></h3><br>
<h3><a href="StudentListPageServlet?currentPage=1">分页显示所有学生</a></h3>
</body>
</html>
StudentListPageServlet:学生列表
对于跳转到jsp进行展示的数据,我们通过request设置属性所对应的对象进行数据传递。
/**
* 这是用于分页显示学生列表的servlet
* @author xiaomi
*/
public class StudentListPageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1. 获取需要显示的页码数
int currentPage =Integer.parseInt( request.getParameter("currentPage"));
//2. 根据指定的页数,去获取该页的数据回来
//List<Student> --- list.jsp
StudentService service = new StudentServiceImpl();
PageBean pageBean= service.findStudentByPage(currentPage);
request.setAttribute("pageBean", pageBean);
//3. 跳转界面。
request.getRequestDispatcher("list.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
list.jsp 学生列表展示界面
对于直接跳转的页面直接通过a标签带参跳转,jsp中我们一般进行少量数据的传递。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: huhanghao
Date: 2019-10-31
Time: 22:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="SearchStudentServlet" method="post">
<table border="1" width="700">
<tr >
<td colspan="8">
按姓名查询:<input type="text" name="sname"/>
按性别查询:<select name="sgender">
<option value="">--请选择--
<option value="男">男
<option value="女">女
</select>
<input type="submit" value="查询">
<a href="add.jsp">添加</a>
</td>
</tr>
<tr align="center">
<td>编号</td>
<td>姓名</td>
<td>性别</td>
<td>电话</td>
<td>生日</td>
<td>爱好</td>
<td>简介</td>
<td>操作</td>
</tr>
<c:forEach items="${pageBean.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.info }</td>
<td><a href="EditServlet?sid=${stu.sid }">更新</a> <a href="#" onclick="doDelete(${stu.sid})">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="8">
第 ${pageBean.currentPage } / ${pageBean.totalPage }
每页显示${pageBean.pageSize }条
总的记录数${pageBean.totalSize }
<c:if test="${pageBean.currentPage !=1 }">
<a href="StudentListPageServlet?currentPage=1">首页</a>
| <a href="StudentListPageServlet?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="StudentListPageServlet?currentPage=${i }">${i }</a>
</c:if>
</c:forEach>
<c:if test="${pageBean.currentPage !=pageBean.totalPage }">
<a href="StudentListPageServlet?currentPage=${pageBean.currentPage+1 }">下一页</a> |
<a href="StudentListPageServlet?currentPage=${pageBean.totalPage }">尾页</a>
</c:if>
</td>
</tr>
</table>
</form>
</body>
<script>
function doDelete(sid) {
/* 如果这里弹出的对话框,用户点击的是确定,就马上去请求Servlet。
如何知道用户点击的是确定。
如何在js的方法中请求servlet。 */
var flag = confirm("是否确定删除?");
if(flag){
//表明点了确定。 访问servlet。 在当前标签页上打开 超链接,
//window.location.href="DeleteServlet?sid="+sid;
location.href="DeleteServlet?sid="+sid;
}
}
</script>
</html>
EditServlet学生信息更新
/**
* 处理单个学生的更新, 查询一个学生的信息,然后跳转到更新页面
* @author xiaomi
*
*/
public class EditServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1. 接收id
int sid = Integer.parseInt(request.getParameter("sid"));
//2. 查询学生数据
StudentService service = new StudentServiceImpl();
Student stu = service.findStudentById(sid);
//3. 显示数据
//存数据
request.setAttribute("stu", stu);
//跳转
request.getRequestDispatcher("edit.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
edit.jsp更新学生信息页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!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>更新学生页面</title>
</head>
<body>
<h3>更新学生页面</h3>
<form method="post" action="UpdateServlet">
<input type="hidden" name="sid" value="${stu.sid }">
<table border="1" width="600">
<tr>
<td>姓名</td>
<td><input type="text" name="sname" value="${stu.sname }"></td>
</tr>
<tr>
<td>性别</td>
<td>
<!-- 如果性别是男的, 可以在男的性别 input标签里面, 出现checked ,
如果性别是男的, 可以在女的性别 input标签里面,出现checked -->
<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>
<tr>
<td>电话</td>
<td><input type="text" name="phone" value="${stu.phone }"></td>
</tr>
<tr>
<td>生日</td>
<td><input type="text" name="birthday" value="${stu.birthday }"></td>
</tr>
<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>>篮球
<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>>看书
<input type="checkbox" name="hobby" value="写字" <c:if test="${fn:contains(stu.hobby,'写字') }">checked</c:if>>写字
</td>
</tr>
<tr>
<td>简介</td>
<td><textarea name="info" rows="3" cols="20">${stu.info }</textarea></td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="更新"> </td>
</tr>
</table>
</form>
</body>
</html>