当前位置: 首页 > news >正文

java-mysql 三层架构

在 Java 应用程序中,三层架构(Three-Tier Architecture)是一种常见的设计模式,用于分离应用程序的表示层、业务逻辑层和数据访问层。这种架构有助于提高代码的可维护性、可扩展性和可重用性。以下是详细解释 Java 应用程序中使用 MySQL 的三层架构:

### 一、三层架构简介

1. **表示层(Presentation Layer)**:
   - 负责与用户交互,包括用户界面(UI)的展示和用户输入的处理。
   - 通常包含 JSP、Servlet 或其他前端技术(如 Thymeleaf、Angular、React 等)。

2. **业务逻辑层(Business Logic Layer)**:
   - 处理应用程序的业务逻辑,执行具体的业务操作。
   - 通常包含服务类(Service)、业务对象(BO)等。

3. **数据访问层(Data Access Layer)**:
   - 负责与数据库进行交互,执行数据的持久化操作。
   - 通常包含数据访问对象(DAO)类。

### 二、示例应用程序

假设我们有一个简单的应用程序,用于管理用户信息,包括用户的 `id` 和 `name`。以下是使用 MySQL 的三层架构示例。

#### 1. 数据库表

首先,创建一个 MySQL 数据库表 `users`:

```sql
CREATE DATABASE testdb;

USE testdb;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);
```

#### 2. 数据访问层(DAO)

定义一个数据访问对象(DAO)类,用于与数据库进行交互。

```java
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;

public class UserDAO {
    private String jdbcURL = "jdbc:mysql://localhost:3306/testdb";
    private String jdbcUsername = "root";
    private String jdbcPassword = "yourpassword";

    private static final String INSERT_USERS_SQL = "INSERT INTO users (name) VALUES (?);";
    private static final String SELECT_USER_BY_ID = "SELECT id, name FROM users WHERE id = ?";
    private static final String SELECT_ALL_USERS = "SELECT * FROM users";
    private static final String DELETE_USER_SQL = "DELETE FROM users WHERE id = ?;";
    private static final String UPDATE_USER_SQL = "UPDATE users SET name = ? WHERE id = ?;";

    protected Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return connection;
    }

    public void insertUser(User user) throws SQLException {
        try (Connection connection = getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
            preparedStatement.setString(1, user.getName());
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public User selectUser(int id) {
        User user = null;
        try (Connection connection = getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(SELECT_USER_BY_ID)) {
            preparedStatement.setInt(1, id);
            ResultSet rs = preparedStatement.executeQuery();

            while (rs.next()) {
                String name = rs.getString("name");
                user = new User(id, name);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return user;
    }

    public List<User> selectAllUsers() {
        List<User> users = new ArrayList<>();
        try (Connection connection = getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(SELECT_ALL_USERS)) {
            ResultSet rs = preparedStatement.executeQuery();

            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                users.add(new User(id, name));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }

    public boolean deleteUser(int id) throws SQLException {
        boolean rowDeleted;
        try (Connection connection = getConnection();
             PreparedStatement statement = connection.prepareStatement(DELETE_USER_SQL)) {
            statement.setInt(1, id);
            rowDeleted = statement.executeUpdate() > 0;
        }
        return rowDeleted;
    }

    public boolean updateUser(User user) throws SQLException {
        boolean rowUpdated;
        try (Connection connection = getConnection();
             PreparedStatement statement = connection.prepareStatement(UPDATE_USER_SQL)) {
            statement.setString(1, user.getName());
            statement.setInt(2, user.getId());
            rowUpdated = statement.executeUpdate() > 0;
        }
        return rowUpdated;
    }
}
```

#### 3. 业务逻辑层(Service)

定义一个服务类,处理应用程序的业务逻辑。

```java
import java.sql.SQLException;
import java.util.List;

public class UserService {
    private UserDAO userDAO;

    public UserService() {
        userDAO = new UserDAO();
    }

    public void addUser(User user) {
        try {
            userDAO.insertUser(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public User getUser(int id) {
        return userDAO.selectUser(id);
    }

    public List<User> getAllUsers() {
        return userDAO.selectAllUsers();
    }

    public void updateUser(User user) {
        try {
            userDAO.updateUser(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void deleteUser(int id) {
        try {
            userDAO.deleteUser(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
```

#### 4. 表示层(Servlet)

使用 Servlet 处理用户请求和响应。

```java
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/")
public class UserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private UserService userService;

    public void init() {
        userService = new UserService();
    }

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getServletPath();

        try {
            switch (action) {
                case "/new":
                    showNewForm(request, response);
                    break;
                case "/insert":
                    insertUser(request, response);
                    break;
                case "/delete":
                    deleteUser(request, response);
                    break;
                case "/edit":
                    showEditForm(request, response);
                    break;
                case "/update":
                    updateUser(request, response);
                    break;
                default:
                    listUser(request, response);
                    break;
            }
        } catch (SQLException ex) {
            throw new ServletException(ex);
        }
    }

    private void listUser(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException, ServletException {
        List<User> listUser = userService.getAllUsers();
        request.setAttribute("listUser", listUser);
        RequestDispatcher dispatcher = request.getRequestDispatcher("user-list.jsp");
        dispatcher.forward(request, response);
    }

    private void showNewForm(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher("user-form.jsp");
        dispatcher.forward(request, response);
    }

    private void showEditForm(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, ServletException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        User existingUser = userService.getUser(id);
        RequestDispatcher dispatcher = request.getRequestDispatcher("user-form.jsp");
        request.setAttribute("user", existingUser);
        dispatcher.forward(request, response);
    }

    private void insertUser(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        String name = request.getParameter("name");
        User newUser = new User(name);
        userService.addUser(newUser);
        response.sendRedirect("list");
    }

    private void updateUser(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        String name = request.getParameter("name");

        User user = new User(id, name);
        userService.updateUser(user);
        response.sendRedirect("list");
    }

    private void deleteUser(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        userService.deleteUser(id);
        response.sendRedirect("list");
    }
}
```

#### 5. 用户实体类(User)

定义一个用户实体类,表示数据库表 `users` 中的记录。

```java
public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public User(String name) {


        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
```

#### 6. JSP 页面

定义两个 JSP 页面:一个用于显示用户列表,另一个用于用户表单。

**user-list.jsp**:

```jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>User List</title>
</head>
<body>
<h2>User List</h2>
<a href="new">Add New User</a>
<table border="1">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Actions</th>
    </tr>
    <c:forEach var="user" items="${listUser}">
        <tr>
            <td>${user.id}</td>
            <td>${user.name}</td>
            <td>
                <a href="edit?id=${user.id}">Edit</a>
                <a href="delete?id=${user.id}">Delete</a>
            </td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

相关文章:

java-mysql 三层架构

在 Java 应用程序中&#xff0c;三层架构&#xff08;Three-Tier Architecture&#xff09;是一种常见的设计模式&#xff0c;用于分离应用程序的表示层、业务逻辑层和数据访问层。这种架构有助于提高代码的可维护性、可扩展性和可重用性。以下是详细解释 Java 应用程序中使用 …...

打工人如何应对AI对工作岗位的风险

面对AI对工作岗位的潜在取代&#xff0c;我们可以从多个层面制定应对策略&#xff0c;以确保劳动力市场的平稳过渡和社会的可持续发展。以下是一些具体的应对策略&#xff1a; 一、加强教育与培训 提升STEM教育&#xff1a;增加科学、技术、工程和数学&#xff08;STEM&#…...

C++:从C语言过渡到C++

在这篇博客中&#xff0c;我将会介绍从C语言过渡到C的一些基础知识。 目录 C起源 C的关键字 输出hello&#xff0c;world ​编辑 命名空间 1.什么是命名空间 2.namespace的作用 3.域作用限定符 4.命名空间的使用 IO流 缺省参数 函数重载 引用 1.引用的定义 2.引…...

在安卓中使用FFmpeg录制摄像头的视频并保存到本地MP4文件

在移动应用开发中&#xff0c;有时需要利用设备的摄像头录制视频&#xff0c;并且希望在录制过程中能够精确控制视频的质量、格式和时长。FFmpeg作为一个强大的多媒体处理工具&#xff0c;提供了广泛的功能和选项&#xff0c;能够帮助我们实现这样的需求。 添加依赖 在安卓平台…...

Vue从零到实战第一天

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

BUUCTF - Basic

文章目录 1. Linux Labs 【SSH连接漏洞】2. BUU LFI COURSE【文件包含漏洞】3. BUU BRUTE【暴力破解用户名密码】4. BUU SQL COURSE【SQL注入-当前数据库】5. Upload-Labs-Linux 1【文件上传漏洞】7. Buu Upload Course 1【文件上传包含漏洞】8. sqli-labs 1【SQL注入-服务器上…...

如何理解Node.js?NPM?Yarn?Vue?React?

一、背景 对后端技术栈更熟悉&#xff0c;对前端技术栈不了解&#xff0c;希望通过前后端的技术栈进行对比&#xff0c;可以更直观地了解前端技术栈。 二、Node.js Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JavaScript 运行环境。它使得 JavaScript 可以在服务器端运…...

苹果入局,AI手机或将实现“真智能”?

【潮汐商业评论/原创】 “AI应用智能手机不就是现在的AI手机。” 当被问到现阶段对AI手机的看法时&#xff0c;John如是说。“术业有专攻&#xff0c;那么多APP在做AI功能&#xff0c;下载用就是了&#xff0c;也用不着现在换个AI手机啊。” 对于AI手机&#xff0c;或许大多…...

AI网络爬虫019:搜狗图片的时间戳反爬虫应对策略

文章目录 一、介绍二、输入内容三、输出内容一、介绍 如何批量爬取下载搜狗图片搜索结果页面的图片?以孙允珠这个关键词的搜索结果为例: https://pic.sogou.com/pics? 翻页规律如下: https://pic.sogou.com/napi/pc/searchList?mode=2&start=384&xml_len=48&am…...

Windows 网络重置及重置网络可能出现的问题( WIFI 没有了 / WLAN 图标消失)

当 Windows 网络出现本机故障时&#xff0c;一般从以下两个方面解决&#xff1a;网络栈和使用网络栈的组件或程序。 1、Winsock 组件问题 以管理身份运行 cmd&#xff0c;输入以下命令 netsh winsock reset重置 Winsock 组件以修复网络连接问题。 Winsock 是 Windows 操作系…...

100 个网络基础知识普及,看完成半个网络高手!

1&#xff09;什么是链接&#xff1f; 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2&#xff09;OSI 参考模型的层次是什么&#xff1f; 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0…...

高盛开源的量化金融 Python 库

GS Quant GS Quant是用于量化金融的Python工具包&#xff0c;建立在世界上最强大的风险转移平台之一之上。旨在加速量化交易策略和风险管理解决方案的开发&#xff0c;凭借25年的全球市场经验精心打造。 它由高盛的定量开发人员&#xff08;定量&#xff09;创建和维护&#…...

【Linux】docker和docker-compose 区别是什么

Docker 和 Docker Compose 是用于容器化应用的工具,它们在开发、部署和管理容器化应用程序时有不同的作用。以下是对它们的简要介绍和功能描述: Docker 定义: Docker 是一个开源的平台,允许开发者自动化地部署、扩展和管理应用程序容器。容器是一种轻量级、可移植、独立的软…...

Qt图片缩放显示

在Qt中&#xff0c;如果你想显示图片的像素或者对图片进行缩放显示&#xff0c;可以使用 QImage 类来处理图片数据&#xff0c;并使用 QLabel 或自定义的 QWidget 来显示图片&#xff0c;但是很难通过鼠标进行缩放显示 QGraphicsView可以实现此功能 在Qt中&#xff0c;QGraphi…...

47、lvs之DR

1、DR模式&#xff1a; 1.1、lvs三种模式&#xff1a; nat 地址转换 DR 直接路由模式 tun 隧道模式 1.2、DR模式的特点&#xff1a; 调度器在整个lvs集群当中是最重要的&#xff0c;在nat模式下&#xff0c;即负载接收请求&#xff0c;同时根据负载均衡的算法转发流量&…...

分布式技术栈、微服务架构 区分

1.分布式技术栈 这些技术栈都是为了更好的开发分布式架构的项目。 &#xff08;大营销平台的系统框架如下图&#xff0c;扩展的分布式技术栈&#xff09; &#xff08;1&#xff09;Dubbo——分布式技术栈 DubboNacos注册中心是应用可以分布式部署&#xff0c;并且提供RPC接…...

【JavaEE精炼宝库】文件操作(2)——文件内容读写 | IO流

文章目录 一、输入流1.1 InputStream 概述&#xff1a;1.2 read 方法详解&#xff1a;1.3 close 方法&#xff1a;1.4 利用 Scanner 进行读操作&#xff1a;1.5 Reader&#xff1a; 二、输出流2.1 OutputStream 概述&#xff1a;2.2 write 方法详解&#xff1a;2.3 利用 PrintW…...

C++ 指针变量做参数传递时的情况分析

前言 指针变量作为参数传递时&#xff0c;很容易混淆指针本身和指针指向的内容&#xff0c;实际应用中可能会导致无法预料的问题&#xff0c;所以做一下详细分析。 注意&#xff0c;在测试过程中为了看测试效果&#xff0c;有些指针变量分配了空间&#xff0c;但是未做回收&am…...

Linux环境下Oracle 11g的离线安装与配置历程

在成功体验了 Windows 版本的Oracle 11g 后&#xff0c;这几天心血来潮&#xff0c;决定再挑战一下Linux 环境下的安装&#xff0c;特别是在考虑到部门内部虚拟机无法联网的情况下&#xff0c;我选择了在CentOS 7上进行离线安装。这次安装之旅&#xff0c;主要参考了下面大佬的…...

上位机图像处理和嵌入式模块部署(mcu项目2:串口日志记录器)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 淘宝上面有一个商品蛮好玩的&#xff0c;那就是日志记录器。说是记录器&#xff0c;其实就是一个模块&#xff0c;这个模块的输入是一个ttl串口&am…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...