JDBC封装CURD
使用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>
项目分析
业务需求
反映了组织机构或客户对系统、产品高层次的目标要求,通常在项目定义与范围文档中予以说明。
用户需求
描述了用户使用产品必须要完成的任务,这在使用实例或方案脚本中予以说明。
功能需求
定义了开发人员必须实现的软件功能,使用户利用系统能够完成他们的任务,从而满足了业务需求。
非功能性的需求
描述了系统展现给用户的行为和执行的操作等,它包括产品必须遵从的标准、规范和约束,操作界面的具体细节和构造上的限制。
需求分析报告
报告所说明的功能需求充分描述了软件系统所应具有的外部行为。“需求分析报告”在开发、测试、质量保证、项目管理以及相关项目功能中起着重要作用。