使用jdbc时,每一次对数据库操作,都会建立连接,关闭连接,导致,每次写新功能,都要重复写很多遍代码,这就导致代码的冗余度高,复用性差,所以将数据库的操作封装成工具类,封装进DBHelper工具类中。
连接数据库
//常量大写 private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb?serverTimezone=UTC&characterEncoding=utf8"; private static final String NAME = "root"; private static final String PASSWORD = "root"; private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; private static Connection con=null; private static PreparedStatement ps=null; private static ResultSet rs=null; //加载数据库驱动 //static静态代码块,在jvm加载类的时候启用,在一个类中可以有多个static代码块,根据static的顺序来运行 static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 获取数据库连接 * @return */ public static Connection getCon(){ try { con = DriverManager.getConnection(URL,NAME,PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return con; }
查询
适用于 select
public List<Map> queryAll(String sql,Object...objs){ //object...objs 的意思就是object是可变的,他是可以存在,也是可以不存在的 List<Object> objects = Arrays.asList(objs); //使用Map集合,可以不需要再封装数据库 List<Map> list=new LinkedList<>(); //获取数据库连接 con = DBHelper.getCon(); try { ps = con.prepareStatement(sql); //赋予预编译对象的值 //(sql+" ").split("\\?") sql+" "这里的空格切记不能少 长度的下标从0开始起,所以?的数量要减去1 for (int i = 0; i < (sql+" ").split("\\?").length - 1; i++) { ps.setObject(i + 1, objects.get(i)); } rs = ps.executeQuery(); //ResultSetMetaData 可用于获取关于 ResultSet 对象中列的类型和属性信息的对象 //getMetaData() 得到数据集的列数 ResultSetMetaData metaData=rs.getMetaData(); while(rs.next()){ Map map = new HashMap(); //循环获取数据 这里的下标是从1开始 for (int i = 1; i <= metaData.getColumnCount(); i++) { //getColumnName() 获取指定列的名称 String key=metaData.getColumnName(i); map.put(key,rs.getObject(key)); } list.add(map); } } catch (SQLException e) { e.printStackTrace(); }finally { close(); } return list; }
更新 添加 删除
适用于 update insert delete
public int update(String sql,Object...objs){ int num=0; con = DBHelper.getCon(); try { //获取objs的值 List<Object> objects = Arrays.asList(objs); ps = con.prepareStatement(sql); //赋予预编译对象的值 for (int i = 0; i < (sql+" ").split("\\?").length - 1; i++) { //将值循环赋予 ps.setObject(i + 1, objects.get(i)); } num=ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally { close(); } return num; }
关闭资源
public void close(){ try { if(con!=null) con.close(); if(ps!=null) ps.close(); if(rs!=null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } }
分页
将自己的程序展现给用户,肯定越简洁越好,分页更加适应用户的心理,毕竟谁也不会愿意看着老长的页面。
分页工具类
首先便需要一个分页工具类,将分页所需要的各种参数都给他封装起来。
public class PageBean<T> { private Integer page;//当前页 private Integer limit;//每页的条数 private Integer totalCount;//查询数据的总行数 private Integer totalPages;//总页数 private List<T> list=new ArrayList<T>();//当前页的数据集合 public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } public Integer getLimit() { return limit; } public void setLimit(Integer limit) { this.limit = limit; } public Integer getTotalCount() { return totalCount; } public void setTotalCount(Integer totalCount) { this.totalCount = totalCount; } public Integer getTotalPages() { return totalPages; } public void setTotalPages(Integer totalPages) { this.totalPages = totalPages; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } //无参的构造方法 public PageBean() { } //有参的构造方法 public PageBean(Integer page, Integer limit, Integer totalCount, Integer totalPages, List<T> list) { this.page = page; this.limit = limit; this.totalCount = totalCount; this.totalPages = totalPages; this.list = list; } @Override public String toString() { return "PageBean{" + "page=" + page + ", limit=" + limit + ", totalCount=" + totalCount + ", totalPages=" + totalPages + ", list=" + list + '}'; }
获取前台数据
//从页面获取页数判断如果为空则为1否则通过 Integer.valueOf(request.getParameter("page") 获取页面传过来的参数 int page = request.getParameter("page")!=null?Integer.valueOf(request.getParameter("page")):1 //获取页面每页长度如果为空则定义为10否则按 Integer.valueOf(request.getParameter("pageSize") 获取的长度像service传递 int pageSize = request.getParameter("pageSize")!=null?Integer.valueOf(request.getParameter("pageSize")):10; //定义SQL语句查询所有数据 String sql="select e.*,d.dname from emp e left join dept d on e.did=d.id "; //通过调用dao层的分页查询方法,将数据获取 //PageBean<Emp> PageBean<T>就是传入的参数 list<Map> PageBean<Emp> pageList =empService.pageList(page,pageSize,sql);
dao层部署
//分页 public PageBean<Map> pageList(int page, int pageSize, String sql, String... obj) { //1.获取总条数 int count = getCount(sql, obj); //2.根据总条数和每页条数进行计算总页数(根据是否有余数,判断是否需要页数加一) int totlePages = count % pageSize == 0 ? count / pageSize : (count / pageSize) + 1; //3.判断当前页是否大于总页数或小于1页 免得出现负数和不存在的页数 if (page < 1) { page = 1; } else if (page > totlePages) { page = totlePages; } //4.判断通过后计算当前分页的起始位置 int startindex = (page - 1) * pageSize; //链式调用concat链接数据 //sql= sql.concat("limit ").concat(startindex+"").concat(",").concat(pageSize+""); sql += " limit " + startindex + "," + pageSize; System.out.println("分页方法:" + sql); System.out.println(list); //获取总列数数据 List<Map> list = select(sql, obj); PageBean<Map> pagelist = new PageBean<>(totlePages, count, page, pageSize, list); System.out.println(pagelist); return pagelist; } public int getCount( String sql, String... obj) { int count =0; Connection conn = DBHelper.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { ps = conn.prepareStatement("select count(*) num from("+sql+") d"); System.out.println("查询总条数:"+sql); for (int j = 0; j < obj.length; j++) { System.out.println("第"+j+"个参数:"+obj[j]); ps.setObject(j + 1, obj[j]); } rs = ps.executeQuery(); if (rs.next()) { count=rs.getInt("num"); } } catch (SQLException e) { e.printStackTrace(); } finally { DBHelper.close(conn, ps, rs); } return count; }
页面设计
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <input type="hidden" id="spage" value="1"> <input type="hidden" id="epage" value="2"> <input type="button" id="start" value="上一页" > <!-- --> <input type="button" id="end" value="下一页"> </body> <script src="${pageContext.request.contextPath}/js/jquery-1.11.2.min.js"></script> <script type="application/javascript"> var pageSize=3; $("#start").click(function(){ alert(pageSize); let spage = $("#spage").val(); //异步请求 获取部门的信息,动态的显示到select中 $.ajax({ url: '${pageContext.request.contextPath}/EmpServlet?method=pageList',//请求路径 data:{"page":spage,"pageSize":pageSize},//key:value,key:value....... type: "post",//请求方式 get dataType: "json",// 请求后台后,后台返回的数据格式 是json success: function (data) { // 如果请求成功,那后 后台json数据 ,data只是1个变量名 console.log(data); } }); }) $("#end").click(function(){ alert(pageSize); let epage = $("#epage").val(); //异步请求 获取部门的信息,动态的显示到select中 $.ajax({ url: '${pageContext.request.contextPath}/EmpServlet?method=pageList',//请求路径 data:{"page":epage,"pageSize":pageSize},//key:value,key:value....... type: "post",//请求方式 get dataType: "json",// 请求后台后,后台返回的数据格式 是json success: function (data) { // 如果请求成功,那后 后台json数据 ,data只是1个变量名 console.log(data); } }); }) </script> </html>
项目分析
业务需求
反映了组织机构或客户对系统、产品高层次的目标要求,通常在项目定义与范围文档中予以说明。
用户需求
描述了用户使用产品必须要完成的任务,这在使用实例或方案脚本中予以说明。
功能需求
定义了开发人员必须实现的软件功能,使用户利用系统能够完成他们的任务,从而满足了业务需求。
非功能性的需求
描述了系统展现给用户的行为和执行的操作等,它包括产品必须遵从的标准、规范和约束,操作界面的具体细节和构造上的限制。
需求分析报告
报告所说明的功能需求充分描述了软件系统所应具有的外部行为。“需求分析报告”在开发、测试、质量保证、项目管理以及相关项目功能中起着重要作用。