1.三层架构
与MVC设计模式的目标一致:都是为了解耦合,提高代码复用
                   区别:二者对项目的理解角度不同

2.三层组成

搭建系统三层架构 管理系统三层架构_sql


表示层(USL,User Show Layer:视图层)

    -前台:对应于MVC的View,用于和用户交互,界面显示

                   jsp,html,js,css

                   代码位置:WebContent

        -后台:对应于MVC的Controller,用于控制跳转,调用业务逻辑层

                   Servlet,SpringMVC,Struts2    

                   位于xxx.servlet包中

业务逻辑层(BLL,Business Logic Layer:Service层)

        -接收表示层的请求 调用

        -组装数据访问层,逻辑性的操作(增删改查,不可拆)

        一般位于xxx.service包中

数据访问层(DAL,Data Access Layer:Dao层)

        -直接访问数据库的操作,原子性的操作(增删改查)

        一般位于xxx.dao包中

三层间的关系:
上层将请求传递给下层,下层处理后,返回给上层

 

三层与MVC对比:

搭建系统三层架构 管理系统三层架构_html_02

 

案例项目结构:

 

 

搭建系统三层架构 管理系统三层架构_搭建系统三层架构_03

 

搭建系统三层架构 管理系统三层架构_java_04

add.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
	<script type="text/javascript">
		function check(){  //return true:表单正常提交,false:终止提交
			var sno=$("#sno").val();
			var sname=$("#sname").val();
			var sage=$("#sage").val();
			var saddress=$("#saddress").val();
			if(!(sno>0&&sno<101)){
				alert("学号有误!必须是1-100");
				return false;
			}
			if(!(sname.length>1&sname.length<20)){
				alert("姓名长度有误!必须是2-19位");
				return false;
			}
			//if(...) return false;
			return true;
		};
		
		$(document).ready(function() {
		});
	</script>
<body>
	<!-- onsubmit="return check():表单验证 -->
	<form action="AddStudentServlet" method="post" onsubmit="return check()">
		学号:<input type="text" name="sno" id="sno" /><br />
		姓名:<input type="text" name="sname" id="sname"/><br /> 
		年龄:<input type="text" name="sage" id="sage"/><br /> 
		地址:<input type="text" name="saddress" id="saddress" /><br /> 
		<input type="submit" value="添加学生" />
	</form>
</body>
</html>

index.jsp:

<%@page import="org.student.entity.Student"%>
<%@page import="java.util.List"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学生信息列表</title>
</head>
	<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function(){
			$("tr:odd").css("background-color","lightgray");
		});
	</script>
<body>

	<%
		//error:adderror失败
		//否则,1.确实执行了增加 2,直接访问查询全部页面 这样都会导致error为null,所以一进查询页面就会有“增加成功!”
		String error = (String) request.getAttribute("error");
		if (error != null) {
			if (error.equals("adderror")) {
				out.print("增加失败!");
			} else if (error.equals("noadderror")) {
				out.print("增加成功!");
			}
		}
	%>
	<table border="1px">
		<tr>
			<th>学号</th>
			<th>姓名</th>
			<th>年龄</th>
			<th>操作</th>
		</tr>
		<%
			//获取request域中的数据
			//根据key拿value,从servlet中拿值
			List<Student> students = (List<Student>) request.getAttribute("students");
			for (Student student : students) {
		%>
		<tr>
			<td><a href="QueryStudentBySnoServlet?sno=<%=student.getSno()%>"><%=student.getSno()%></a></td>
			<td><%=student.getSname()%></td>
			<td><%=student.getSage()%></td>
			<td><a href="DeleteStudentServlet?sno=<%=student.getSno()%>">删除</a></td>
		</tr>
		<%
			}
		%>
	</table>
	<a href="add.jsp">新增</a>
</body>
</html>

studentInfo.jsp:

<%@page import="org.student.entity.Student"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学生个人信息</title>
</head>
<body>
	<%
		Student student=(Student)request.getAttribute("student");
	%>
	<!-- 通过表单展示学生 -->
	<form action="UpdateStudentServlet" method="post">
		学号:<input type="text" name="sno" value="<%=student.getSno()%>" readonly="readonly"/><br/>
		姓名:<input type="text" name="sname" value="<%=student.getSname()%>"/><br/>
		年龄:<input type="text" name="sage" value="<%=student.getSage()%>"/><br/>
		地址:<input type="text" name="saddress" value="<%=student.getSaddress()%>"/><br/>
		<input type="submit" value="修改"/>
		<a href="QueryAllStudentServlet">返回</a>
	</form>
</body>
</html>

 

Student.java:

package org.student.entity;

public class Student {
	private String sno;
	private String sname;
	private int sage;
	private String saddress;
	
	public Student() {
	}
	
	public Student(String sname, int sage, String saddress) {
		this.sname = sname;
		this.sage = sage;
		this.saddress = saddress;
	}
	public Student(String sno, String sname, int sage, String saddress) {
		this.sno = sno;
		this.sname = sname;
		this.sage = sage;
		this.saddress = saddress;
	}
	
	public String getSno() {
		return sno;
	}
	public void setSno(String sno) {
		this.sno = sno;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public int getSage() {
		return sage;
	}
	public void setSage(int sage) {
		this.sage = sage;
	}
	public String getSaddress() {
		return saddress;
	}
	public void setSaddress(String saddress) {
		this.saddress = saddress;
	}
	
	
}

StudentDao.java:

package org.student.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.student.entity.Student;

//数据访问层:原子性的增删改查
public class StudentDao {
	String URL = "jdbc:mysql://localhost:3306/threetiersample";
	String USERNAME = "root";
	String PASSWORD = "";

	// 根据学号查此人是否存在
	public boolean isExist(String sno) {
		return queryStudetByNo(sno) == null ? false : true;
	}

	// 查询全部学生,用集合表示
	public List<Student> queryAllStudents() {
		List<Student> students = new ArrayList<>();
		Student student = null;
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "select * from student";
			pstmt = connection.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				String no = rs.getString("sno");
				String name = rs.getString("sname");
				int age = rs.getInt("sage");
				String address = rs.getString("saddress");
				student = new Student(no, name, age, address);
				students.add(student);
			}
			return students;

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

	// 增加学生
	public boolean addStudent(Student student) {
		Connection connection = null;
		PreparedStatement pstmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "insert into student values(?,?,?,?)";
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, student.getSno());
			pstmt.setString(2, student.getSname());
			pstmt.setInt(3, student.getSage());
			pstmt.setString(4, student.getSaddress());
			int count = pstmt.executeUpdate();
			if (count > 0) {
				return true;
			} else {
				return false;
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

	// 根据学号修改学生:先根据sno找人,然后信息替换为新的student
	public boolean updateStudentBySno(String sno, Student student) {
		Connection connection = null;
		PreparedStatement pstmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "update student set sname=?,sage=?,saddress=? where sno=?";
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, student.getSname());
			pstmt.setInt(2, student.getSage());
			pstmt.setString(3, student.getSaddress());
			pstmt.setString(4, sno);
			int count = pstmt.executeUpdate();
			if (count > 0) {
				return true;
			} else {
				return false;
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

	// 根据学号来删除学生
	public boolean deleteStudentBySno(String sno) {
		Connection connection = null;
		PreparedStatement pstmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "delete from student where sno=?";
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, sno);
			int count = pstmt.executeUpdate();
			if (count > 0) {
				return true;
			} else {
				return false;
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

	// 根据学号查询学生
	public Student queryStudetByNo(String sno) {
		Student student = null;
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "select * from student where sno=?";
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, sno);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				String no = rs.getString("sno");
				String name = rs.getString("sname");
				int age = rs.getInt("sage");
				String address = rs.getString("saddress");
				student = new Student(no, name, age, address);
			}
			return student;

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}
}

StudentService.java:

package org.student.service;

import java.util.List;

import org.student.dao.StudentDao;
import org.student.entity.Student;

//业务逻辑层:逻辑性的增删改查(增:查+增),对dao层进行的组装
public class StudentService {
	StudentDao studentDao=new StudentDao();
	public boolean addStudent(Student student) {
		if(!studentDao.isExist(student.getSno())) { //判断此人是否存在
			studentDao.addStudent(student);
			return true;
		}else {
			System.out.println("此人已存在!!!");
			return false;
		}
	}
	
	public boolean deleteStudentBySno(String sno) {
		if(studentDao.isExist(sno)) {
			return studentDao.deleteStudentBySno(sno);
		}
		return false;
	}
	
	public boolean updateStudentBySno(String sno,Student student) {
		if(studentDao.isExist(sno)) {
			return studentDao.updateStudentBySno(sno, student);
		}
		return false;
	}
	
	public Student queryStudentBySno(String sno) {
		return studentDao.queryStudetByNo(sno);
	}
	
	public List<Student> queryAllStudent(){
		return studentDao.queryAllStudents();
	}
}

AddStudentServlet.java:

package org.student.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.student.entity.Student;
import org.student.service.StudentService;

public class AddStudentServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String no=request.getParameter("sno");
		String name=request.getParameter("sname");
		int age=Integer.parseInt(request.getParameter("sage"));
		String address=request.getParameter("saddress");
		Student student=new Student(no,name,age,address);
		
		//service层写好后,开始在servlet调用service
		StudentService studentService=new StudentService();
		boolean result=studentService.addStudent(student);
		
		/*
		 * out request response session application
		 * out:PrintWriter out = response.getWriter();
		 * session:request.getSession()
		 * application:request.getServletContext()
		 */
		
		//设置响应编码
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		//由于out是jsp的内置对象,所以要先拿到out
		PrintWriter out = response.getWriter();
		/*
		if(result) {
			//out.println("增加成功!");
			//response.sendRedirect("QueryAllStudentServlet");
		}else {
			//out.println("增加失败!");
			//response.sendRedirect("QueryAllStudentServlet");
		}
		*/
		if(!result) { //如果增加失败,给request域放入一条数据
			request.setAttribute("error", "adderror");
		}else {//增加成功
			request.setAttribute("error", "noadderror");
		}
		//增加成功失败,都会跳转查询页
		//response.sendRedirect("QueryAllStudentServlet");
		//如果增加成功,跳转到查询页
		request.getRequestDispatcher("QueryAllStudentServlet").forward(request, response);
	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

DeleteStudentServlet.java:

package org.student.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.student.service.StudentService;

public class DeleteStudentServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//删除功能
		request.setCharacterEncoding("utf-8");
		//接收前端传来的学号
		String no = request.getParameter("sno");
		//servlet直接掉service去删
		StudentService service=new StudentService();
		boolean result=service.deleteStudentBySno(no);

		//设置响应编码
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		if(result) {
			//out.println("删除成功!!!");
			response.sendRedirect("QueryAllStudentServlet");//删除学生之后重新查询,然后数据返回jsp,而不是直接跳到index.jsp
		}else {
			out.println("删除失败!!!");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

 UpdateStudentServlet.java:

package org.student.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.student.entity.Student;
import org.student.service.StudentService;

public class UpdateStudentServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		// 获取修改的人的学号
		String no = request.getParameter("sno");
		// 获取修改后的内容
		String name = request.getParameter("sname");
		int age = Integer.parseInt(request.getParameter("sage"));
		String address = request.getParameter("saddress");
		// 将修改后的内容封装到一个实体类中
		Student student = new Student(name, age, address);
		// Servlet调Service(上层调下层)
		StudentService service = new StudentService();
		boolean result = service.updateStudentBySno(no, student);

		// 设置响应编码
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		if (result) {
			//out.println("修改成功!!!");
			response.sendRedirect("QueryAllStudentServlet");//修改完后跳转到QueryAllStudentServlet
		} else {
			out.println("修改失败!!!");
		}

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

QueryStudentBySnoServlet.java:

package org.student.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.student.entity.Student;
import org.student.service.StudentService;


public class QueryStudentBySnoServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String no=request.getParameter("sno");
		StudentService service=new StudentService();
		Student student=service.queryStudentBySno(no);
		System.out.println(student.toString());
		//将此人的信息传到前台studentInfo.jsp显示
		request.setAttribute("student", student); //将查到的学生信息放在request域中
		//如果request域没有数据,使用重定向跳转response.sendRedirect();
		//如果request域有数据(request.setAttribute() ),使用请求转发跳转
		request.getRequestDispatcher("studentInfo.jsp").forward(request,response);
		
		
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

QueryAllStudentServlet.java:

package org.student.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.student.entity.Student;
import org.student.service.StudentService;


public class QueryAllStudentServlet extends HttpServlet {
	

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		StudentService service=new StudentService();
		List<Student> students=service.queryAllStudent();
		System.out.println(students.toString());
		//将Servlet传给jsp
		request.setAttribute("students", students);
		//因为request域中有数据,因此需要通过请求转发的方式跳转(重定向会丢失request域数据)
		//pageContext<request<session<application
		
		request.getRequestDispatcher("index.jsp").forward(request,response);
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);
	}

}