基础配置
导入数据库直接将源码复制粘贴到控制台执行即可,elm数据库表结构如下
查看我们要使用的business表,有9个字段。
配置pom.xml和web.xml,配置方法和前面的Servlet实验类似。多个servlet配置web.xml文件时,要先把所有名字和类的对应关系写在前面,url和名字的绑定放在后面。
因为要使用jdbc连接mysql数据库要在src下面新建一个lib包存放jdbc的jar包,并右键lib将它标注为库。
添加成功后在idea下面有对应的文件
三层架构编写后端代码
- 表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
- 业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
- 数据访问层:主要看数据层里面有没有包含逻辑处理,实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。
表示层
表示层由前端的用户界面和后端的Servlet构成,由于这里主要探讨后端,所以前端设计地比较简单
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<meta charset="UTF-8">
<title>studentInfo</title>
</head>
<body>
<form action="<c:url value="/Search"/>" method="post">
<input type="text" name="query">
<input type="submit" value="查询">
</form>
<form action="<c:url value="/Insert"/>" method="post">
name:
<input type="text" name="businessName"><br>
address:
<input type="text" name="businessAddress"><br>
explain:
<input type="text" name="businessExplain"><br>
orderTypeId: <input type="text" name="orderTypeId"><br>
starPrice:
<input type="text" name="starPrice"><br>
deliverPrice: <input type="text" name="deliverPrice"><br>
<button type="submit" value="submit">插入</button>
</form>
</body>
</html>
Servlet类继承自HttpServlet类,重写doPost方法,主要功能就是接受请求然后创建Service类然后调用对应的方法,再将返回的数据写到游览器中
import com.zlh.Service.BusinessService;
import com.zlh.Service.impl.BusinessServiceImpl;
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.nio.charset.StandardCharsets;
import java.sql.SQLException;
/**
* The queryServlet class extends HttpServlet.
* */
public class queryServlet extends HttpServlet {
/**
* The doPost method is used to dispose the post requests.
* @param req is the request of client
* @param resp is the response of Server
* */
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//getParameter query from sqlStatement,convert the query's encoding into UTF-8
String sqlStatement = req.getParameter("query");
sqlStatement=new String(sqlStatement.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
//Build the BusinessDaoImpl class and query the database according the sqlStatement
String result = null;
BusinessService businessService = new BusinessServiceImpl();
try {
result = businessService.query(sqlStatement);
} catch (SQLException e) {
throw new RuntimeException(e);
}
//write the result to the browser.
resp.setCharacterEncoding("GBK");
resp.getWriter().write(result);
}//of doPost
}//of class queryServlet
import com.zlh.Pojo.entity.Business;
import com.zlh.Service.BusinessService;
import com.zlh.Service.impl.BusinessServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* The insertServlet class for insert request.
* */
public class insertServlet extends HttpServlet {
/**
* doPost method is used to dispose the insert request.
* @param req The request body.
* @param resp The response to the request.
* */
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Business business = new Business();
req.setCharacterEncoding("UTF-8");
business.setBusinessName(req.getParameter("businessName"));
business.setBusinessAddress(req.getParameter("businessAddress"));
business.setBusinessExplain(req.getParameter("businessExplain"));
business.setOrderTypeId(req.getParameter("orderTypeId"));
business.setStarPrice(req.getParameter("starPrice"));
business.setDeliverPrice(req.getParameter("deliverPrice"));
BusinessService businessService = new BusinessServiceImpl();
String result;
try {
result = businessService.insert(business);
resp.setCharacterEncoding("GBK");
resp.getWriter().write(result);
//resp.sendRedirect("index.jsp");
}//of try
catch (Exception e) {
throw new RuntimeException(e);
}//of catch
}//of doPost
}//of insertServlet
业务逻辑层
业务逻辑层所有的Service都是接口的形式,再用对应的类实现接口的抽象方法,这样既可以降低耦合度也可以隐藏下面类实现的细节,提高灵活性。所有的业务逻辑都在这一层完成。在这里首先进行差错检测,如果查询内容为空,就直接返回报错信息。
再判断输入的内容是商家编号还是商家用户名以便实现后面不同的查询方式,然后通过判断结果将查询的参数封装到相应的字符串中。
将Dao层返回的对象内容取出来封装到字符串(html页面)中。
import com.zlh.Dao.BusinessDao;
import com.zlh.Dao.impl.BusinessDaoImpl;
import com.zlh.Pojo.dto.BusinessDTO;
import com.zlh.Pojo.entity.Business;
import com.zlh.Service.BusinessService;
import java.sql.SQLException;
/**
* The class implements the BusinessService interface methods.
* */
public class BusinessServiceImpl implements BusinessService {
/**
* The query method is used to make a sql statement and call the method of Dao layer.
* @param sqlStatement The query sql statement.
* @return The displaying string.
* */
@Override
public String query(String sqlStatement) throws SQLException {
//Judge the input field whether is empty.
if(sqlStatement.trim().isEmpty()){
return "输入内容为空";
}
String sql = null;
//Judge the type of the query
if(isNumber(sqlStatement)){
sql = "select * from business where businessId = '"+sqlStatement+"'";
}//of if
else{
sql = "select * from business where businessName like '%"+sqlStatement+"%'";
}//of else
//call the query method of the dao layer.
BusinessDao businessDao = new BusinessDaoImpl();
BusinessDTO business = businessDao.query(sql);
//Encapsulated return result.
if(business.getBusinessId()==null){
return "查询内容不存在";
}
String result = "<p>id:"+business.getBusinessId()+"<br>"
+"name:" +business.getBusinessName()+"<br>"
+"address:"+business.getBusinessAddress()+"<br>"
+"explain:"+business.getBusinessExplain()+"<br>"
+"deliverPrice:"+business.getDeliverPrice()+"<br>"
+"orderTypeId:"+ business.getOrderTypeId() +"<br>"
+"starPrice:"+ business.getStarPrice() +"<br>";
return result;
}//of query
@Override
public String insert(Business business) throws SQLException {
if(business.getBusinessName().trim().isEmpty()){
return "插入内容为空";
}
String result;
BusinessDao businessDao = new BusinessDaoImpl();
result=businessDao.insert(business);
return result;
}
/**
* Judge the query parameter whether is a number.
* @param sqlStatement The given statement.
* */
public boolean isNumber(String sqlStatement){
try{
Integer.parseInt(sqlStatement);
return true;
}catch (Exception e){
return false;
}//of catch
}//of isNumber
}
数据持久层:
数据持久层这里采用的是jdbc,所以每次使用时需要创建连接对象和关闭连接对象
根据Service层具体需求返回对应的对象,如这里的queryDao就把查询结果封装为BusinessDTO。Statement对象是jdbc专门用来执行sql语句的对象,需要注意的是statement的excute函数当sql语句为select时返回true,其他为false;excuteUpdate返回的是影响的行数;excuteQuery返回的是结果集合。ResultSet是用于检索数据库查询结果集的接口。
Insert方法
import com.zlh.Dao.BusinessDao;
import com.zlh.Pojo.dto.BusinessDTO;
import com.zlh.Pojo.entity.Business;
import java.sql.*;
/**
* The BusinessDaoImpl class is used to connect and query the database.
* */
public class BusinessDaoImpl implements BusinessDao {
//The sqlStatement is used to be as the parameter for the query
String sqlStatement;
//connection class for building jdbc connection
Connection con =null;
//Statement class for executing the sql statement
Statement state = null;
/**
* The method of querying database.
* @param sql The sqlStatement.
* @return The business object.
*/
public BusinessDTO query(String sql) throws SQLException {
//build the connection and business class
connectDB();
BusinessDTO business = new BusinessDTO();
//Execute the sql and inject the result into the business
ResultSet rs = state.executeQuery(sql);
if(rs.next()){
business.setBusinessId(rs.getString(1));
business.setBusinessName(rs.getString(2));
business.setBusinessAddress(rs.getString(3));
business.setBusinessExplain(rs.getString(4));
business.setOrderTypeId(rs.getString(6));
business.setStarPrice(rs.getString(7));
business.setDeliverPrice(rs.getString(8));
}//of if
rs.close();
closeDB();
return business;
}//of query
@Override
public String insert(Business business) throws SQLException {
//build the connection and business class
connectDB();
String sql = "insert into business (businessName,businessAddress,businessExplain,businessImg,orderTypeId,starPrice,deliveryPrice)"
+" values "+
"('"+business.getBusinessName()+"', '"+business.getBusinessAddress()+"', '"+business.getBusinessExplain()+"', '"+business.getBusinessImg()+"', '"+business.getOrderTypeId()+"', '"+business.getStarPrice()+"', '"+business.getDeliverPrice()+"')";
int rs = state.executeUpdate(sql);
System.out.println(rs);
closeDB();
if(rs!=0){
return "插入成功";
}
else{
return "插入失败";
}
}
/**
* connect the database
* */
public void connectDB() {
//Register the driver according reflection.
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}//of catch
//build the jdbc connection and create state class.
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/elm?useSSL=false&serverTimezone=UTC", "root", "74125896");
state=con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}//of catch
}//of connectDB
/**
* close the connection.
* */
public void closeDB()
{
//close all connection
try {
state.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}//of closeDB
}//of class BusinessDaoImpl
结果展示
总结
三层架构的优劣
- 降低了系统的性能。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
- 有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码
- 增加了代码量,增加了工作量
- 降低耦合度,使各层开发人员能够只专注自己那一层
- ps:使用tomcat服务器时,有时候idea不会报错,调试会发现在某个死循环内,但是tomcat页面会报错,要注意查看tomcat的信息。还有Servlet编程要注意编码格式的问题,注意设置编码格式和解码。