1.设计数据库
以该表为例子
其中sc_code为主键
2.设计实体
当设计完数据库时,我们需要对数据库的数据进行包装,方便之后我们对其进行管理操作。
对比数据我们可以画出school表的e-r图
明确了school实体的关系和属性后,就可以将school表中的数据设计为一个School类进行管理。
public class School {
private String sc_code;
private String sc_name;
private Date sc_birth;
private String sc_address;
private Integer sc_total;
private Double sc_area;
//并为属性设置get set方法,以及构造方法,本篇将不再展示。
//。。。
}
3.明确设计的功能
本程序将完成对school数据的增删改查,并为使用者提供直观的操作界面。
4.创建项目
创建一个java web项目,本篇以maven自动生成的javaweb项目改造
如图
其中的java文件夹存放java源文件,用于进行数据处理和请求处理。
resources文件夹存放资源文件。
webapp存放jsp文件以及 webapp.xml文件。jsp用于进行动态页面展示,webapp。xml文件用于进行webapp的路径分配以及其他的web设置。
target 文件属于编译生成文件。
5.概念设计
5.1设计界面
对于需求,我们可以设计三个界面
1用于对学校进行展示的界面,并且可以滴学校数据进行删除。
2用于添加学校的界面。
3用于修改学校的界面。
5.2设计设计请求处理层
对于请求处理我们需要使用到servlet 用于对请求进行处理。并且可以对增加,删除,修改,展示的请求进行响应。我们需要处理以下4种请求
1索取学校数据的请求。
2索取对应编号学校数据的请求。
3删除学校数据的请求。
4增加学校数据的请求。
5.3设计业务处理层
当我们将所有的数据处理放到请求处理层是不合理的,若数据的设置放在请求处理层会使程序变得荣誉,耦合度也会大大提高,不方便我们对程序进行模块化设计。并且这也会大大复杂化请求处理。不利于对程序的重构。所以我们需要对数据的处理专门设计一个业务处理层。
对于需求我们可以设计以下方法
//删除特定的school学校
boolean del(String sc_code);
//获取所有的学校数据
List<School> getScAll();
//通过编号获取学校数据
School getScBySc_code(String sc_code);
//更新学校数据
boolean setSc(School school);
//增加学校数据
boolean addSc(School school);
5.4设计数据库交互层
对于数据库连接的获取数据是繁琐的,我们需要单独一层对其进行封装。并完成以下内容:
1获取school表数据。
2获取对应sc_code的school表数据。
3删除对应sc_code的school表数据。
4添加school表数据。
6.具体设计
6.1界面设计
我们通过jsp设计动态界面,jsp本质上是servlet,所以我们可以通过<%%>添加java代码,但这违背了jsp用于设计界面的初衷,也大大提高了前端人员的维护难度。我们可以通过EL表达式与jstl标签库对jsp中的java代码标签化。以减少原生java代码的数量,简化代码,体现jsp文件用于展示数据的目的。
maven导入
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
设计query.jsp
用于展示学校信息和各个界面的跳转功能。 通过后端传来的请求获取到学校的信息,并反映到界面上。
需要后端出入School类型的集合。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table>
<tr>
<td>学校编号</td>
<td>学校名字</td>
<td>学校地址</td>
<td>学校建校日期</td>
<td>学校人数</td>
<td>学校占地</td>
<td>操作</td>
</tr>
<c:forEach items="${requestScope.scs}" var="sc">
<tr>
<td>${sc.sc_code}</td>
<td>${sc.sc_name}</td>
<td>${sc.sc_address}</td>
<td>${sc.sc_birth}</td>
<td>${sc.sc_total}</td>
<td>${sc.sc_area}</td>
<td>
<a href="del.do?sc_code=${sc.sc_code}">删除</a>
<a href="edit.do?sc_code=${sc.sc_code}">修改</a>
</td>
</tr>
</c:forEach>
</table>
<a href="insert.do">新增</a>
</body>
</html>
设计edit.jsp
用于显示修改学校的信息,并进行修改。
需要后端传入对应sc_code的School类型数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="edit.do?m=1">
学校编号:${requestScope.sc.sc_code}<br>
<input type="hidden" name="sc_code" value="${requestScope.sc.sc_code}"><br>
学校名字:<input type="text" name="sc_name" value="${requestScope.sc.sc_name}"><br>
学校地址:<input type="text" name="sc_address" value="${requestScope.sc.sc_address}"><br>
建校日期:<input type="date" name="sc_birth" value="${requestScope.sc.sc_birth}"><br>
学校人数:<input type="text" name="sc_total" value="${requestScope.sc.sc_total}"><br>
学校占地:<input type="number" name="sc_area" value="${requestScope.sc.sc_area}"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
设计insert.jsp
用于添加数据,发到后端进行增加学校的操作。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="insert.do?m=1">
学校编号:<input type="number" name="sc_code" value="1000" ><br>
学校名字:<input type="text" name="sc_name"><br>
学校地址:<input type="text" name="sc_address"><br>
建校日期:<input type="date" name="sc_birth"><br>
学校人数:<input type="text" name="sc_total"><br>
学校占地:<input type="number" name="sc_area"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
5.2设计设计请求处理层
对于前端发来的数据,servlet通过service方法或者doxx方法进行处理。我们可以通过HttpRequest对象的gerparameter方法进行获取, 对于前端的请求所需要数据,我们可以通过HttpRequest对象的setAttribute 方法进行保存对象的操作,并转发给前端。
我们使用到servlet需要将其在webapp.xml中设置一个映射。使用者才能访问到对应的servlet,我们可以根据模糊匹配的方式进行多个请求路径发给一个servlet用于减少servlet的数量。
如图,本篇中设计了一个SchoolServle类t进行学校相关请求的处理。
<!-- servlet配置-->
<servlet>
<!-- servlet名字-->
<servlet-name>schoolServlet</servlet-name>
<!-- servlet对应的实现类-->
<servlet-class>com.smd.servlet.SchoolServlet</servlet-class>
</servlet>
<!-- servlet对应的映射-->
<servlet-mapping>
<!-- 通过名称相同进行映射与实体类的匹配-->
<servlet-name>schoolServlet</servlet-name>
<!-- 映射的url地址-->
<!-- 映射的url地址可以模糊查询,*.do的意思为当有请求访问到xx.do的地址时
将会自动跳转到SchoolServlet类中-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
通过 HttpRequest的 getServletPath()方法可以区分访问的路径从而区分访问的需求
设计如图:
package com.smd.servlet;
import com.smd.entity.School;
import com.smd.service.Impl.SchoolServiceImpl;
import com.smd.service.SchoolService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SchoolServlet extends HttpServlet {
private SchoolService service=new SchoolServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sc_code;
String _do = req.getServletPath();
DateFormat dft=new SimpleDateFormat("yyyy-MM-dd");
switch(_do){
case "/query.do":
req.setAttribute("scs",service.getScAll());
req.getRequestDispatcher("/school/query.jsp").forward(req,resp);
break;
case "/del.do":
sc_code= req.getParameter("sc_code");
if(!service.del(sc_code)){
req.setAttribute("msg","删除失败");
req.getRequestDispatcher("msg.jsp").forward(req,resp);
return;
}
resp.sendRedirect("query.do");
break;
case "/edit.do":
if(req.getParameter("m")==null) {
sc_code = req.getParameter("sc_code");
req.setAttribute("sc", service.getScBySc_code(sc_code));
req.getRequestDispatcher("/school/edit.jsp").forward(req, resp);
}else {
School school = new School();
school.setSc_code(req.getParameter("sc_code"));
school.setSc_name(req.getParameter("sc_name"));
school.setSc_address(req.getParameter("sc_address"));
try {
school.setSc_birth(dft.parse(req.getParameter("sc_birth")));
}catch (Exception e){
e.printStackTrace();
school.setSc_birth(new Date());
}
school.setSc_total(Integer.parseInt(req.getParameter("sc_total")));
school.setSc_area(Double.parseDouble(req.getParameter("sc_area")));
System.out.println(school);
if(service.setSc(school)){
resp.sendRedirect("query.do");
}else {
req.setAttribute("msg","修改失败");
req.getRequestDispatcher("msg.jsp").forward(req,resp);
return;
}
}
break;
case "/insert.do":
if(req.getParameter("m")==null) {
req.getRequestDispatcher("/school/insert.jsp").forward(req, resp);
}else {
School school = new School();
school.setSc_code(req.getParameter("sc_code"));
school.setSc_name(req.getParameter("sc_name"));
school.setSc_address(req.getParameter("sc_address"));
try {
school.setSc_birth(dft.parse(req.getParameter("sc_birth")));
}catch (Exception e){
e.printStackTrace();
school.setSc_birth(new Date());
}
school.setSc_total(Integer.parseInt(req.getParameter("sc_total")));
school.setSc_area(Double.parseDouble(req.getParameter("sc_area")));
System.out.println(school);
if(service.addSc(school)){
resp.sendRedirect("query.do");
}else {
System.out.println("f");
req.setAttribute("msg","新增失败");
req.getRequestDispatcher("msg.jsp").forward(req,resp);
return;
}
}
break;
}
}
}
6.3设计业务处理层
根据需求我们可以设计出以下方法。
//删除特定的school学校
boolean del(String sc_code);
//获取所有的学校数据
List<School> getScAll();
//通过编号获取学校数据
School getScBySc_code(String sc_code);
//更新学校数据
boolean setSc(School school);
//增加学校数据
boolean addSc(School school);
并对以上方法进行实现。
package com.smd.service.Impl;
import com.smd.dao.SchoolDao;
import com.smd.entity.School;
import com.smd.service.SchoolService;
import java.util.List;
public class SchoolServiceImpl implements SchoolService {
private SchoolDao dao=new SchoolDao();
@Override
public boolean del(String sc_code) {
return dao.delSchool(sc_code);
}
@Override
public List<School> getScAll() {
return dao.selectScAll();
}
@Override
public School getScBySc_code(String sc_code) {
return dao.selectScByCode(sc_code);
}
@Override
public boolean setSc(School school) {
return dao.updateSc(school);
}
@Override
public boolean addSc(School school) {
return dao.insertSc(school);
}
}
6.4设计数据库交互层
在设计数据库交互前,需要导入jdbc包进行数据库连接管理。
maven导入路径如图
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
通过jdbc包进行对数据的连接。通时为了方便对数据库连接进行管理。可以设计一个工具类进行专门的设计。
package com.smd.utils;
import java.sql.*;
public class JdbcUntil {
private JdbcUntil(){}
public static Connection getCon() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test?timezone=Asia/Shanghai&charset=utf-8";
String user = "root";
String pwd = "abc123456";
return DriverManager.getConnection(url, user, pwd);
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static Connection getCon(String ac,String user,String pwd) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/"+ac+"?timezone=Asia/Shanghai&charset=utf-8";
return DriverManager.getConnection(url, user, pwd);
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static void close(Connection con, Statement statement, ResultSet resultSet){
try {
if (con != null)
con.close();
if (statement != null)
statement.close();
if (resultSet != null)
resultSet.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
Connectors类用于表示数据库连接
Statement类用于表示数据库操作
ResultSet类用于保存数据库返回的数据
getCon方法用于获取数据库连接。
close方法用于关闭数据相关的连接。
通过需求我们可以设计交互,如图
package com.smd.dao;
import com.smd.entity.School;
import com.smd.utils.JdbcUntil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class SchoolDao {
private Connection con;
private String sql;
private PreparedStatement ps;
private ResultSet rs;
public boolean delSchool(String sc_code){
con = JdbcUntil.getCon();
if(con==null)
return false;
sql="delete from school where sc_code= ?";
try {
ps = con.prepareStatement(sql);
ps.setString(1, sc_code);
return ps.executeUpdate()>0;
}catch (Exception e){
e.printStackTrace();
return false;
}finally {
JdbcUntil.close(con,ps,rs);
}
}
public List<School> selectScAll() {
con = JdbcUntil.getCon();
List<School> scs=new ArrayList<>();
School school;
if(con==null)
return scs;
sql="select * from school ";
try {
ps = con.prepareStatement(sql);
rs=ps.executeQuery();
while (rs.next()){
school=new School();
school.setSc_code(rs.getString(1));
school.setSc_name(rs.getString(2));
school.setSc_birth(rs.getDate(3));
school.setSc_address(rs.getString(4));
school.setSc_total(rs.getInt(5));
school.setSc_area(rs.getDouble(6));
scs.add(school);
}
}catch (Exception e){
e.printStackTrace();
return new ArrayList<>();
}finally {
JdbcUntil.close(con,ps,rs);
}
return scs;
}
public School selectScByCode(String sc_code) {
con = JdbcUntil.getCon();
School school=null;
if(con==null)
return school;
sql="select * from school where sc_code=?";
try {
ps = con.prepareStatement(sql);
ps.setString(1,sc_code);
rs=ps.executeQuery();
if(rs.next()){
school=new School();
school.setSc_code(rs.getString(1));
school.setSc_name(rs.getString(2));
school.setSc_birth(rs.getDate(3));
school.setSc_address(rs.getString(4));
school.setSc_total(rs.getInt(5));
school.setSc_area(rs.getDouble(6));
}
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
JdbcUntil.close(con,ps,rs);
}
return school;
}
public boolean updateSc(School school) {
con = JdbcUntil.getCon();
if(con==null)
return false;
sql="update school set sc_name=?, sc_address=?, sc_birth =? ,sc_total=?, sc_area =? where sc_code=?";
try {
ps = con.prepareStatement(sql);
ps.setString(1, school.getSc_name());
ps.setString(2, school.getSc_address());
ps.setDate(3,new Date(school.getSc_birth().getTime()));
ps.setInt(4,school.getSc_total());
ps.setDouble(5,school.getSc_area());
ps.setString(6,school.getSc_code());
return ps.executeUpdate()>0;
}catch (Exception e){
e.printStackTrace();
return false;
}finally {
JdbcUntil.close(con,ps,rs);
}
}
public boolean insertSc(School school) {
con = JdbcUntil.getCon();
if(con==null)
return false;
sql="insert into school value (?,?,?,?,?,?)";
try {
ps = con.prepareStatement(sql);
ps.setString(1,school.getSc_code());
ps.setString(2, school.getSc_name());
ps.setString(3, school.getSc_address());
ps.setDate(4,new Date(school.getSc_birth().getTime()));
ps.setInt(5,school.getSc_total());
ps.setDouble(6,school.getSc_area());
return ps.executeUpdate()>0;
}catch (Exception e){
e.printStackTrace();
return false;
}finally {
JdbcUntil.close(con,ps,rs);
}
}
}
7.测试
启动服务器,访问对应地址,得到如图结果
进行删除测试 ,删除11003编号的学校结果: 成功
测试新增功能,点击新增超链接
添加数据点击提交
结果:成功
测试编辑功能,点击编号1111学校数据对应的修改超连接
将学校名字改为交大
结果:成功
结论
最终项目如图
可以完成对学校数据的管理。