目录
项目介绍
数据库设计
各包结构设计与说明
功能实现
1. 登录功能
2. 分页查询、模糊查询
3. 增、删、改操作
总结
项目介绍
本项目主要实现了对用户信息的管理,能够在客户端很好的操作各个功能,并实时更新用户数据。采用 MySQL数据库 存储数据,JDBC 连接数据库,Servlet、JSP 等技术完成各个功能的具体实现。界面采用 Bootstrap框架 技术,实现了一个简单的界面效果。
数据库设计
为了方便起见,将管理员的用户名和密码写在了用户信息表中。(不合理的设计,当个反面教材)
图示:
各包结构设计与说明
userInfo_project:模块名 src / dao:操作数据库的接口(访问数据库层) src / dao / impl:操作数据库接口的具体实现类 src / domain:实体类 src / service:一系列数据处理的接口(业务逻辑层) src / service / impl:数据处理接口的具体实现类 src / util:连接数据库的工具类 src / web:存放各个servlet web:前端展示界面(界面层) |
功能实现
1. 登录功能
设计思路:管理员填写用户名和密码后,通过表单提交到 LoginServlet 进行数据验证操作。
LoginServlet:
//登录 @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"); //获取系统生成的验证码 HttpSession session = request.getSession(); String checkCode_server = (String) session.getAttribute("CHECKCODE_SERVER"); //删除session,确保验证码的一次性 session.removeAttribute("CHECKCODE_SERVER"); //判断验证码:验证码不正确 if (!checkCode_server.equalsIgnoreCase(verifycode)) { //提示信息 request.setAttribute("login_msg", "验证码错误!"); //跳转登录页面,转发 request.getRequestDispatcher("/login.jsp").forward(request, response); return; } //获取所有参数的map集合 Map<String, String[]> map = request.getParameterMap(); //封装User对象 User user = new User(); try { BeanUtils.populate(user, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //调用Service查询 UserService service = new UserServiceImpl(); User loginUser = service.login(user); //判断是否登录成功 if (loginUser != null) { //登录成功,将用户存到session session.setAttribute("user", loginUser); //跳转到主页面,重定向 response.sendRedirect(request.getContextPath() + "/index.jsp"); } else { //登录失败,提示错误信息 request.setAttribute("login_msg", "用户名或密码错误!"); //跳转登录页面,转发 request.getRequestDispatcher("/login.jsp").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
注意:数据的查询操作是通过调用封装在UserServiceImpl类中的login方法来实现的,而其中的login方法是根据封装在UserDaoImpl类中的findUserByUsernameAndPassword方法来实现的。
login:
//验证登录信息 @Override public User login(User user) { return dao.findUserByUsernameAndPassword(user.getUsername(), user.getPassword()); }
findUserByUsernameAndPassword:
//根据用户名和密码查询User对象 @Override public User findUserByUsernameAndPassword(String username, String password) { try { String sql = "select * from user where username = ? and password = ?"; User user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password); return user; } catch (Exception e) { e.printStackTrace(); return null; } }
实现效果:
2. 分页查询、模糊查询
设计思路:创建一个分页的实体类对象 PageBean,主页跳转到 FindUserByPageServlet 中进行查询。
PageBean属性:
//总记录数 private int totalCount; //总页码 private int totalPage; //每页的数据 private List<T> list; //当前页码 private int currentPage; //每页显示的记录数 private int rows;
FindUserByPageServlet:
//查询 @WebServlet("/findUserByPageServlet") public class FindUserByPageServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置编码 request.setCharacterEncoding("utf-8"); //当前页码 String currentPage = request.getParameter("currentPage"); //每页显示条数 String rows = request.getParameter("rows"); //判断当前页码、每页显示的条数 if (currentPage == null || "".equals(currentPage)) { currentPage = "1"; } if (rows == null || "".equals(rows)) { rows = "5"; } //获取条件查询参数 Map<String, String[]> condition = request.getParameterMap(); //调用service查询 UserService service = new UserServiceImpl(); PageBean<User> pb = service.findUserByPage(currentPage, rows, condition); //将PageBean存入request request.setAttribute("pb", pb); //将查询条件存入request request.setAttribute("condition", condition); //转发到list.jsp request.getRequestDispatcher("/list.jsp").forward(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
注意:数据的查询是通过调用封装在UserServiceImpl类中的findUserByPage方法实现的,然而具体的数据库操作是根据封装在UserDaoImpl类中的 findTotalCount 和 findByPage 方法 来实现的。
findTotalCount:
//查询总记录条数 @Override public int findTotalCount(Map<String, String[]> condition) { //定义模板初始化sql String sql = "select count(*) from user where 1 =1 "; StringBuilder sb = new StringBuilder(sql); //遍历map Set<String> keySet = condition.keySet(); //定义参数集合 List<Object> params = new ArrayList<>(); for (String key : keySet) { //排除分页条件参数 if ("currentPage".equals(key) || "rows".equals(key)) { continue; } //获取value String value = condition.get(key)[0]; //判断value是否有值 if (value != null && !"".equals(value)) { //有值 sb.append(" and " + key + " like ? "); //?条件的值 params.add("%" + value + "%"); } } return template.queryForObject(sb.toString(), Integer.class, params.toArray()); }
findByPage:
//在数据库中查询数据,获取一个User的对象集合 @Override public List<User> findByPage(int start, int rows, Map<String, String[]> condition) { String sql = "select * from user where 1 = 1 "; StringBuilder sb = new StringBuilder(sql); //遍历map Set<String> keySet = condition.keySet(); //定义参数集合 List<Object> params = new ArrayList<>(); for (String key : keySet) { //排除分页条件参数 if ("currentPage".equals(key) || "rows".equals(key)) { continue; } //获取value String value = condition.get(key)[0]; //判断value是否有值 if (value != null && !"".equals(value)) { //有值 sb.append(" and " + key + " like ? "); //?条件的值 params.add("%" + value + "%"); } } if (start < 0) start = 0; //添加分页查询 sb.append(" limit ?,? "); //添加分页查询参数值 params.add(start); params.add(rows); return template.query(sb.toString(), new BeanPropertyRowMapper<>(User.class), params.toArray()); }
findUserByPage:
//处理查询 @Override public PageBean<User> findUserByPage(String _currentPage, String _rows, Map<String, String[]> condition) { //类型转换 int currentPage = Integer.parseInt(_currentPage); int rows = Integer.parseInt(_rows); //第一页时,不能点击上一页 if (currentPage <= 0) currentPage = 1; //创建PageBean对象 PageBean<User> pb = new PageBean<>(); //调用dao查询总记录数 int totalCount = dao.findTotalCount(condition); pb.setTotalCount(totalCount); //计算总页码 int totalPage = (totalCount % rows) == 0 ? totalCount / rows : totalCount / rows + 1; pb.setTotalPage(totalPage); //最后一页时,不能点击下一页 if (currentPage >= totalPage) currentPage = totalPage; //设置参数 pb.setCurrentPage(currentPage); pb.setRows(rows); //调用dao查询list集合 //计算开始记录索引 int start = (currentPage - 1) * rows; List<User> list = dao.findByPage(start, rows, condition); pb.setList(list); return pb; }
实现效果:
3. 增、删、改操作
设计思路:管理员选择对应的功能操作后,JSP页面的数据就会提交到对应的 Servlet 中进行处理,通过调用业务逻辑层中的方法,业务逻辑层再调用数据库操作层中的方法,从而实现用户信息的增、删、改。
实现效果:
总结
本项目综合性很强,涉及到的知识点比较多,盲目的敲代码是不理智的,明确项目的设计思路十分重要。本次介绍只展示出了几个比较重要功能的部分代码,其他部分就不详细介绍了。博主认为最难的点就在于数据的交互,前端到后端,后端到前端,前端到前端,后端到后端,使用的数据传递方式不尽相同,要明确是哪一种数据传递场景,这样就很好解决了。
源码
可在博主主页获取!