CREATE DATABASE stus;
USE stus;
CREATE TABLE students(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR (20),
gender VARCHAR (5),
phone VARCHAR (20),
birthday DATE,
hobby VARCHAR(50),
info VARCHAR(200)
);
不会用的看我上一节博客
注意:导包的时候注意千万不要导错,否则会产生未知的错误
工程连接数据库,使用数据库连接池,开源数据库连接池 c3p0
c3p0-0.9.1.2.jar
mysql-connector-java-5.1.7-bin.jar
c3p0-config.xml 写用户名 密码,放在src目录下,名字不能改
使用JDBCUtils ,封装简化了CRUD(增删改查)操作
commons-dbutils-1.4.jar
jsp页面中,要做一些遍历选择操作,使用 JSTL 标签库
jstl.jar
standard.jar
<head>
<title>学生管理系统title>
head>
<body>
<h3><a href="StudentListServlet">显示所有学生列表a>h3>
<h3><a href="StudentListPageServlet?currentPage=1">分页显示所有学生列表a>h3>
body>
try {
//1、在数据库中查询所有学生的数据,并返回一个list集合
StudentService stu = new StudentServiceImpl();
List<Student> list = stu.findAll();
//2、将返回的数据保存在作用域中
request.setAttribute("list",list);
//3、跳转页面
request.getRequestDispatcher("list.jsp").forward(request,response);
} catch (SQLException e) {
e.printStackTrace();
}
/**
* 业务逻辑层,处理所有的业务,
* 业务包含多个逻辑,也可以是单个逻辑,当是单个逻辑的时候,和 dao层没有什么区别,但是处理多个逻辑的时候,就有区别了
* dao层只能处理单个逻辑,业务处理多个逻辑(分页的业务)
*/
public interface StudentService {
/**
* 查询所有学生的信息
* @return List
*/
List<Student> findAll() throws SQLException;
}
public class StudentServiceImpl implements StudentService {
@Override
public List<Student> findAll() throws SQLException {
StudentDao studentDao = new StudentDaoImpl();
List<Student> list = studentDao.findAll();
return list;
}
}
/**
* 数据访问层,进行数据的访问处理和封装
* 只能处理单个的逻辑,每个逻辑是一个方法封装的
*/
public interface StudentDao {
/**
* 查询所有的学生
* @return List
*/
List<Student> findAll() throws SQLException;
}
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> findAll() throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
List<Student> list = queryRunner.query("select * from students", new BeanListHandler<Student>(Student.class));
return list;
}
}
知识点:
1. window.confirm("确定要删除?") js中的弹出框,有确定删除按钮,确定返回true,取消返回folse
2. window.location.href="url" 使用js完成 标签的功能
3. 要删除某一个学生的信息,是根据唯一标识id进行删除的,点击事件,调用方法,方法中需要传参数id的值 function a(${stu.sid})
接的时候直接写个变量, function a (sid){ } ,方法名不要使用特殊的名字,比如id什么的,与document对象中的方法变量重名时,报错。
4. 在删除跳转页面的时候,一定要跳转到StudentListServlet,要重新查一遍数据库,才能显示删除数 据库后最新的结果,
因为,之前的查的数据作用域是request,现在不是一个作用域中,查到的是空就算之后改域,
增大作用域,也只能是查到之前的数据,查不到插入后的数据库中的数据
所以,只有重新再查一遍,才能看到新查入的数据
<script type="text/javascript">
function adele(id) {
//弹出框确定和删除,返回booern
var con = confirm("确定要删除吗?");
if (con){
window.location.href="StudentDeleteServlet?sid="+id;
}
}
script>
try {
//1、获取要删除学生的id
int id = (int)Long.parseLong(request.getParameter("sid"));
//2、删除学生
StudentService studentService = new StudentServiceImpl();
studentService.delete(id);
//3、跳转页面
request.getRequestDispatcher("StudentListServlet").forward(request,response);
} catch (SQLException e) {
e.printStackTrace();
}
/**
* 删除
* 根据id删除学生的信息
* @param id
* @throws SQLException
*/
void delete(int id) throws SQLException;
@Override
public void delete(int id) throws SQLException {
StudentDao studentDao = new StudentDaoImpl();
studentDao.delete(id);
}
/**
* 删除
* 根据id 删除学生
* @param id
* @throws SQLException
*/
void delete(int id) throws SQLException;
@Override
public void delete(int id) throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
queryRunner.update("delete from students where sid = ?",id);
}
知识点:
1. 将字符串类型 转化成 日期(Date)类型
Date date = new SimpleDateFormat("yyyy-mm-dd").parse("String");
2. 将日期(Date)类型转化成 字符串类型
String a= new SimpleDateFormat("yyyy-mm-dd").format(new Date);
3. 获得复选框的值,使用 String[] str = request.getParameterValues("hobby")
4. 将数组里面的数据转成一个字符串,使用 Arrays 工具类
String str = Arrays.toString( str ); ===>[a,b,c]
去掉中括号: str = str.substring(开始位置, 结束位置);
5. 提交数据有中文乱码问题,post提交,request.setCharacterEncoding("utf-8")
<a href="add.jsp">添加a>
<h3>添加学生页面h3>
<form action="StudentAddServlet" method="post">
<table border="1" width="600">
......
<tr><td>性别td>
<td><input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女td>
tr>
........
<tr><td>爱好td><td>
<input type="checkbox" name="hobby" value="游泳">游泳
<input type="checkbox" name="hobby" value="敲代码">敲代码
.....td> tr>
<tr><td>简介td><td>
<textarea cols="20" rows="4" name="info">textarea> td>
tr>
<tr><td colspan="2"><input type="submit" value="添加">td>tr>
table>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理乱码,提交数据有中文,post提交
request.setCharacterEncoding("utf8");
try {
//1、获取页面提交过来的一个学生的数据,并封装成一个Student对象
Student stu = new Student();
stu.setSname(request.getParameter("sname"));
stu.setGender(request.getParameter("gender"));
stu.setPhone(request.getParameter("phone"));
stu.setInfo(request.getParameter("info"));
//将字符串转化成日期格式,因为Student类中的日期是Date类型
//判断,当不写东西的时候,不报错,为空
String birthday = request.getParameter("birthday");
if(birthday.isEmpty() || birthday==null){
stu.setBirthday(null);
}else {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = simpleDateFormat.parse(birthday);
stu.setBirthday(date);
}
//复选框是对个选项,gerParameter()只能获取第一个,用getParameterValues()
String[] hobbies = request.getParameterValues("hobby");
//Arrays数据操作的工具类
String hobby = Arrays.toString(hobbies);
//去掉 [ ] 号
hobby = hobby.substring(1, hobby.length() - 1);
stu.setHobby(hobby);
//2、将数据插入到数据库中
StudentService studentService = new StudentServiceImpl();
studentService.insert(stu);
//3、跳转页面,注意,这里不能直接跳转list.jsp,应高跳转到相应的StudentListServlet中,否则查不到数据,
//因为,之前的查的数据作用域是request,现在不是一个作用域中,查到的是空
//就算之后改了作用域,增大作用域,也只能是查到之前的数据,查不到插入后的数据库中的数据
//所以,只有重新再查一遍,才能看到新查入的数据
request.getRequestDispatcher("StudentListServlet").forward(request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**增加
* 将一个学生的所有信息插入到数据库中
* @param stu
*/
void insert(Student stu) throws SQLException;
@Override
public void insert(Student stu) throws SQLException {
StudentDao studentDao = new StudentDaoImpl();
studentDao.insert(stu);
}
/**增加
* 将一个学生的所有信息插入到数据库中
* @param stu
*/
void insert(Student stu) throws SQLException;
@Override
public void insert(Student stu) throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
queryRunner.update("insert into students values(null,?,?,?,?,?,?)",
stu.getSname(),
stu.getGender(),
stu.getPhone(),
stu.getBirthday(),
stu.getHobby(),
stu.getInfo()
);
}
知识点:
1. StudentEditServlet.java 使用getParameter()获取id要转化成Long 再转int
2. update.jsp中,要更新的学生的原来的信息要显示在页面上
单选按钮:是等于和不等一的关系,引入JSTL 标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
checked="checked">男
复选框按钮:是包含的关系,要引入
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
checked="checked">游泳
<a href="StudentEditServlet?id=${stu.sid}">更新a>
//1、获取id,知道要更新哪一个学生的信息
int id = (int)Long.parseLong(request.getParameter("id"));
//2、根据id查询这个学生的全部信息
StudentService studentService = new StudentServiceImpl();
Student student = studentService.findStudent(id);
//3、将查询的这个学生的信息保存在作用域中
request.setAttribute("stu",student);
//4、跳转页面,跳转到更新学生页面
request.getRequestDispatcher("update.jsp").forward(request,response);
<h3>这是更新学生页面h3>
<form action="StudentUpdateServlet" method="post">
<table border="1" width="600">
<tr>
<td colspan="2"><input type="hidden" name="id" value="${stu.sid}">td>
tr>
<tr>
<td>姓名td>
<td><input type="text" name="sname" value="${stu.sname}">td>
tr>
<tr>
<td>性别td>
<td>
<input type="radio" name="gender" value="男" if test="${stu.gender == '男'}">checked="checked"c:if>>男
<input type="radio" name="gender" value="女" if test="${stu.gender == '女'}">checked="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="date" name="birthday" value="${stu.birthday}">td>
tr>
<tr>
<td>爱好td>
<td>
<%--这是包含的关系,是否包含这一项--%>
<input type="checkbox" name="hobby" value="游泳" if test="${fn:contains(stu.hobby,'游泳')}">checked="checked"c:if>>游泳
<input type="checkbox" name="hobby" value="敲代码" if test="${fn:contains(stu.hobby,'敲代码')}">checked="checked"c:if>>敲代码
<input type="checkbox" name="hobby" value="打篮球" if test="${fn:contains(stu.hobby,'打篮球')}">checked="checked"c:if>>打篮球
<input type="checkbox" name="hobby" value="泡妹子" if test="${fn:contains(stu.hobby,'泡妹子')}">checked="checked"c:if>>泡妹子
<input type="checkbox" name="hobby" value="吃鸡" if test="${fn:contains(stu.hobby,'吃鸡')}">checked="checked"c:if>>吃鸡
td>
tr>
<tr>
<td>简介td>
<td>
<textarea cols="20" rows="4" name="info" >
${stu.info}
textarea>
td>
tr>
<tr>
<td colspan="2"><input type="submit" value="更新">td>
tr>
table>
form>
//提交的数据有中文,所以要处理乱码,是post请求,数据在请求体中,
request.setCharacterEncoding("utf8");
try {
//1、获取页面提交过来的一个学生的数据,并封装成一个Student对象
Student stu = new Student();
stu.setSid((int)Long.parseLong(request.getParameter("id")));
stu.setSname(request.getParameter("sname"));
stu.setGender(request.getParameter("gender"));
stu.setPhone(request.getParameter("phone"));
stu.setInfo(request.getParameter("info"));
//将字符串转化成日期格式,因为Student类中的日期是Date类型
//判断,当不写东西的时候,不报错,为空
String birthday = request.getParameter("birthday");
if(birthday.isEmpty() || birthday==null){
stu.setBirthday(null);
}else {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = simpleDateFormat.parse(birthday);
stu.setBirthday(date);
}
//复选框是对个选项,gerParameter()只能获取第一个,用getParameterValues()
String[] hobbies = request.getParameterValues("hobby");
//Arrays数据操作的工具类
String hobby = Arrays.toString(hobbies);
//去掉 [ ] 号
hobby = hobby.substring(1, hobby.length() - 1);
stu.setHobby(hobby);
//2、将数据更新到数据库中
StudentService studentService = new StudentServiceImpl();
studentService.update(stu);
//3、跳转页面,显示更新内容。注意,这里不能直接跳转list.jsp,应该跳转到相应的StudentListServlet中,否则查不到数据,
//因为,之前的查的数据作用域是request,现在不是一个作用域中,查到的是空
//就算之后改了作用域,增大作用域,也只能是查到之前的数据,查不到插入后的数据库中的更新的数据
//所以,只有重新再查一遍,才能看到新查入的数据
request.getRequestDispatcher("StudentListServlet").forward(request,response);
知识点:SQL语句 like 和正则表达式
1. 按姓名查询
select * from students where sname like '%like%';
2. 按性别查询
select * from students where gender = ?;
3. 按姓名and性别查询
select * from students where sname like '%like%' and gender = ?;
4. 什么都不选点击查询,查询所有
select * from students where 1=1 and sname like ? and gender = ?;
ArrayList aa = new ArrayList(); //存储占位符,就是存储问号
aa.add("%"+name+"%"); //第一个?
aa.add(gender); //第二个 ?
List list = queryRunner.query(sql, new BeanListHandler(Student.class),aa.toArray());
aa.toArray() 将集合中的数据转化成数组
<form action="StudentSearchServlet" method="post">
<table border="1" width="80%" align="center">
<tr>
<td colspan="8">
按姓名查询:<input type="text" name="name">
按性别查询:
<select name="gender" >
<option value="">--请选择--option>
<option value="男">男option>
<option value="女">女option>
select>
<input type="submit" value="查询">
<a href="add.jsp">添加a>
td>
tr>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//提交数据中有中文,post请求,所以要处理乱码问题
request.setCharacterEncoding("utf-8");
try {
//1、获取提交的数据 按姓名或者 按性别,或者两个条件
String name = request.getParameter("name");
String gender = request.getParameter("gender");
//2、根据提交的信息查询数据库,返回一个List 集合
StudentService studentService = new StudentServiceImpl();
List<Student> list = studentService.search(name, gender);
//3、将查询到的数据List保存在作用域中
request.setAttribute("list",list);
//4、跳转页面,注意,这地方要跳转到list.jsp了,因为根据id已经查出想要的数据,直接显示就行,替换原来的数据
request.getRequestDispatcher("list.jsp").forward(request,response);
} catch (SQLException e) {
e.printStackTrace();
}
}
在这里插入代码片
/**
* 模糊查询,搜索 使用 like 正则表达式
* @param name
* @param gender
* @throws SQLException
* @return List
*/
List<Student> search(String name,String gender) throws SQLException;
@Override
public List<Student> search(String name, String gender) throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
//判断情况,1、按姓/2、按性别 3、按姓名和性别、4全部为空,查询所有
//一个 ? 号,只占用一个字符,不能是多个
//第一种方法:不使用占位符
//第二种:使用占位符
String sql = "select * from students where 1 = 1";
ArrayList<String> aa = new ArrayList<String>(); //存储占位符,就是存储问号
if(!TextUtils.isEmpty(name)){
// sql = sql + " and sname like '%"+name+"%'";
sql = sql + " and sname like ?";
aa.add("%"+name+"%");
}
if (!TextUtils.isEmpty(gender)){
// sql = sql + " and gender = '"+gender+"'";
sql = sql + " and gender = ?";
aa.add(gender);
}
// List list = queryRunner.query(sql, new BeanListHandler(Student.class));
// aa.toArray() 将集合中的数据转化成数组
List<Student> list = queryRunner.query(sql, new BeanListHandler<Student>(Student.class),aa.toArray());
return list;
}
知识点:
1. 分页体现了业务逻辑层(service) 和 数据访问层(Dao层)的区别和联系
service: 包含多个逻辑
Dao:每个方法只能是一个逻辑,单一逻辑
2. (1)查询数据库显示当前页的所有学生的数据,---》对应dao层一个方法
(2)在页面显示所有的数据:包括
当前页currentPage---->当前页是手动从前端传入的1,之后根据1,进行+1下一页,点击某一页美酒传入你点击的数字
总页数totalPage,
当前页的记录数pageSize----->自己定义一页显示几条
总记录数:totalSize------>需要调用dao层一个方法,使用SQL语句 limit 5 offset (0,5,10...)
当前页所有学生的信息List ----> 对应dao层一个方法,根据当前页查询这一页的所有学生信息
-----> 这些数据封装成一个对象PageBean中,然后再页面显示出来
3. 在查询语句中,使用JDBCUtilsjar包, sql语句 select count(*) from students
这地方使用new CalarHandler() 实现类,主要用于sql语句的求平均数,最大值。总数等
返回的数据用Long类型接收才可以收,不能用int类型
Long along = (Long) queryRunner.query("select count(*) from students", new ScalarHandler());
int i = along.intValue(); 将Long类型转化成int类型
4. 当前页所有学生的信息List ----> 对应dao层一个方法,根据当前页查询这一页的所有学生信息
这个地方,根据当前页数,查询当前页上的所有学生,需要自己找规律
一页5条数据,怎么设置 limit 5 offset 0...
--------->limit 5 offset (当前页 - 1) * 5
5. 首页 | 上一页 :在第一页不显示
尾页 | 下一页 :在最后一页不显示
在当前页时候,该页不是超链接
----> 在list_page.jsp 显示页面中,实现这些功能
6. 在第一页时候,手动输入一个参数是当前页currentPage=1
分页显示所有学生列表
<h3><a href="StudentListPageServlet?currentPage=1">分页显示所有学生列表a>h3>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1、获取当前页
int currentPage = Integer.parseInt(request.getParameter("currentPage")) ;
//2、查询数据库,获取数据
StudentService studentService = new StudentServiceImpl();
PageBean pageBean = studentService.fenye(currentPage);
//3、将数据存储到作用域中
request.setAttribute("pageBean",pageBean);
//4、跳转页面
request.getRequestDispatcher("list_page.jsp").forward(request,response);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 这是分页的业务,体现了service层(业务逻辑层) 和Dao层(数据访问层)的区别
* @param currentPage 当前页
* @return PageBean所有信息 封装了分页的
*/
PageBean fenye(int currentPage) throws SQLException;
@Override
public PageBean fenye(int currentPage) throws SQLException {
StudentDao studentDao = new StudentDaoImpl();
//获得当前页学生的信息
List<Student> list = studentDao.findCurrentPage(currentPage);
//获得当前页的记录数
int pageSize = ((StudentDaoImpl) studentDao).pageSize;
//获得总记录数
int totalSize = studentDao.count();
//总页数:根据总记录数 和当前页的记录数得到总页数
int totalPage = totalSize/pageSize;
totalPage = (totalSize%pageSize) == 0 ? totalPage : totalPage+1;
//封装数据,并返回
PageBean pageBean = new PageBean(currentPage,totalPage,pageSize,totalSize,list);
return pageBean;
}
/**
* 查询当前页上的所有学生的信息
* @param currentPage 当前页
* @return List 当前页的所有学生
*/
List<Student> findCurrentPage(int currentPage) throws SQLException;
/**
* 查询数据库,使用count() 方法,返回总记录数
* @return 返回总记录数
*/
int count() throws SQLException;
public final int pageSize = 5; //当前页的记录数,这个是固定的
@Override
public List<Student> findCurrentPage(int currentPage) throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
List<Student> list = queryRunner.query("select * from students limit ? offset ?", new BeanListHandler<Student>(Student.class), pageSize, (currentPage - 1) * pageSize);
return list;
}
@Override
public int count() throws SQLException {
DataSource dataSource = JDBCUtil02.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
//这地方使用scalarHandler实现类,主要用于sql语句的求平均数,最大值。总数等
//返回的数据用Long类型接收才可以收,不能用int类型
Long along = (Long) queryRunner.query("select count(*) from students", new ScalarHandler());
int i = along.intValue();
return i;
}
<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.totalPage}">[尾页]a> |
<a href="StudentListPageServlet?currentPage=${pageBean.currentPage+1}">下一页a>
c:if>
td>
tr>