JavaEE架构

一.架构选型

1.VM架构

VM架构通常指的是虚拟机(Virtual Machine)的架构。虚拟机是一种软件实现的计算机系统,它模拟了物理计算机的功能,允许在单一物理硬件上运行多个操作系统实例。虚拟机架构主要包括以下几个关键组件:
1. 虚拟机监控器(Hypervisor):
   - 类型1 Hypervisor:直接运行在物理硬件上,也称为裸机Hypervisor。例如,VMware ESXi、Microsoft Hyper-V、Xen。
   - 类型2 Hypervisor:运行在宿主操作系统之上,例如VMware Workstation、Oracle VirtualBox。
2. 虚拟机(VM):
   - 每个虚拟机都包含一个完整的操作系统和应用程序,它们与物理硬件隔离,运行在虚拟化环境中。
3. 虚拟硬件:
   - 虚拟机通过虚拟硬件与物理硬件交互,包括虚拟CPU、虚拟内存、虚拟磁盘和虚拟网络接口等。
4. 管理工具:
   - 用于创建、配置、管理和监控虚拟机的工具,例如VMware vCenter、Microsoft System Center Virtual Machine Manager。
5. 存储和网络虚拟化:
   - 虚拟化技术还扩展到存储和网络资源,允许更灵活和高效地管理这些资源。
虚拟机架构的主要优势包括:
- 资源利用率:通过在一台物理服务器上运行多个虚拟机,可以更高效地利用硬件资源。
- 隔离性:每个虚拟机都是独立的,一个虚拟机的故障不会影响其他虚拟机。
- 灵活性:虚拟机可以轻松地迁移、复制和备份。
- 成本效益:减少了对物理硬件的需求,降低了硬件和维护成本。
虚拟机架构广泛应用于数据中心、云计算、开发和测试环境等场景。

2.MVC架构

MVC架构(Model-View-Controller)是一种广泛应用于软件工程中的设计模式,特别是在构建用户界面时。它将应用程序分为三个主要部分,以提高代码的组织性和可维护性。以下是MVC架构的详细介绍:

1. Model(模型):
   - 职责:负责管理应用程序的核心数据和业务逻辑。它直接与数据库或其他数据源交互,处理数据的获取、存储和更新。
   - 特点:独立于用户界面,不直接与用户交互。

2. View(视图):
   - 职责:负责显示数据(模型)给用户,并接收用户的输入。视图通常是从模型获取数据的用户界面元素。
   - 特点:不包含业务逻辑,只负责数据的展示和用户交互的呈现。

3. Controller(控制器):
   - 职责:作为模型和视图之间的中介,处理用户的输入并更新模型。控制器接收来自视图的用户操作,根据需要更新模型,并可能要求视图更新以反映模型的变化。
   - 特点:包含应用程序的逻辑,决定如何处理用户输入和更新视图。

MVC架构的主要优势包括:

- 分离关注点:通过将应用程序的不同方面分离,使得代码更易于管理和维护。
- 可复用性:模型和控制器可以在不同的视图中复用,减少了代码重复。
- 并行开发:不同的开发者可以同时工作在模型、视图和控制器上,提高了开发效率。
- 易于测试:分离的组件使得单元测试和集成测试更加容易。

MVC架构广泛应用于Web开发框架中,如Ruby on Rails、ASP.NET MVC、Spring MVC等。它帮助开发者构建结构清晰、易于扩展和维护的应用程序。

3.MVVC架构

MVVC架构(Model-View-ViewModel)是一种软件设计模式,它是MVC(Model-View-Controller)架构的一个变体,主要用于简化用户界面的开发,特别是在实现数据绑定和命令绑定的场景中。MVVC架构在WPF(Windows Presentation Foundation)、Silverlight以及一些现代Web框架如Knockout.js和Vue.js中得到了广泛应用。

MVVC架构的组成部分包括:

1. Model(模型):
   - 职责:代表应用程序的核心数据和业务逻辑。它通常包含数据访问层和业务规则,与MVC中的Model类似。
   - 特点:独立于用户界面,不直接与用户交互。

2. View(视图):
   - 职责:定义应用程序的用户界面。它负责展示数据(来自ViewModel)给用户,并接收用户的输入。
   - 特点:不包含业务逻辑,只负责数据的展示和用户交互的呈现。

3. ViewModel(视图模型):
   - 职责:作为视图和模型之间的桥梁,提供视图所需的数据和命令。ViewModel通常包含视图的状态和行为逻辑,它将模型的数据转换为视图可以轻松使用的形式。
   - 特点:包含视图的逻辑,但不直接引用视图,实现了视图和模型的解耦。

MVVC架构的关键特性是数据绑定,它允许视图和ViewModel之间的自动同步。当ViewModel中的数据发生变化时,视图会自动更新,反之亦然。这种双向数据绑定机制减少了手动更新UI的代码量,提高了开发效率。

MVVC架构的主要优势包括:

- 分离关注点:清晰地分离了视图、视图逻辑和业务逻辑,使得代码更易于管理和维护。
- 可测试性:ViewModel不依赖于视图,使得单元测试更加容易。
- 可复用性:ViewModel可以在不同的视图中复用,减少了代码重复。
- 简化开发:数据绑定和命令绑定减少了样板代码,加快了开发速度。

MVVC架构特别适合于需要复杂用户交互和数据展示的应用程序,它通过提供一种结构化的方式来组织代码,帮助开发者构建响应迅速、易于维护的应用程序。

二.项目架构

将分层思想转换为Java包

1.创建项目

2.创建包(“项目架构”)

2.1 dao(数据操作的抽象:CRUD

DAO(Data Access Object)是一种设计模式,用于抽象和封装对数据源的访问。它提供了一个接口,用于执行对数据库或其他持久化机制的操作,而不暴露底层数据访问的细节。DAO模式的主要目的是将业务逻辑与数据访问逻辑分离,从而提高代码的可维护性、可复用性和可测试性。

DAO模式通常包括以下几个组件:

1. **DAO接口**:
   - 定义了对数据源进行操作的方法,如创建、读取、更新和删除(CRUD)操作。
   - 接口使得可以在不改变业务逻辑的情况下更换数据访问的实现。

2. **DAO实现类**:
   - 实现了DAO接口,包含具体的SQL语句或使用ORM(对象关系映射)框架来与数据库交互。
   - 负责处理数据的持久化和检索。

3. **数据传输对象(DTO)**:
   - 用于在应用程序的不同层之间传输数据的简单对象。
   - 通常只包含属性和getter/setter方法,不包含业务逻辑。

4. **数据源**:
   - 可以是关系型数据库、NoSQL数据库、文件系统或其他任何形式的数据存储。

DAO模式的主要优势包括:

- **分离关注点**:业务逻辑不需要知道数据是如何持久化的,只需通过DAO接口与数据交互。
- **易于维护**:数据访问逻辑集中在一个地方,便于管理和优化。
- **提高可复用性**:DAO可以在不同的业务逻辑中复用,减少了代码重复。
- **增强可测试性**:可以通过模拟DAO接口来测试业务逻辑,而不需要实际访问数据库。

在实际应用中,DAO模式常常与其他设计模式如服务层模式结合使用,以进一步分离业务逻辑和数据访问逻辑。此外,现代框架如Spring和Hibernate提供了对DAO模式的支持,简化了数据访问层的开发。

2.2 entity

开发Entity的主要目的是在软件系统中对现实世界的对象或概念进行抽象和建模,以便更好地管理和操 作数据。具体目的包括:

数据抽象与封装

       抽象现实对象:Entity将现实世界的对象或概念抽象为代码中的数据结构,便于系统处理。

       封装数据与行为:Entity封装了对象的属性和行为,确保数据的一致性和完整性。

数据持久化

       与数据库映射:Entity通常与数据库表对应,简化数据存储与检索。

       ORM支持:通过对象关系映射(ORM),Entity可以直接与数据库交互,减少手动SQL操作。

2.3 service(解决项目中的业务问题)

Service 的核心职责
1. **封装业务逻辑**:
   - Service 层包含应用程序的核心业务逻辑,例如验证、计算、数据处理等。
   - 它确保业务规则的一致性和可维护性。

2. **协调数据访问**:
   - Service 层调用数据访问对象(DAO)或 Repository 来获取或存储数据。
   - 它可以在多个 DAO 或 Entity 之间协调复杂的操作。

3. **事务管理**:
   - Service 层通常负责管理事务(Transaction),确保多个操作在一个事务中执行。
   - 在 Java EE 中,可以使用 `@Transactional` 注解来声明事务边界。

4. **解耦表示层和数据访问层**:
   - Service 层作为中间层,将表示层(如 Controller)与数据访问层(如 DAO)解耦,使代码更易于维护和测试。

5. **提供可重用的服务**:
   - Service 层的方法可以被多个表示层组件(如 Web 控制器、REST 端点)调用,实现逻辑的复用。

2.4 controller

数据的传输

        前端到后台

        后台到前端

2.5 vo

View Object: 视图对象,也需要展示的对象

2.6 dto

DTO(Data Transfer Object,数据传输对象)是一种设计模式,用于在不同层或组件之间传输数据。DTO 的主要目的是封装数据,减少网络调用次数,并简化数据交换的过程。它通常是一个简单的 Java 类,包含属性和对应的 getter/setter 方法,不包含任何业务逻辑。

---

### DTO 的核心特点
1. **数据封装**:
   - DTO 是一个纯粹的数据容器,用于封装一组相关的数据。
   - 它通常只包含字段和访问这些字段的方法(getter/setter)。

2. **减少网络调用**:
   - 在分布式系统中,DTO 可以一次性传输大量数据,减少多次调用的开销。

3. **解耦层与层之间的依赖**:
   - DTO 用于在表示层(如前端)、服务层和持久层之间传递数据,避免直接暴露领域模型(Entity)。

4. **简化数据格式**:
   - DTO 可以根据需要调整数据的结构,例如过滤敏感信息、组合多个字段或转换数据格式。

5. **无业务逻辑**:
   - DTO 不包含任何业务逻辑,仅用于数据传输。

---

### DTO 的使用场景
1. **前后端数据交互**:
   - 在 RESTful API 中,DTO 用于封装请求和响应的数据。
2. **服务间通信**:
   - 在微服务架构中,DTO 用于在不同服务之间传递数据。
3. **数据脱敏**:
   - DTO 可以隐藏敏感信息(如密码、身份证号),只暴露必要的数据。
4. **数据聚合**:
   - DTO 可以将多个 Entity 或数据源的数据组合成一个对象,简化数据传输。

2.7 exception

项目的异常处理类

2.8 util

工具类

顺序随意(数据库->controller)

三.数据库

四.实体类(entity)

lombok:自动生成set/get,toString(),构造器

@Data //set/get 无参构造方法
@AllArgsConstructor //全参构造器
@NoArgsConstructor //无参构造器
public class User {
    private Integer id;
    private String username;
    private String password;
}

五.数据访问层(Dao)

1.接口

/**
 * 用户数据访问接口
 */
public interface IUserDao {
    /**
     * 添加数据
     * @param user
     */
    void save(User user);

    /**
     * 根据id删除
     * @param id
     */
    void deleteId(int id);

    /**
     * 修改数据
     * 对象指定的id
     * @param user
     */
    void update(User user);

    /**
     * 返回所有数据
     * @return 所有数据的集合
     */
    List<User> findAll();
}

2.实现类

/**
 * UserDao的实现类
 * @author 武鑫鑫
 */
public class UserDaoImpl implements IUserDao {
    @Override
    public void save(User user) {
        JdbcUtil.connect();
        String sql = "INSERT INTO user_tab(user_username,user_password) VALUES(?,?)";
        JdbcUtil.preparedStatement(sql,user.getUsername(),user.getPassword());
        JdbcUtil.executeUpdate();
        JdbcUtil.close();
    }

    @Override
    public void deleteId(int id) {
        JdbcUtil.connect();
        String sql = "DELETE FROM user_tab WHERE user_id = ?";
        JdbcUtil.preparedStatement(sql,id);
        JdbcUtil.executeUpdate();
        JdbcUtil.close();
    }

    @Override
    public void update(User user) {
        JdbcUtil.connect();
        String sql = "UPDATE user_tab SET user_password=? WHERE user_username=?";
        JdbcUtil.preparedStatement(sql,user.getPassword(),user.getUsername());
        JdbcUtil.executeUpdate();
        JdbcUtil.close();
    }

    @Override
    public List<User> findAll() {
        List<User> list = new ArrayList<>();
        JdbcUtil.connect();
        String sql = "SELECT * FROM user_tab";
        JdbcUtil.preparedStatement(sql);
        ResultSet rs = JdbcUtil.executeQuery();

        try {
            while (rs.next()){
                int id = rs.getInt("user_id");
                String username = rs.getString("user_username");
                String password = rs.getString("user_password");
                User user = new User(id,username,password);
                list.add(user);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        JdbcUtil.close();
        return list;
    }
}

六.DTO

模拟一个Result对象:职责将对象搬运到前端

1.Result

@Data
public class Result {

    private int code;
    private String msg;
    private Object results;
    private Date time;

    /**
     * 成功返回
     * @param results
     * @return
     */
    public static Result success(Object results){
        Result r = new Result();
        r.setCode(ResultCode.SUCCESS.getCode());
        r.setMsg(ResultCode.SUCCESS.getMsg());
        r.setResults(results);
        r.setTime(new Date());
        return r;
    }

    /**
     * 失败返回
     * @return
     */
    public static Result failed(){
        Result r = new Result();
        r.setCode(ResultCode.FAILED.getCode());
        r.setMsg(ResultCode.FAILED.getMsg());
        r.setTime(new Date());
        return r;
    }
}

2.ResultCode(枚举类)

/**
 * 枚举类:[代码."原因"]
 * 规范返回结果[代码,代码解析]
 */
@Getter
public enum ResultCode {
    SUCCESS(200,"成功"),
    FAILED(500,"失败");

    private Integer code;
    private String msg;

    /**
     * 构造器
     *
     * @param code
     * @param msg
     */
    private ResultCode(Integer code,String msg){
        this.code = code;
        this.msg = msg;
    }
}

七.JdbcUtil

JDBC的简单封装工具类

1.引入依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

2.jdbc五部曲

2.1 注册驱动

 //只运行一次
    static {
        registry();
    }

    /**
     * 1.注册驱动
     */
    private static void registry(){
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

2.2 建立连接

    /**
     * 2.建立连接
     */
    public static void connect(){
        try {
            conn = DriverManager.getConnection(URL,USERNAME,PASSWORD);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

2.3 预处理

执行SQL语句

    /**
     * 3.预处理SQL
     * @param sql
     * @param values
     */
    public static void preparedStatement(String sql,Object... values){
        try {
            pst = conn.prepareStatement(sql);
            for (int i=0;i<values.length;i++){
                pst.setObject(i+1,values[i]);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

2.4 执行SQL

(1)执行增删改操作

    /**
     * 4.1执行增删改
     */
    public static void executeUpdate(){
        try {
            pst.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

(2)执行查询操作

    /**
     * 4.2执行查询
     * @return
     */
    public static ResultSet executeQuery(){
        try {
            rs = pst.executeQuery();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return rs;
    }

2.5 关闭数据库连接

    /**
     * 5.关闭数据库的连接
     */
    public static void close(){
        try {
            if(rs!=null){
                rs.close();
            }
            if(pst!=null){
                pst.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

八.service

业务

public interface IUserService {
    /**
     * 添加用户
     * @param user
     */
    void add(User user);
    void updateUser(User user);
    void removeById(int id);
    List<User> findAll();
}
public class UserServiceImpl implements IUserService {
    private IUserDao userDao;

    public UserServiceImpl() {
        this.userDao = new UserDaoImpl();
    }

    @Override
    public void add(User user) {
        userDao.save(user);
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
    }

    @Override
    public void removeById(int id) {
        userDao.deleteId(id);
    }

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }
}

九.单元测试

1.引入单元测试框架(JUnit)

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

2.测试用例

public class UserServiceImplTest {
    private IUserService ius;

    @Before
    public void init(){
        ius = new UserServiceImpl();
    }

    @Test
    public void add() {
        User user = new User();
        user.setUsername("wjx");
        user.setPassword("888");
        ius.add(user);
    }

    @Test
    public void updateUser() {
        User user = new User();
        user.setUsername("wjx");
        user.setPassword("666");
        ius.updateUser(user);
    }

    @Test
    public void removeById() {
        ius.removeById(1);
    }

    @Test
    public void findAll(){
        List<User> all = ius.findAll();
        Assert.assertEquals(1,all.size());
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967571.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

车载测试工具 --- CANoe VH6501 进行Not Acknowledge (NAck) 测试

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

第40天:Web开发-JS应用VueJS框架Vite构建启动打包渲染XSS源码泄露代码审计

#知识点 1、安全开发-VueJS-搭建启动&打包安全 2、安全开发-VueJS-源码泄漏&代码审计 一、Vue搭建创建项目启动项目 1、Vue 框架搭建->基于nodejs搭建&#xff0c;安装nodejs即可 参考&#xff1a;https://cn.vuejs.org/ 已安装18.3或更高版本的Node.js 2、Vue 创建…

Axure原型图怎么通过链接共享

一、进入Axure 二、点击共享 三、弹出下面弹框&#xff0c;点击发布就可以了 发布成功后&#xff0c;会展示链接&#xff0c;复制即可共享给他人 四、发布失败可能的原因 Axure未更新&#xff0c;首页菜单栏点击帮助选择Axure更新&#xff0c;完成更新重复以上步骤即可

DeepSeek本地化部署

DeepSeek本地化部署 本教程为一键式部署&#xff0c;适合于mac、ubuntu、windows。【开源地址】 环境要求 nodejs > 18Python > 3.10.12 步骤一&#xff1a;安装ollama客户端 官网直接安装&#xff0c;ollama官网。安装完成后使用命令&#xff1a;ollama -h&#xf…

单片机学习笔记——入门51单片机

一、单片机基础介绍 1.何为单片机 单片机&#xff0c;英文Micro Controller Unit&#xff0c;简称MCU 。内部集成了中央处理器CPU、随机存储器ROM、只读存储器RAM、定时器/计算器、中断系统和IO口等一系列电脑的常用硬件功能 单片机的任务是信息采集&#xff08;依靠传感器&a…

DeepSeek-R1相关论文解读

另&#xff1a;数学推理论文篇&#xff1a;DeepSeekMath 一、DeepSeek-R1-Zero和DeepSeek R1区别 都使用了RL强化学习中的GROP&#xff0c;但是R1还使用了SFT&#xff0c;进行了多阶段训练。 1. 什么是SFT&#xff1f; SFT是给模型一些正确例子&#xff1a;情况1 answer&…

【AIGC】语言模型的发展历程:从统计方法到大规模预训练模型的演化

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;语言模型的发展历程&#xff1a;从统计方法到大规模预训练模型的演化1 统计语言模型&#xff08;Statistical Language Model, SLM&#xff09;&#xff1a;统…

ArcGIS Pro批量创建离线服务sd包

背景&#xff1a; 主要针对一个工程内有多个地图框项&#xff1a; 处理方法&#xff1a;通过Python脚本处理打包。 运行环境 在Pro的Python环境中去运行编写的Python脚本。 Python 脚本参考 import arcpy import os# Set output file names outdir r"d:\data\out&…

天津三石峰科技——汽车生产厂的设备振动检测项目案例

汽车产线有很多传动设备需要长期在线运行&#xff0c;会出现老化、疲劳、磨损等 问题&#xff0c;为了避免意外停机造成损失&#xff0c;需要加装一些健康监测设备&#xff0c;监测设备运 行状态。天津三石峰科技采用 12 通道振动信号采集卡&#xff08;下图 1&#xff09;对…

【Linux】深入理解linux权限

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …

三次握手,四次挥手,服务器模型(多进程并发,线程),基于套接字的UDP通信

三次握手&#xff1a; 第一次握手&#xff1a;客户端向服务器发送SYN待确认数据x, 客户端进入SYN_SEND状态​ 第二次握手&#xff1a;服务器向客户端回传一条ACK应答数据x1, 同时发送一条SYN待确认数据y&#xff0c;服务器进入SYN_RECV状态​ 第三次握手&#xff1a;客户端向服…

PostgreSQL的学习心得和知识总结(一百六十七)|深入理解PostgreSQL数据库之静态语法检查工具PgSanity的使用和实现

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库链接,点击前往 4、日本著名PostgreSQL数据库专家 铃木启修 网站…

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的&#xff01;在上篇我们学习了单向链表&#xff0c;而单向链表虽然空间利用率高&#xff0c;插入和删除也只需改变指针就可以达到&#xff01;但是我们在每次查找、删除、访问..…

Docker 之mysql从头开始——Docker下mysql安装、启动、配置、进入容器执行(查询)sql

一、Docker 之mysql安装配置 步骤一&#xff1a;拉取镜像 1. 查看是否包含已安装的mysql。 docker images | grep mysql 2. 如上图所示&#xff0c;我们有mysql镜像&#xff0c;所以不必对mysql镜像进行拉取&#xff0c;如若没有上图中的惊喜&#xff0c;使用如下命令进行拉取…

网易日常实习一面面经

1. 自我介绍 2. 两道代码题&#xff1a; 第一道题&#xff1a;写一道链表排序题要求空间复杂度O(1) &#xff1a;已ac 插入排序算法 时间复杂度 O(N^2)&#xff0c;空间复杂度O(1) class ListNode{int val;ListNode next;public ListNode(int x) {this.val x;} } public cl…

DeepSeek LLM 论文解读:相信长期主义开源理念可扩展大语言模型(DeepSeek 吹响通用人工智能的号角)

论文链接&#xff1a;DeepSeek LLM: Scaling Open-Source Language Models with Longtermism&#xff08;相信长期主义开源理念可扩展大语言模型&#xff09; 目录 摘要一、数据处理&#xff08;一&#xff09;数据清洗与丰富&#xff08;二&#xff09;分词器与词汇设置 二、模…

02DevOps基础环境准备

准备两台Linux的操作系统&#xff0c;最简单的方式就是在本机上使用虚拟机搭建两个操作系统&#xff08;实际生产环境是两台服务器&#xff0c;虚拟机的方式用于学习使用&#xff09; 我搭建的两台服务器的ip分别是192.168.1.10、192.168.1.11 192.168.1.10服务器用于安装doc…

基于 SpringBoot 和 Vue 的智能腰带健康监测数据可视化平台开发(文末联系,整套资料提供)

基于 SpringBoot 和 Vue 的智能腰带健康监测数据可视化平台开发 一、系统介绍 随着人们生活水平的提高和健康意识的增强&#xff0c;智能健康监测设备越来越受到关注。智能腰带作为一种新型的健康监测设备&#xff0c;能够实时采集用户的腰部健康数据&#xff0c;如姿势、运动…

表单与交互:HTML表单标签全面解析

目录 前言 一.HTML表单的基本结构 基本结构 示例 二.常用表单控件 文本输入框 选择控件 文件上传 按钮 综合案例 三.标签的作用 四.注意事项 前言 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础&#xff0c;其中表单&#xff08;<form>&…

vue3中使用print-js组件实现打印操作

第一步&#xff1a;安装依赖 yarn add print-js 第二步&#xff1a;创建打印组件&#xff1a;PrintHtmlComp.vue <template><div id"printArea_123456789"><!-- 默认插槽&#xff0c;传入打印内容 --><slot></slot></div>…