三层架构定义及代码(一)

一. 基础

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

二. 三层定义

2.0 三层名–常用名

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

2.1.1 前台:对应于MVC中的View
  1. 作用:用于和用户交互,界面的显示
  2. 文件类型: jsp js html css jquery等Web前端技术
  3. 代码位置:WebContent
2.1.2 后台:对应于MVC中的Controller,
  1. 作用:用于控制跳转,调用业务逻辑层
  2. 文件类型:Servlet (SpringMVC , Struts2)
  3. 代码位置:位于xxx.servlet包

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

  1. 作用:接收表示层的请求 调用;
    组装数据访问层,逻辑性的操作(增删改查 , 删:查+删)
  2. 文件类型:java
  3. 代码位置:一般位于 xxx.service包(也可以是 :xxx.manager , xxx.bll )

2.3 数据访问层(DAL, Data Acess Layer)–Dao层

  1. 作用:直接访问数据库的操作,原子性的操作(增删改查)
  2. 文件类型:java
  3. 代码位置:一般位于 xxx.dao包

2.4 图片示意

在这里插入图片描述

2.5 三层关系

  1. 上层将请求传递给下层,下层将处理后结果返回给上层
  2. 上层依赖于下层,
  3. 依赖:代码的理解,就是持有成员变量;或者理解为:有A 的前提是现有B(先有数据库,才可以有Dao层,Dao层依赖于数据库)

三. MVC设计模式与三层架构比较图示

在这里插入图片描述

四.一个简单的案例

4.1 具体功能

(Servlet2.5实现)
设计一个增加功能,对应表单:sno(唯一),sname,sage,saddress

4.2 实现具体思路顺序(从底层到上层)

4.2.1 写代码顺序
  1. 数据库
  2. 实体类
  3. 数据访问层
  4. 业务逻辑层
  5. 表示层的后台
  6. 表示层的前台
4.2.2 从前端到后端调用图示

在这里插入图片描述

4.2.3 从后端到前端返回值图示(绿色)

在这里插入图片描述

4.3 数据库表

设计一个4列的表单student :sno(唯一),sname,sage,saddress

CREATE TABLE student(
sno int PRIMARY KEY,
sname VARCHAR(20),
sage int,
saddress VARCHAR(30)
);

4.4 实体类 Student.java

位于的包:org.student.entity

package org.student.entity;
public class Student {
private int sno;
private String sname;
private int sage;
private String saddress;
public Student() {
}
public Student( String sname, int sage, String saddress) {
	super();
	this.sname = sname;
	this.sage = sage;
	this.saddress = saddress;
}
public Student(int sno, String sname, int sage, String saddress) {
	super();
	this.sno = sno;
	this.sname = sname;
	this.sage = sage;
	this.saddress = saddress;
}
@Override
public String toString() {
	return "Student [sno=" + sno + ", sname=" + sname + ", sage=" + sage + ", saddress=" + saddress + "]";
}
public int getSno() {
	return sno;
}
public void setSno(int 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;
}
}

4.4 数据访问层 StudentDao.java

  1. 位于的包: org.student.dao
  2. 通过学号返回学生
  3. 通过学号判断表中是否存在这个学号
  4. 将学生添加到表中
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.LinkedList;
import java.util.List;
import org.student.entity.Student;

//数据访问层 :原子性的增删改查
public class StudentDao {
	private final String URL = "jdbc:mysql://localhost:3306/mvc";
	private final String USERNAME = "root";
	private final String PASSWORD = "root";
//	添加学生
	public boolean addStudent(Student student) { // zs 23 xm
		PreparedStatement pstmt = null;
		Connection connection = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			String sql = "insert into student(sno,sname,sage,saddress) values(?,?,?,?)";
			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, student.getSno());
			pstmt.setString(2, student.getSname());
			pstmt.setInt(3, student.getSno());
			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();
			}
		}
	}
//	通过学号,返回学生是否存在
	public boolean isExist(int sno) {  // true:存在   false:不存在
		return queryStudentBysno(sno) == null ? false : true;
	}

//	通过学号,返回学生
	public Student queryStudentBysno(int 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.setInt(1, sno);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				int no = rs.getInt("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) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}	
}

4.5 业务逻辑层 StudentService.java

  1. 位于的包: org.student.service
  2. 在增加前根据学号判断学号是否存在
  3. 在不存在后,进行添加
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())) {  //不存在
				      // 进行添加
				return studentDao.addStudent(student);
			}else {
				System.out.println("此人已经存在");
				return false;
			}
		}
}

4.5 表示层后台 AddStudentServlet .java

4.5.1 表示层后台 AddStudentServlet .java
  1. 位于的包: org.student.servlet
  2. 设置请求编码
  3. 获取数据,将数据封装到实体类中
  4. 调用业务逻辑层方法,返回添加是否成功
  5. 根据不同返回值,打印对应回馈信息
4.5.2 关于三层架构的编码问题
  1. 设置请求编码,放在第一行
request.setCharacterEncoding("utf-8"); 
  1. 设置响应编码,在响应前设置编码
//			1.先设置响应编码 
			response.setContentType("text/html; charset=UTF-8"); 
			response.setCharacterEncoding("utf-8");
//			2. 再响应     ----------注意1,2先后顺序
			PrintWriter out = response.getWriter();   //响应对象
4.5.3 使用内置对象
  1. out : PrintWriter out = response.getWriter()
  2. session: HttpSession session = request.getSession()
  3. application: ServletContext application = request.getServletContext()
/**
 * out request response session application
* out :		PrintWriter out = response.getWriter();
  session:		HttpSession session = request.getSession();
 application:	ServletContext application = request.getServletContext();
 * 
 */
4.5.3 代码
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"); //请求编码
		
			int no = Integer.parseInt(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);
			StudentService studentService = new StudentService();
			
			boolean result = studentService.addstudent(student);
			
			
//			1.先设置响应编码 
			response.setContentType("text/html; charset=UTF-8"); 
			response.setCharacterEncoding("utf-8");
//			2. 再响应     ----------注意1,2先后顺序
			PrintWriter out = response.getWriter();   //响应对象
			
			if (result) {
				out.println("增加成功");
			}else {
				out.println("增加失败");
			}	
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}

4.6 表示层前台 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>
<body>
	<form action="AddStudentServlet"  method="post">
			学号:<input type = "text" name = "sno" /> <br/>
			姓名:<input type = "text" name = "sname" /> <br/>
			年龄:<input type = "text" name = "sage" /> <br/>
			地址:<input type = "text" name = "saddress" /> <br/>
			<input type = "submit" value="新增" /> <br/>
	</form>

</body>
</html>

4.7 项目代码结构图

在这里插入图片描述

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值