用户列表查询功能
实现步骤
- 编写userListServlet
- 调用service层的findAll()方法,返回list集合
- 将list集合存到request域对象中
- 转发到list.jsp页面展示
- 编写service(接口+实现类)
- 编写dao(接口+实现类)
- 编写jsp(遍历数据并展示)
登录功能
实现步骤
显示验证码
- 调整页面,加入验证码
- 添加点击事件,实现点击切换验证码
- 给表单添加name属性,并在数据库中添加username和password的字段
实现登录功能
- 给javaBean添加两个属性username和password,并且生成set,get,toString()方法
- 创建LoginServlet,获取验证码并校验
- 获取表单提交的数据,封装成user对象
- 编写并调用service的isLogin方法查询
- 根据返回的结果来判断是否登录成功
- 登录成功,跳转到首页
- 登录失败,转发到登录页
添加功能
实现步骤
- 修改添加按钮跳转的地址为add.jsp页面,并修改add.jsp表单项的name属性
- 创建AddUserServlet
- 获取表单提交的数据,封装成user对象
- 编写并调用service的addUser方法保存
- 跳转到userListServlet,再次查询

删除功能
实现步骤
- 在list.jsp页面中为删除按钮绑定当前用户的id
- 创建DeleteUserByIdServlet
- 获取提交过来的id
- 编写并调用service的removeUserById方法来删除
- 跳转到userListServlet,再次查询
改进
点击删除按钮删除的时候,不是直接跳转,而是弹出确认框,待用户确认之后再跳转
注意
点击删除按钮的时候通过参数的形式将要删除的id传递到js代码里面
调用dao的deleteUserById方法的时候,把id转成int类型

修改功能
实现步骤
用户信息的回显
将修改按钮的跳转的地址改为FindUserByIdServlet,并绑定当前用户的id
创建findUserByIdServlet
获取提交过来的id
编写并调用service的findUserById方法查询
将查到的user存入request中,转发到update.jsp
在update.jsp通过EL表达式取出user中存的数据并展示
用jstl的if标签根据user的gender和address的值显示不同的性别和籍贯
<input type="radio" name="gender" value="男" ${user.gender == "男" ? "checked" :""}>男 <input type="radio" name="gender" value="女" ${user.gender == "女" ? "checked" :""}>女 <option value="陕西" ${user.address == "陕西" ? "selected" : ""}>陕西</option> <option value="北京" ${user.address == "北京" ? "selected" : ""}>北京</option> <option value="上海" ${user.address == "上海" ? "selected" : ""}>上海</option>
用户信息的修改
为表单添加隐藏域,用于提交id
提交表单到UpdateUserByIdServlet
获取表单提交的数据封装到user对象中
编写并调用service的updateUser方法修改
跳转到userListServlet,再次查询
注意:
修改的时候,sql语句里面的?要和要修改的属性一一对应

删除选中功能
实现步骤
前台代码
获取选中的条目的id
- 创建一个表单,把table包裹起来
- 给复选框添加name属性,第一个复选框不需要添加
- 给删除选中按钮绑定单击事件
- 给复选框添加value属性,并在单击事件中测试,能否提交过去
后台代码
- 创建DelSelectedUserByIdsServlet
- 获取提交过来的ids的数组
- 编写并调用service的removeUsersByIds方法,在方法里面遍历数组,并调用dao来删除
- 跳转到userListServlet,再次查询
细节
- 为第一个复选框添加点击事件,实现全选和全不选
- 在表单提交之前,弹出确认框,防止误删
- 在用户点击确认之后,判断是否有选中的条目,如果有的话才提交表单

分页查询功能
实现步骤
浏览器需要哪些数据才能展示分页
| 含义 | 属性 | 实现 |
|---|---|---|
| 总记录数 | totalCount | 服务器就可以通过聚合函数查询得到 |
| 总页数 | totalPage | 服务器可以通过计算得到 |
| 每页的数据 | list | 服务器就可以通过分页查询得到 |
| 当前的页 | currentPage | 浏览器传给服务器的,服务器再原封不动的传给它 |
| 每页显示的记录数 | rows | 浏览器传给服务器的,服务器再原封不动的传给它 |
服务器会将这些数据打包到pageBean中,保存到域对象中,然后转发给浏览器
服务器需要哪些数据才能实现分页查询
select * from user limit 起始索引,每页的条数
浏览器会将这两样东西,拼接到url后面,传给服务器
http://localhost:8080/PageServlet?currentPage=1&rows=5
后台代码编写步骤
创建PageBean实体类,添加所需的属性
创建FindUserByPageServlet(处理分页请求的servlet)
在index.jsp中修改访问路径,传递currentPage和rows给服务器
在FindUserByPageServlet就可以获取currentPage(当前的页码)和rows(每页显示的记录数)
编写并调用Service的findUserByPage方法去查询,返回一个PageBean对象
- 创建一个空的PageBean对象
- 设置currentPage属性的值和rows属性的值
- 设置totalCount属性的值(用dao查询总记录数)
- 设置totalPage属性的值(用总记录数和每页显示的记录数计算得到)
- 设置list属性的值(调用dao进行分页查询得到[传入起始的索引和每页显示的记录数])
- 返回设置好的PageBean对象
将返回的PageBean对象存到request域对象中
转发到list.jsp
前台代码编写步骤
修改表格中数据的来源
${pb.list}修改总记录数和总页码数
共${pb.totalCount}条记录,共${pb.totalPage}页遍历显示分页条
<c:forEach begin="1" end="${pb.totalPage}" var="i"> <li><a href="#">${i}</a></li> </c:forEach>给分页条添加点击效果
<li><a href="${pageContext.request.contextPath}/FindUserByPageServlet?currentPage=${i}&rows=3">${i}</a></li>实现高亮效果
<li ${pb.currentPage == i ? "class='active'" : ""}><a href="${pageContext.request.contextPath}/FindUserByPageServlet?currentPage=${i}&rows=3">${i}</a></li>


复杂查询
实现步骤
给list.jsp添加查询的表单
在FindUserByPageServlet获取添加查询的参数condition
Map<String, String[]> condition = request.getParameterMap();先将条件查询的参数condition传递到service层
PageBean<User> pb = service.findUserByPage(currentPage,rows,condition);再将条件查询的参数condition传递到dao层
int totalCount = userDao.findTotalCount(condition); List<User> list = userDao.findByPage(start,rows,condition);在dao层中重新实现查询总记录数(动态的拼接sql语句)
- 定义模板初始化sql
- 遍历map集合(condition)
- 动态拼接sql语句
- 动态拼接参数
- 查询
在dao层中重新实现分页查询(动态的拼接sql语句)
//还需要拼接分页的limit关键字
//还需要拼接分页查询的参数值注意:一定不要忘记处理请求的中文乱码问题

目录结构


数据准备




实现代码
CheckCodeServlet
@WebServlet("/checkCodeServlet") public class CheckCodeServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 100; int height = 50; //1.创建一对象,在内存中图片(验证码图片对象) BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //2.美化图片 //2.1 填充背景色 Graphics g = image.getGraphics();//画笔对象 g.setColor(Color.PINK);//设置画笔颜色 g.fillRect(0,0,width,height); //2.2画边框 g.setColor(Color.BLUE); g.drawRect(0,0,width - 1,height - 1); String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789"; //生成随机角标 Random ran = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= 4; i++) { int index = ran.nextInt(str.length()); //获取字符 char ch = str.charAt(index);//随机字符 sb.append(ch); //2.3写验证码 g.drawString(ch+"",width/5*i,height/2); } String checkCode_session = sb.toString(); //将验证码存入session request.getSession().setAttribute("checkCode_session",checkCode_session); //2.4画干扰线 g.setColor(Color.GREEN); //随机生成坐标点 for (int i = 0; i < 10; i++) { int x1 = ran.nextInt(width); int x2 = ran.nextInt(width); int y1 = ran.nextInt(height); int y2 = ran.nextInt(height); g.drawLine(x1,y1,x2,y2); } //3.将图片输出到页面展示 ImageIO.write(image,"jpg",response.getOutputStream()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }LoginServlet
/** * @作者 yg * @时间 2020/3/18 21:40 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 先校验验证码,后在去校验用户名和密码 // 设置请求对象的编码,若不设置表单提交的过来的数据会成乱码 request.setCharacterEncoding("utf-8"); // 获取请求参数 // 获取表单提交过来的验证码 String verifycode = request.getParameter("verifycode"); // 从session域对象中获取工具类生成的验证码 // 获取session域对象 HttpSession session = request.getSession(); // 取出session域中的验证码 String code_session = (String) session.getAttribute("checkCode_session"); // 确保session域中验证码的唯一性,将session域中原来的验证码给移除 session.removeAttribute(code_session); if(!code_session.equalsIgnoreCase(verifycode) || code_session == null || verifycode == null ){ // 表名验证码输入错误 // 将错误信息存进request作用域中 request.setAttribute("error_msg", "您输入的验证码错误"); // 请求转发到登录login.jsp页面 request.getRequestDispatcher("/login.jsp").forward(request,response); // 结束方法,下来的代码不会被执行 return; } // 获取请求参数 Map<String, String[]> mapValue = request.getParameterMap(); // 将map集合对象中的数据封装到admin对象中,并返回该admin对象 Admin admin = JDBCUtils.mapToBean(Admin.class,mapValue); // 创建service层对象 IAdminService adminService = new AdminServiceImpl(); // 调用service层的方法 if(adminService.isLogin(admin)) { // 表示用户名和密码正确 // 将admin对象存进session域对象中 session.setAttribute("admin", admin); // 重定向到index.jsp页面 response.sendRedirect(request.getContextPath() + "/index.jsp"); } else { // 表示用户名或者密码错误 // 将错误信息存进request域对象中 request.setAttribute("error_msg", "用户名或者密码错误"); // 请求转发到login.jsp页面 request.getRequestDispatcher("/login.jsp").forward(request,response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }AddUserServlet
@WebServlet("/addUserServlet") public class AddUserServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置请求对象的编码问题,若不设置则表单提交过来的数据会出现乱码 request.setCharacterEncoding("utf-8"); // 获取请求参数 Map<String, String[]> mapValue = request.getParameterMap(); // 将map集合中的数据封装到user对象中,并返回该对象 User user = JDBCUtils.mapToBean(User.class, mapValue); // 创建service层的对象 IUserService userService = new UserServiceImpl(); // 调用service层的方法 userService.addUser(user); // 重定向到查询所有用户的那个servlet中去 // response.sendRedirect(request.getContextPath() + "/userListServlet"); response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }DeleteUserByIdServlet
/** * @作者 yg * @时间 2020/3/18 23:58 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/deleteUserByIdServlet") public class DeleteUserByIdServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求参数id String id = request.getParameter("id"); // 创建service层对象 IUserService userService = new UserServiceImpl(); // 调用service层的方法 userService.removeUserById(Integer.parseInt(id)); // 重定向到查询所有用户信息的servlet中去 // response.sendRedirect(request.getContextPath() + "/userListServlet"); response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }DelSelectedUserByIdsServlet
/** * @作者 yg * @时间 2020/3/18 22:56 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/delSelectedUserByIdsServlet") public class DelSelectedUserByIdsServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求参数 String[] ids = request.getParameterValues("id"); if(ids != null && ids.length != 0) { // 创建session层对象 IUserService userService = new UserServiceImpl(); // 调用service层方法 userService.removeUsersByIds(ids); // 重定向到查询所有用户的那个servlet中去 // response.sendRedirect(request.getContextPath() + "/userListServlet"); response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); } else { throw new NullPointerException("您未勾选中任何一个用户"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }FindUserByIdServlet
/** * @作者 yg * @时间 2020/3/18 23:29 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/findUserByIdServlet") public class FindUserByIdServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求参数 String id = request.getParameter("id"); // 创建service层对象 IUserService userService = new UserServiceImpl(); // 调用service层的方法 User user = userService.findUserById(id); // 将user对象存入request作用域对象中 request.setAttribute("user",user); // 请求转发到update.jsp页面,实现数据的回显 request.getRequestDispatcher("/update.jsp").forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }FindUserByPageServlet
/** * @作者 yg * @时间 2020/3/19 0:14 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/findUserByPageServlet") public class FindUserByPageServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决请求对象的乱码问题 request.setCharacterEncoding("utf-8"); // 获取请求参数,作为复杂查询的condition Map<String, String[]> condition = request.getParameterMap(); // 获取请求参数 String currentPage = request.getParameter("currentPage"); String rows = request.getParameter("rows"); if(currentPage == null || "".equals(currentPage)) { currentPage = "1"; } if(rows == null || "".equals(rows)) { rows = "3"; } // 创建userService层的对象 IUserService userService = new UserServiceImpl(); // 调用service层的方法,返回一个page PageBean<User> pageBean = userService.findUserPage(Integer.parseInt(currentPage),Integer.parseInt(rows),condition); // 将pageBean对象存入request域对象中 request.setAttribute("pageBean",pageBean); // 请求转发到list.jsp页面 request.getRequestDispatcher("/list.jsp").forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }UpdateUserByIdServlet
/** * @作者 yg * @时间 2020/3/18 23:40 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @WebServlet("/updateUserByIdServlet") public class UpdateUserByIdServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置请求对象的乱码问题,若表单提交过来的数据有中文则需要设置编码,否则会乱码 request.setCharacterEncoding("utf-8"); // 获取请求参数,即表单提交过来的数据 Map<String, String[]> mapValue = request.getParameterMap(); // 将map集合中的数据封装到user对象中,并返回该user对象 User user = JDBCUtils.mapToBean(User.class, mapValue); // 创建service层对象 IUserService userService = new UserServiceImpl(); // 调用service层的方法 userService.putUserById(user); // 重定向到查看所有用户信息的那个servlet中去 response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); // response.sendRedirect(request.getContextPath() + "/userListServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }UserListServlet
@WebServlet("/userListServlet") public class UserListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 创建service层对象 IUserService userService = new UserServiceImpl(); // 调用service层方法 List<User> userList = userService.findAll(); // 将该集合对象存进request作用域中 request.setAttribute("userList", userList); // 请求转发到list.jsp页面 request.getRequestDispatcher("/list.jsp").forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }JDBCUtils
/** * JDBC工具类 使用Durid连接池 */ public class JDBCUtils { private static DataSource ds ; static { try { //1.加载配置文件 Properties pro = new Properties(); //使用ClassLoader加载配置文件,获取字节输入流 InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); //2.初始化连接池对象 ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接池对象 */ public static DataSource getDataSource(){ return ds; } /** * 获取连接Connection对象 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } public static <T> T mapToBean(Class<T> t, Map mapValue) { // 变量提升 T obj = null; try { // 在程序运行过程中动态获取类的字节码对象,通过该对象去创建对象 obj = t.newInstance(); // map集合对象中的数据封装到JavaBean对象中 BeanUtils.populate(obj,mapValue); } catch (Exception e) { e.printStackTrace(); return obj; } return obj; } }AdminServiceImpl
/** * @作者 yg * @时间 2020/3/18 22:04 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public class AdminServiceImpl implements IAdminService { // 创建dao层对象 private IAdminDao adminDao = new AdminDaoImpl(); @Override public boolean isLogin(Admin admin) { return adminDao.queryAdminByUsernameAndPwd(admin) != null ? true : false; } }IAdminService
/** * @作者 yg * @时间 2020/3/18 22:04 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public interface IAdminService { boolean isLogin(Admin admin); }IUserService
/** * @作者 yg * @时间 2020/3/18 21:22 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public interface IUserService { List<User> findAll(); void addUser(User user); void removeUsersByIds(String[] ids); User findUserById(String id); void putUserById(User user); void removeUserById(int id); PageBean<User> findUserPage(int currentPage, int rows, Map<String, String[]> condition); }UserServiceImpl
/** * @作者 yg * @时间 2020/3/18 21:22 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public class UserServiceImpl implements IUserService { // 创建dao层对象 private IUserDao userDao = new UserDaoImpl(); @Override public List<User> findAll() { return userDao.queryAll(); } @Override public void addUser(User user) { userDao.insertUser(user); } @Override public void removeUsersByIds(String[] ids) { // 遍历数组,得到每一个元素id for (String id : ids) { // 调用dao层方法 userDao.deleteUserById(Integer.parseInt(id)); } } @Override public User findUserById(String id) { return userDao.queryUserById(Integer.parseInt(id)); } @Override public void putUserById(User user) { userDao.updateUserById(user); } @Override public void removeUserById(int id) { // 复用dao层方法 userDao.deleteUserById(id); } @Override public PageBean<User> findUserPage(int currentPage, int rows, Map<String, String[]> condition) { // 防止点击上一页不存在报错,判断若current <= 0时,就将currentPage重新赋值为1 if(currentPage <= 0) { currentPage = 1; } // 采用空参构造器创建PageBean对象 PageBean<User> pageBean = new PageBean<>(); // 给该对象的currentPage属性赋值 currentPage : 当前页码 pageBean.setCurrentPage(currentPage); // 给该对象的rows属性赋值 rows 查看的记录数(当前页码所展示的记录数) pageBean.setRows(rows); // 给该对象的totalCount属性赋值 totalCount:表示总记录数 (使用聚合函数count来实现) int totalCount = userDao.findTotalCount(condition); pageBean.setTotalCount(totalCount); // 给该对象的totalPage属性赋值 totalPage:表示总页码 (使用向上取整来实现) // 方式一:totalCount % rows == 0 ? totalCount / rows : totalCount / rows +1 // 方式二:(int)Math.ceil(totalCount * 1.0 / rows) 注意:不要少了*1.0 因为两整数相除得到还是一个整数,若想要小数必须有浮点数参与运算 int totalPage = (int) Math.ceil(totalCount * 1.0 / rows); pageBean.setTotalPage(totalPage); // 给该对象的list属性赋值 list: 数据载体 , 数据列表 // 设置limit分页查询的第一个参数 开始索引 = (当前页码 - 1) * 查看的记录数 int startIndex = (currentPage - 1) * rows; List<User> userList = userDao.queryUserByPage(startIndex,rows,condition); pageBean.setList(userList); // 返回一个完整的PageBean对象 return pageBean; } }User
public class User { private int id; private String name; private String gender; private int age; private String address; private String qq; private String email; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", age=" + age + ", address='" + address + '\'' + ", qq='" + qq + '\'' + ", email='" + email + '\'' + '}'; } }PageBean
/** * @作者 yg * @时间 2020/3/19 0:08 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public class PageBean<T> { /** * 总页码 */ private int totalPage; /** * 总记录数 */ private int totalCount; /** * 数据载体 */ private List<T> list; /** * 当前页码 */ private int currentPage; /** * 查看的记录数 */ private int rows; @Override public String toString() { return "PageBean{" + "totalPage=" + totalPage + ", totalCount=" + totalCount + ", list=" + list + ", currentPage=" + currentPage + ", rows=" + rows + '}'; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } }Admin
public class Admin { /** * 用户编号 */ private int id ; /** * 用户名 */ private String username ; /** * 密码 */ private String password ; @Override public String toString() { return "Admin{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }IUserDao
/** * @作者 yg * @时间 2020/3/18 21:29 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public interface IUserDao { List<User> queryAll(); void insertUser(User user); void deleteUserById(int id); User queryUserById(int id); void updateUserById(User user); int findTotalCount(Map<String, String[]> condition); List<User> queryUserByPage(int startIndex, int rows, Map<String, String[]> condition); }IAdminDao
/** * @作者 yg * @时间 2020/3/18 22:08 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public interface IAdminDao { Admin queryAdminByUsernameAndPwd(Admin admin); }UserDaoImpl
/** * @作者 yg * @时间 2020/3/18 21:29 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ @SuppressWarnings("all") // 压制重复代码的警告 public class UserDaoImpl implements IUserDao { private JdbcTemplate jtl = new JdbcTemplate(JDBCUtils.getDataSource()); @Override public List<User> queryAll() { // 定义DQL语句 String dql = "select * from user"; // 执行sql并处理结果 return jtl.query(dql, new BeanPropertyRowMapper<User>(User.class)); } @Override public void insertUser(User user) { // name | gender | age | address | qq | email // 定义DML语句 String dml = "insert into user values(null,?,?,?,?,?,?)"; // 执行sql jtl.update(dml, user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail()); } @Override public void deleteUserById(int id) { // 定义DML语句 String dml = "delete from user where id = ?"; // 执行DML语句 jtl.update(dml,id); } @Override public User queryUserById(int id) { // 定义DQL语句 String dql = "select * from user where id = ?"; // 执行DQL语句,处理结果 return jtl.queryForObject(dql, new BeanPropertyRowMapper<User>(User.class),id); } @Override public void updateUserById(User user) { // name | gender | age | address | qq | email // 定义DML语句 String dml = "update user set name = ? ,gender = ? ,age = ?,address = ?,qq = ? ,email = ? where id = ?"; // 执行sql jtl.update(dml, user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail(),user.getId()); } @Override public int findTotalCount(Map<String, String[]> condition) { // // 定义DQL语句 // String sql = "select count(id) from user"; String sql = "select count(*) from user"; // // 执行sql语句,处理结果 // return jtl.queryForObject(sql, Integer.class); // 定义一个恒成立的sql语句模板 'a' ='a' 1 = 1 都可以的 String sqlTemplate = "select count(id) from user where 'a' = 'a' "; // 注:这里必须要有一个空格 // 创建StringBuilder对象,用来动态拼接sql语句 StringBuilder sb = new StringBuilder(sqlTemplate); // 创建List集合对象,该集合对象可存储任意类型的数据 List param = new ArrayList(); // 遍历map集合 for (String key : condition.keySet()) { // 通过键获取值 String value = condition.get(key)[0]; // 输出键值对对象 System.out.println(key + "=" + value); // 若键key中有名为currentPage或者rows的键则直接跳过本次循环,继续执行下一次循环 // 因为currentPage和rows都是固定值,我们无需做任何操作,所以这里直接跳过这两次循环继续执行下面的内容即可 // currentPage和rows在查询总记录上也排不上用场,直接跳过即可 if("currentPage".equals(key) || "rows".equals(key)) continue; // 若value值不为空串并且不为null,就执行if语句体里的内容 // 校验用户在文本框是否有输入内容,若输入了内容则value肯定就不为null也不为"" , 这步校验至关重要不可省略 // 若用户没输入内容那就没必要再去拼接了 if(!"".equals(value) && value != null) { // 动态拼接sql,组成模糊查询 sb.append(" and "+key+" like ? "); // 将like后面的匹配条件封装到list集合对象中 param.add("%"+value+"%"); } } // 将StringBuilder对象转换为String // 这个最终的动态生成的sql才是我们要的sql语句 String realSql = sb.toString(); System.out.println(realSql); // 输出集合对象 System.out.println(param); // 执行动态拼接好的sql,处理结果 // 这里的结果需要一个int,这里可自动拆箱Integer-->int // param.toArray() ,就相当于将数组的每个元素依次拿出来对动态sql语句中的每个sql依次赋值 return jtl.queryForObject(realSql,Integer.class,param.toArray()); } @Override public List<User> queryUserByPage(int startIndex, int rows, Map<String, String[]> condition) { // // 定义DQL语句 // String dql = "select * from user limit ?,?"; // // 执行DQL语句处理结果 // return jtl.query(dql, new BeanPropertyRowMapper<User>(User.class), startIndex,rows); // 定义一个恒成立的sql语句模板 'a' ='a' 1 = 1 都可以的 String sqlTemplate = "select * from user where 'a' = 'a' "; // 注:这里必须要有一个空格 // 创建StringBuilder对象,用来动态拼接sql语句 StringBuilder sb = new StringBuilder(sqlTemplate); // 创建List集合对象,该集合对象可存储任意类型的数据 List param = new ArrayList(); // 遍历map集合 for (String key : condition.keySet()) { // 通过键获取值 String value = condition.get(key)[0]; // 输出键值对对象 System.out.println(key + "=" + value); // 若键key中有名为currentPage或者rows的键则直接跳过本次循环,继续执行下一次循环 // 因为currentPage和rows都是固定值,我们无需做任何操作,所以这里直接跳过这两次循环继续执行下面的内容即可 // currentPage和rows在查询总记录上也排不上用场,在servlet中这些东西已经提前处理好了,直接跳过即可 if("currentPage".equals(key) || "rows".equals(key)) continue; // 若value值不为空串并且不为null,就执行if语句体里的内容 // 校验用户在文本框是否有输入内容,若输入了内容则value肯定就不为null也不为"" , 这步校验至关重要不可省略 // 若用户没输入内容那就没必要再去拼接了 if(!"".equals(value) && value != null) { // 动态拼接sql,组成模糊查询 sb.append(" and "+key+" like ? "); // 将like后面的匹配条件封装到list集合对象中 param.add("%"+value+"%"); } } // 动态拼接分页查询语句的关键语句limit ?,? // 注意:这里代码的编写应该考虑代码的执行顺序,这行代码必须上面代码执行完后才能去执行到这里 // 正确的是 select * from user where 'a' = 'a' and name = ? limit ?,? // 错误的是 select * from user where 'a' = 'a' limit ?,? and name =? sb.append(" limit ? ,?"); // 将StringBuilder对象转换为String // 这个最终的动态生成的sql才是我们要的sql语句 String realSql = sb.toString(); System.out.println(realSql); param.add(startIndex); param.add(rows); // 输出集合对象 System.out.println(param); // 执行动态拼接好的sql,处理结果 // 这里的结果需要一个int,这里可自动拆箱Integer-->int return jtl.query(realSql,new BeanPropertyRowMapper<User>(User.class),param.toArray()); } }AdminDaoImpl
/** * @作者 yg * @时间 2020/3/18 22:08 * @微信公众号 Java Keep Studying * @CSDN博客 https://blog.csdn.net/qq_41473905 * @Hexo博客 https://mysunshine2019.github.io/ */ public class AdminDaoImpl implements IAdminDao { // 创建Spring的模板对象JdbcTemplate对象 private JdbcTemplate jtl = new JdbcTemplate(JDBCUtils.getDataSource()); @Override public Admin queryAdminByUsernameAndPwd(Admin admin) { // 定义DQL语句 String dql = "select * from admin where username = ? and password = ?"; // 执行sql语句处理结果 // 注意可能查询不到记录,会抛出一个异常,我们不让它抛出,我们手动进行处理 try{ return jtl.queryForObject(dql, new BeanPropertyRowMapper<Admin>(Admin.class),admin.getUsername(),admin.getPassword()); }catch (Exception ex) { return null; } } }druid.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///db9 username=root password=root # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <meta charset="utf-8"> <!-- 使用Edge最新的浏览器的渲染方式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。 width: 默认宽度与设备的宽度相同 initial-scale: 初始的缩放比,为1:1 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>添加用户</title> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container"> <center><h3>添加联系人页面</h3></center> <form action="${pageContext.request.contextPath}/addUserServlet" method="post"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label>性别:</label> <input type="radio" name="gender" value="男" checked="checked"/>男 <input type="radio" name="gender" value="女"/>女 </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄"> </div> <div class="form-group"> <label>籍贯:</label> <select name="address" class="form-control"> <option value="广东">广东</option> <option value="广西">广西</option> <option value="湖南">湖南</option> </select> </div> <div class="form-group"> <label for="qq">QQ:</label> <input type="text" class="form-control" id="qq" name="qq" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" id="email" name="email" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回" /> </div> </form> </div> </body> </html>index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>首页</title> <script> function weok() { } </script> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="js/bootstrap.min.js"></script> <script type="text/javascript"> </script> </head> <body> <div>${sessionScope.admin.username},欢迎回来</div> <div align="center"> <%-- href="${pageContext.request.contextPath}/userListServlet" --%> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=1&rows=3" style="text-decoration:none;font-size:33px">查询所有用户信息 </a> </div> </body> </html>list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <meta charset="utf-8"> <!-- 使用Edge最新的浏览器的渲染方式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。 width: 默认宽度与设备的宽度相同 initial-scale: 初始的缩放比,为1:1 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>用户信息管理系统</title> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="js/bootstrap.min.js"></script> <style type="text/css"> td, th { text-align: center; } </style> <script> // 定义一个函数,实现跳转到根据id删除用户的servlet资源 function deleteUserById(id) { // 判断是否要删除 if(confirm("确定删除吗?")) { // true // 获取到location对象,设置其href的属性值,完成访问servlet资源实现根据id删除用户信息 window.location.href = "${pageContext.request.contextPath}/deleteUserByIdServlet?id="+id; } } // 等页面加载完后再去获取元素标签对象 window.onload = function () { // 获取到"删除选中用户"该元素标签对象并绑定点击事件 document.getElementById("delSelectedUser").onclick = function () { // 判断是否需要删除选中的id对应的用户对象 if(confirm("您确定要删除吗?")) { // 获取到表单元素对象,并调用该元素对象的submit方法 ,注意 : 这里不是onsubmit属性 document.getElementById("form").submit(); } } } </script> </head> <body> <div class="container"> <h3 style="text-align: center">用户信息列表</h3> <div style="float:left"> <form class="form-inline" action="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=1&rows=3" method="post"> <div class="form-group"> <label for="name">姓名</label> <input type="text" class="form-control" id="name" name="name"> </div> <div class="form-group"> <label for="address">籍贯</label> <input type="text" class="form-control" id="address" name="address"> </div> <div class="form-group"> <label for="email">邮箱</label> <input type="text" class="form-control" id="email" name="email"> </div> <button type="submit" class="btn btn-default">查询</button> </form> </div> <div style="float:right"> <a href="${pageContext.request.contextPath}/add.jsp" class="btn btn-primary">添加用户</a> <a class="btn btn-primary" href="javascript:void(0);" id="delSelectedUser">删除选中用户</a> </div> <form action="${pageContext.request.contextPath}/delSelectedUserByIdsServlet" method="post" id="form"> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <c:if test="${not empty pageBean.list}"> <c:forEach var="user" items="${pageBean.list}" varStatus="flag" > <tr> <td><input type="checkbox" name="id" value="${user.id}"></td> <td>${flag.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default" href="${pageContext.request.contextPath}/findUserByIdServlet?id=${user.id}">修改</a>   <a class="btn btn-default" href="javascript:deleteUserById(${user.id})">删除</a> </td> </tr> </c:forEach> </c:if> </table> </form> <div> <nav aria-label="Page navigation"> <ul class="pagination"> <li class=${pageBean.currentPage <= 1 ? "disabled":""}> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage - 1}&rows=3" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <c:forEach var="i" begin="1" end="${pageBean.totalPage}"> <li ${pageBean.currentPage == i ? "class='active'" : ""}> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${id}&rows=3">${i}</a> </li> </c:forEach> <li> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage + 1}&rows=3" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <span style="font-size: 25px;margin-left: 5px;"> 共${pageBean.totalCount}条记录,共${pageBean.totalPage}页 </span> </ul> </nav> </div> </div> </body> </html>login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="zh-CN"> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>管理员登录</title> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="js/bootstrap.min.js"></script> <script type="text/javascript"> var refreshCode = function () { // 获取到验证码图片那个元素标签对象 var vcode = document.getElementById("vcode"); // 修改其对象的src属性值,实现更换图片的功能 vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time="+new Date().getTime(); } </script> </head> <body> <div class="container" style="width: 400px;"> <h3 style="text-align: center;">管理员登录</h3> <form action="${pageContext.request.contextPath}/loginServlet" method="post"> <div class="form-group"> <label for="username">用户名:</label> <input type="text" name="username" class="form-control" id="username" placeholder="请输入用户名"/> </div> <div class="form-group"> <label for="password">密码:</label> <input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/> </div> <div class="form-inline"> <label for="verifycode">验证码:</label> <input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/> <a href="javascript:refreshCode()"><img src="${pageContext.request.contextPath}/checkCodeServlet" title="看不清点击刷新" id="vcode"/></a> </div> <hr/> <div class="form-group" style="text-align: center;"> <input class="btn btn btn-primary" type="submit" value="登录"> </div> </form> <!-- 出错显示的信息框 --> <div class="alert alert-warning alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" > <span>×</span></button> <strong>${error_msg}</strong> </div> </div> </body> </html>update.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>修改用户</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-2.1.0.min.js"></script> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container" style="width: 400px;"> <h3 style="text-align: center;">修改联系人</h3> <form action="${pageContext.request.contextPath}/updateUserByIdServlet" method="post"> <input type="hidden" name="id" value="${user.id}" > <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" value="${user.name}" readonly="readonly" placeholder="请输入姓名" /> </div> <div class="form-group"> <label>性别:</label> <input type="radio" name="gender" value="男" ${user.gender eq "男" ? "checked":""} />男 <input type="radio" name="gender" value="女" ${user.gender eq "女" ? "checked":""} />女 </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" class="form-control" id="age" name="age" value="${user.age}" placeholder="请输入年龄" /> </div> <div class="form-group"> <label>籍贯:</label> <select name="address" class="form-control" > <option value="广东" ${user.address eq "广东" ? "selected":""}>广东</option> <option value="广西" ${user.address eq "广西" ? "selected":""}>广西</option> <option value="湖南" ${user.address eq "湖南" ? "selected":""}>湖南</option> </select> </div> <div class="form-group"> <label for="qq">QQ:</label> <input type="text" class="form-control" id="qq" value="${user.qq}" name="qq" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" value="${user.email}" id="email" name="email" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回"/> </div> </form> </div> </body> </html>关注公众号,更多精彩等着你…
