通常意义上的三层架构指的就是表现层、逻辑层、数据访问层。区分层次的目的是为了实现高内聚,低耦合的思想,层是一种弱耦合结构,层与层之间的依赖是向下的,底层对于上层而言是“无知”的,改变上层的设计对于其调用的底层而言没有任何影响。
表现层也称表示层,主要用于显示数据和接收用户输入。
业务逻辑写在逻辑层内,逻辑层是系统架构中体现核心价值的一部分,起到数据交换中承上启下的作用。对于数据访问层而言,它是调用者;对于表示层而言,它却是被调用者。
数据访问层也称持久层,主要用于实现对数据库的访问。
这是一个实现学生的增删改查的案例。
创建数据库代码:
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;
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();
}
}
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);
}
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")));
}
}
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;
}
}
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();
}
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;
}
}
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();
}
}
}
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);
}
}
在逻辑层的实现中持有的是数据访问层的接口,而非数据访问层的具体实现,调用接口中的方法来进行逻辑层的编写,实现解耦和,如下所示:
public class StudentServiceImpl implements StudentService {
// 此处使用studentDAO的抽象而非具体实现,实现多态解耦和
// private StudentDAOImpl studentDAOImpl = new StudentDAOIml();
private StudentDAO studentDAO = new StudentDAOImpl();
}
JavaEE——三层架构模式介绍
杨老师课堂之JavaWeb体系的MVC与三层架构有什么区别