JavaWeb 经典三层架构学习 -- 案例

目录

    • 1 三层架构的基本认识
      • 1.1 表现层
      • 1.2 逻辑层
      • 1.3 数据访问层
      • 各层间关系图
    • 2 案例目录
      • 2.1 案例目录图
      • 2.2 目录分析
        • src:
          • controller: 表现层
          • dao:数据访问层
          • entity:实体
          • service:业务逻辑层
          • utils:工具
    • 3 案例代码
      • 3.1 数据库
      • 3.2 java代码
        • controller:
          • StudentController.java
        • dao:
          • StudentDAO.java
        • dao.impl:
          • StudentDAOImpl.java
        • entity
          • Student.java
        • service
          • StudentService.java
        • service.impl
          • StudentServiceImpl.java
        • utils
          • MysqlDBConnection.java
          • DBUtil.java
    • 4 值得注意的一点
    • 参考

1 三层架构的基本认识

通常意义上的三层架构指的就是表现层逻辑层数据访问层。区分层次的目的是为了实现高内聚,低耦合的思想,层是一种弱耦合结构,层与层之间的依赖是向下的,底层对于上层而言是“无知”的,改变上层的设计对于其调用的底层而言没有任何影响。

1.1 表现层

表现层也称表示层,主要用于显示数据和接收用户输入。

1.2 逻辑层

业务逻辑写在逻辑层内,逻辑层是系统架构中体现核心价值的一部分,起到数据交换中承上启下的作用。对于数据访问层而言,它是调用者;对于表示层而言,它却是被调用者。

1.3 数据访问层

数据访问层也称持久层,主要用于实现对数据库的访问。

各层间关系图

JavaWeb 经典三层架构学习 -- 案例_第1张图片

2 案例目录

2.1 案例目录图

JavaWeb 经典三层架构学习 -- 案例_第2张图片

2.2 目录分析

src:

controller: 表现层
dao:数据访问层
entity:实体
service:业务逻辑层
utils:工具

3 案例代码

这是一个实现学生的增删改查的案例。

3.1 数据库

创建数据库代码:

CREATE TABLE `NewTable` (
`id`  int(11) NOT NULL AUTO_INCREMENT COMMENT '流水号' ,
`stu_no`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学生编号' ,
`stu_name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`stu_birthday`  date NULL DEFAULT NULL COMMENT '生日' ,
`stu_phone`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电话号码' ,
`stu_address`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '家庭住址' ,
`stu_height`  double NULL DEFAULT NULL COMMENT '身高' ,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=25
ROW_FORMAT=DYNAMIC;

JavaWeb 经典三层架构学习 -- 案例_第3张图片

3.2 java代码

controller:

StudentController.java
package controller;

import java.util.List;
import java.util.Scanner;

import org.apache.log4j.Logger;

import entity.Student;
import service.StudentService;
import service.impl.StudentServiceImpl;

public class StudentController {
	static Scanner in = new Scanner(System.in);
	static Logger logger = Logger.getLogger(StudentController.class);

	private StudentService studentService = new StudentServiceImpl();

	public void prompt() {
		System.out.println("请选择要进行的操作:\n1.新增\t2.修改\t3.删除\t4.查找记录\t5.退出");
		int judge = in.nextInt();
		switch (judge) {
		case 1:
			addInfo();
			prompt();
			break;
		case 2:
			updateInfo();
			prompt();
			break;
		case 3:
			deleteInfo();
			prompt();
			break;
		case 4:
			queryAll();
			prompt();
			break;
		case 5:
			System.exit(1);
			break;

		default:
			break;
		}
	}

	public void queryAll() {
		List<Student> students = studentService.findAll();
		students.forEach(System.out::println);
	}

	public void deleteInfo() {
		System.out.println("请输入要删除的学生id:");
		Integer id = in.nextInt();
		if (studentService.delete(id)) {
			System.out.println("删除成功");
			logger.info("删除数据成功");
		} else
			System.out.println("删除失败");
	}

	public void updateInfo() {
		System.out.println("请输入需要更新的学生信息:");
		Student student = getStudent();
		if (studentService.update(student)) {
			System.out.println("更新成功");
			logger.info("更新数据成功");
		} else
			System.out.println("更新失败");
	}

	public void addInfo() {
		System.out.println("请输入要添加的学生信息:");
		Student student = getStudent();
		if (studentService.save(student)) {
			System.out.println("添加成功");
			logger.info("添加数据成功");
		} else
			System.out.println("添加失败");
	}

	public Student getStudent() {
		System.out.println("学号,姓名,生日,手机,地址,身高");
		String stuNo = in.next();
		String stuName = in.next();
		String stuBirthday = in.next();
		String stuPhone = in.next();
		String stuAddress = in.next();
		Double stuHeight = in.nextDouble();
		Student student = new Student(stuNo, stuName, stuBirthday, stuPhone, stuAddress, stuHeight);
		return student;
	}

	public static void main(String[] args) {
		StudentController studentController = new StudentController();
		studentController.prompt();
	}
}

dao:

StudentDAO.java
package dao;

import java.util.List;

import entity.Student;

public interface StudentDAO {

	// 保存,单个学生,student
	public int save(Student student);

	// 修改,单个学生,student
	public int update(Student student);

	// 删除,单个学生,id
	public int delete(Integer id);

	// 删除,单个学生,stuNo
	public int deleteByStuNo(String stuNo);

	// 查询,单个学生,id
	public Student findById(Integer id);

	// 查询,单个学生,stuNo
	public Student findByStuNo(String stuNo);

	// 查询,学生列表,stuName
	public List<Student> findByStuName(String stuName);

	// 查询,学生列表,null
	public List<Student> findAll();

	// 查询,学生列表,null
	public List<Student> findAllByPage(int pageSize, int page);

}

dao.impl:

StudentDAOImpl.java
package dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import dao.StudentDAO;
import entity.Student;
import utils.DBUtil;

public class StudentDAOImpl implements StudentDAO {

	private DBUtil util = new DBUtil();

	@Override
	public int save(Student student) {
		String sql = "insert into tab_student (stu_no,stu_name,stu_birthday,stu_phone,stu_address,stu_height) values(?,?,?,?,?,?)";
		int count = util.execute(sql, student.getStuNo(), student.getStuName(), student.getStuBirthday(),
				student.getStuPhone(), student.getStuAddress(), student.getStuHeight());
		return count;
	}

	@Override
	public int update(Student student) {
		String sql = "update tab_student set stu_name=?,stu_birthday=?,stu_phone=?,stu_address=?,stu_height=? where stu_no=?";
		int count = util.execute(sql, student.getStuName(), student.getStuBirthday(), student.getStuPhone(),
				student.getStuAddress(), student.getStuHeight(), student.getStuNo());
		return count;
	}

	@Override
	public int delete(Integer id) {
		String sql = "delete from tab_student where id = ?";
		int count = util.execute(sql, id);
		return count;
	}

	@Override
	public int deleteByStuNo(String stuNo) {
		String sql = "delete from tab_student where stu_no = ?";
		int count = util.execute(sql, stuNo);
		return count;
	}

	@Override
	public Student findById(Integer id) {
		Student student = new Student();
		try {
			String sql = "select * from tab_student where id = ?";
			ResultSet rs = util.query(sql, id);
			while (rs.next()) {
				handleData(rs, student);
			}
		} catch (NumberFormatException | SQLException e) {
			e.printStackTrace();
		}
		return student;
	}

	@Override
	public Student findByStuNo(String stuNo) {
		Student student = new Student();
		try {
			String sql = "select * from tab_student where stu_no = ?";
			ResultSet rs = util.query(sql, stuNo);
			while (rs.next()) {
				handleData(rs, student);
			}
		} catch (NumberFormatException | SQLException e) {
			e.printStackTrace();
		}
		return student;
	}

	@Override
	public List<Student> findByStuName(String stuName) {
		List<Student> students = new ArrayList<Student>();
		try {
			String sql = "select * from tab_student where stu_name = ?";
			ResultSet rs = util.query(sql, stuName);
			while (rs.next()) {
				Student student = new Student();
				handleData(rs, student);
				students.add(student);
			}
		} catch (NumberFormatException | SQLException e) {
			e.printStackTrace();
		}
		return students;
	}

	@Override
	public List<Student> findAll() {
		List<Student> students = new ArrayList<Student>();
		try {
			String sql = "select * from tab_student";
			ResultSet rs = util.query(sql);
			while (rs.next()) {
				Student student = new Student();
				handleData(rs, student);
				students.add(student);
			}
		} catch (NumberFormatException | SQLException e) {
			e.printStackTrace();
		}
		return students;
	}

	@Override
	public List<Student> findAllByPage(int pageSize, int page) {
		List<Student> students = new ArrayList<Student>();
		try {
			String sql = "select * from tab_student";
			ResultSet rs = util.queryByPage(sql, pageSize, page);
			while (rs.next()) {
				Student student = new Student();
				handleData(rs, student);
				students.add(student);
			}
		} catch (NumberFormatException | SQLException e) {
			e.printStackTrace();
		}
		return students;
	}

	private void handleData(ResultSet rs, Student student) throws SQLException {
		student.setId(Integer.valueOf(rs.getString("id")));
		student.setStuNo(rs.getString("stu_no"));
		student.setStuName(rs.getString("stu_name"));
		student.setStuBirthday(rs.getString("stu_birthday"));
		student.setStuPhone(rs.getString("stu_phone"));
		student.setStuAddress(rs.getString("stu_address"));
		student.setStuHeight(Double.valueOf(rs.getString("stu_height")));
	}
}

entity

Student.java
package entity;

public class Student {
	private Integer id;
	private String stuNo;
	private String stuName;
	private String stuBirthday;
	private String stuPhone;
	private String stuAddress;
	private Double stuHeight;

	public Student() {

	}

	public Student(String stuNo, String stuName, String stuBirthday, String stuPhone, String stuAddress,
			Double stuHeight) {
		super();
		this.stuNo = stuNo;
		this.stuName = stuName;
		this.stuBirthday = stuBirthday;
		this.stuPhone = stuPhone;
		this.stuAddress = stuAddress;
		this.stuHeight = stuHeight;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getStuNo() {
		return stuNo;
	}

	public void setStuNo(String stuNo) {
		this.stuNo = stuNo;
	}

	public String getStuName() {
		return stuName;
	}

	public void setStuName(String stuName) {
		this.stuName = stuName;
	}

	public String getStuBirthday() {
		return stuBirthday;
	}

	public void setStuBirthday(String stuBirthday) {
		this.stuBirthday = stuBirthday;
	}

	public String getStuPhone() {
		return stuPhone;
	}

	public void setStuPhone(String stuPhone) {
		this.stuPhone = stuPhone;
	}

	public String getStuAddress() {
		return stuAddress;
	}

	public void setStuAddress(String stuAddress) {
		this.stuAddress = stuAddress;
	}

	public Double getStuHeight() {
		return stuHeight;
	}

	public void setStuHeight(Double stuHeight) {
		this.stuHeight = stuHeight;
	}

	@Override
	public String toString() {
		String result = "编号:\t" + this.getId() + "\n姓名:\t" + this.getStuName() + "\n生日:\t" + this.getStuBirthday()
				+ "\n手机:\t" + this.getStuPhone() + "\n地址:\t" + this.getStuAddress() + "\n-------------------------\n";
		return result;
	}
}

service

StudentService.java
package service;

import java.util.List;

import entity.Student;

public interface StudentService {

	public boolean save(Student student);

	public boolean update(Student student);

	public boolean delete(Integer id);

	public List<Student> findAll();
}

service.impl

StudentServiceImpl.java
package service.impl;

import java.util.List;

import dao.StudentDAO;
import dao.impl.StudentDAOImpl;
import entity.Student;
import service.StudentService;

public class StudentServiceImpl implements StudentService {

	// 此处使用studentDAO的抽象而非具体实现,实现多态解耦和
	// private StudentDAOImpl studentDAOImpl = new StudentDAOIml();
	private StudentDAO studentDAO = new StudentDAOImpl();

	@Override
	public boolean save(Student student) {
		boolean flag = studentDAO.save(student) == 1;
		return flag;
	}

	@Override
	public boolean update(Student student) {
		boolean flag = studentDAO.update(student) == 1;
		return flag;
	}

	@Override
	public boolean delete(Integer id) {
		boolean flag = studentDAO.delete(id) == 1;
		return flag;
	}

	@Override
	public List<Student> findAll() {
		List<Student> students = studentDAO.findAll();
		return students;
	}

}

utils

MysqlDBConnection.java
package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MysqlDBConnection {

	private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
	private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/learn?characterEncoding=utf8&useSSL=true";
	private static final String DATABASE_USRE = "root";
	private static final String DATABASE_PASSWORD = "root";

	public static Connection getConnction() {
		Connection dbConnection = null;
		try {
			Class.forName(DRIVER_CLASS);
			dbConnection = DriverManager.getConnection(DATABASE_URL, DATABASE_USRE, DATABASE_PASSWORD);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dbConnection;
	}

	public static void closeConnection(Connection dbConnection) {
		try {
			if (dbConnection != null && (!dbConnection.isClosed())) {
				dbConnection.close();
			}
		} catch (SQLException sqlEx) {
			sqlEx.printStackTrace();
		}
	}

	public static void closeResultSet(ResultSet res) {
		try {
			if (res != null) {
				res.close();
				res = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void closeStatement(PreparedStatement pStatement) {
		try {
			if (pStatement != null) {
				pStatement.close();
				pStatement = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

DBUtil.java
package utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;

public class DBUtil {
	private static Connection conn;
	private static PreparedStatement pstmt;
	private static ResultSet rs;

	/**
	 * 增,删,改
	 * 
	 * @param sql
	 * @param objects
	 * @return
	 */
	public int execute(String sql, Object... objects) {
		int count = 0;
		try {
			getMysqlConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < objects.length; i++) {
				pstmt.setObject(i + 1, objects[i]);
			}
			count = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return count;
	}

	/**
	 * 查
	 * 
	 * @param str
	 * @param objects
	 * @return
	 */
	public CachedRowSet query(String str, Object... objects) {
		CachedRowSet cachedRowSet = null;
		try {
			getMysqlConnection();
			// cachedRowSet = new CachedRowSetImpl(); 不推荐使用
			RowSetFactory rowSetFactory = RowSetProvider.newFactory();
			cachedRowSet = rowSetFactory.createCachedRowSet();
			pstmt = conn.prepareStatement(str);
			for (int i = 0; i < objects.length; i++) {
				pstmt.setObject(i + 1, objects[i]);
			}
			rs = pstmt.executeQuery();
			cachedRowSet.populate(rs);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close();
		}
		return cachedRowSet;
	}

	/**
	 * 实现分页查询
	 * 
	 * @param str
	 * @param pageSize
	 * @param page
	 * @param objects
	 * @return
	 */
	public CachedRowSet queryByPage(String sql, int pageSize, int page, Object... objects) {
		CachedRowSet cachedRowSet = null;
		try {
			getMysqlConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < objects.length; i++) {
				pstmt.setObject(i + 1, objects[i]);
			}
			rs = pstmt.executeQuery();
			// 开始进行分页
			RowSetFactory rowSetFactory = RowSetProvider.newFactory();
			cachedRowSet = rowSetFactory.createCachedRowSet();
			// 参数判断
			if (pageSize < 1)
				pageSize = 1;
			if (page < 1)
				page = 1;
			cachedRowSet.setPageSize(pageSize);
			cachedRowSet.populate(rs, (page - 1) * pageSize + 1);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close();
		}
		return cachedRowSet;
	}

	// 获得mysql连接
	public static void getMysqlConnection() {
		conn = MysqlDBConnection.getConnction();
	}

	// 获得SqlServer连接
	public static void getSqlserverConnection() {
		conn = SQLServerDBConnection.getConnction();
	}

	// 关闭连接
	public void close() {
		MysqlDBConnection.closeResultSet(rs);
		MysqlDBConnection.closeStatement(pstmt);
		MysqlDBConnection.closeConnection(conn);
	}
}

4 值得注意的一点

在逻辑层的实现中持有的是数据访问层的接口,而非数据访问层的具体实现,调用接口中的方法来进行逻辑层的编写,实现解耦和,如下所示:

public class StudentServiceImpl implements StudentService {

	// 此处使用studentDAO的抽象而非具体实现,实现多态解耦和
	// private StudentDAOImpl studentDAOImpl = new StudentDAOIml();
	private StudentDAO studentDAO = new StudentDAOImpl();
	
}

参考

JavaEE——三层架构模式介绍
杨老师课堂之JavaWeb体系的MVC与三层架构有什么区别

你可能感兴趣的:(Java学习)