SpringBoot+Vue3+Element Plus 打造分布式存储体系

中心代码,注释必读

// download:3w ukoou com

分布式存储体系是一种将很多数据存储在多台核算机上的存储体系,它能够将数据拆分成多个部分存储在不同的核算机上,从而达到数据备份、负载均衡、容错和灵敏扩展等意图。

该体系的效果有以下几个方面:

  1. 数据备份:分布式存储体系能够将数据存储在多台核算机上,当其间某一个核算机产生毛病时,备份的数据能够被用来康复数据,确保数据的安全性。

  2. 负载均衡:在传统的单个存储设备中,数据存储的容量有限,当数据量过大时,就需求将数据存储在多个设备上。分布式存储体系能够完成数据的自动分配,防止出现某个节点过载的状况,确保数据存储的平衡性。

  3. 容错性:分布式存储体系能够通过多个节点的数据备份和冗余存储,当某个主节点毛病时,备份节点能够接收服务,从而完成数据的无误康复,确保存储体系的高可用性。

分布式存储体系的意义十分严重,它为大规模数据的存储和办理供给了新的思路,有效地解决了传统存储体系中遇到的数据办理难题,同时也为云核算、大数据等技术的发展供给了支持和保证,能够说是当时技术领域的一项重要基础设施。

SpringBoot+Vue3+ElementPlus开发分布式存储体系后台

首要,咱们需求清晰这个项意图根本结构,这个项目是由后端、前端、数据层三部分构成的,咱们将采用前后端别离的办法,前端运用Vue3和ElementPlus进行开发,后端运用SpringBoot进行开发,数据库运用MySQL进行操作。

第一步:项目建立

1.1 创立SpringBoot项目

咱们首要需求创立一个SpringBoot项目。运用IDEA,新建一个SpringBoot项目,选择Maven类型的项目,并翻开Spring Initializr,依据咱们的需求选择需求的模块,包括Web、JPA、MySQL、Druid等。然后,点击Generate按钮,项目就建好了。

1.2 建立前端环境

进入前端工程目录下,运用指令vue create 创立 Vue3 项目模板,并增加 Element Plus 框架依赖。

vue create vue3-elementplus-demo
cd vue3-elementplus-demo
npm install element-plus --save

1.3 建立后端环境

在 Spring Boot 工程中,修改 application.properties 装备文件信息,加入对 MySQL 和 Druid 的装备。在 pom.xml 文件中增加对相关依赖的装备,如下:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>1.1.16</version>
</dependency>

以上装备完成后,咱们就根本构建好了项意图根本结构。

第二步:开发后台接口

2.1 创立数据模型

src/main/java 目录下创立一个名为 com.example.demo.entity 的包,用于寄存实体类。在这个包下创立一个名为 User.java 的类,表示用户的根本信息,包含 用户名暗码

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    // getter和setter办法省掉
}

2.2 创立数据访问层

src/main/java 目录下创立一个名为 com.example.demo.repository 的包,用于寄存数据访问层的代码,即耐久层。在这个包下创立一个名为 UserRepository.java 的接口,承继JpaRepository接口,并增加一个依照用户名查询用户信息的办法。

@Repository
public interface UserRepository extends JpaRepository<User, Long>{
    User findByUsername(String username);
}

2.3 创立服务层

src/main/java 目录下创立一个名为 com.example.demo.service 的包,用于寄存服务层的代码,即事务层。在这个包下创立一个名为 UserService.java 的类,用于处理用户相关的事务逻辑,包括登录、注册、修改暗码等等。

@Service
public class UserService{
    @Autowired
    private UserRepository userRepository;
    public User checkUser(String username, String password) {
        User user = userRepository.findByUsername(username);
        if (user != null && password.equals(user.getPassword())) {
            user.setPassword(null);
            return user;
        }
        return null;
    }
    // 增加其他事务逻辑办法(例如:注册、修改暗码等等)
}

2.4 创立操控层

src/main/java 目录下创立一个名为 com.example.demo.controller 的包,用于寄存操控层的代码,即接口层。在这个包下创立一个名为 LoginController.java 的类,用于处理用户登录相关的恳求。

@RestController
@RequestMapping("/api")
public class LoginController {
    @Autowired
    private UserService userService;
    @PostMapping("/login")
    public Result login(@RequestBody User user) {
        String username = user.getUsername();
        String password = user.getPassword();
        User u = userService.checkUser(username, password);
        if (u == null) {
            return ResultFactory.buildFailResult("用户名或暗码过错!");
        } else {
            return ResultFactory.buildSuccessResult(u);
        }
    }
}

第三步:开发前端页面

3.1 创立登录页面

咱们需求创立一个登录页面,让用户输入用户名和暗码,然后提交到后台进行验证。咱们运用 Element Plus 中的表单组件来增加输入框,用到了 el-formel-form-itemel-inputel-button

<template>
  <div class="login-container">
    <el-form ref="form" :model="form" :rules="rules" class="form-container">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="form.username"></el-input>
      </el-form-item>
      <el-form-item label="暗码" prop="password">
        <el-input type="password" v-model="form.password"></el-input>
      </el-form-item>
      <div class="form-btn-container">
        <el-button type="primary" @click="handleSubmit('form')">登录</el-button>
        <el-button>重置</el-button>
      </div>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "Login",
  data() {
    return {
      form: {
        username: "",
        password: "",
      },
      rules: {
        username: [
          { required: true, message: "请输入用户名", trigger: "blur" },
        ],
        password: [
          { required: true, message: "请输入暗码", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    async handleSubmit(formName) {
      const { data: res } = await this.$axios.post("/api/login", this.form);
      if (res.code === 200) {
        this.$message.success("登录成功!");
        this.$router.push({ name: "dashboard" });
      } else {
        this.$message.error(res.message);
      }
    },
  },
};
</script>

其间,form 对象是用来寄存用户输入的用户名和暗码,rules 对象是用来定义输入框的校验规则,handleSubmit 办法是用来提交登录表单的,提交成功后跳转到 dashboard 页面。

3.2 创立主页

咱们需求创立一个主页,用来展示后台的各种功用。这儿咱们运用 Element Plus 中的布局组件来创立一个根本的页面布局,用到了 el-containerel-asideel-headerel-containerel-mainel-menuel-submenuel-menu-item 等组件。

<template>
  <div class="dashboard-container">
    <el-container style="height: 100%">
      <el-header style="height: 50px;">
        <div class="dashboard-title">后台办理体系</div>
        <el-button class="logout-btn" @click="handleLogout">退出登录</el-button>
      </el-header>
      <el-container style="height: calc(100% - 50px);">
        <el-aside style="width: 200px; padding: 10px;">
          <el-menu
            default-active="1"
            background-color="#333"
            text-color="#fff"
            active-text-color="#ffd04b"
            class="el-menu-vertical-demo"
            :collapse.sync="isCollapse"
          >
            <el-submenu index="1">
              <template slot="title">
                <i class="el-icon-location"></i>
                <span slot="title">导航一</span>
              </template>
              <el-menu-item index="1-1">选项1</el-menu-item>
              <el-menu-item index="1-2">选项2</el-menu-item>
              <el-menu-item index="1-3">选项3</el-menu-item>
            </el-submenu>
            <el-submenu index="2">
              <template slot="title">
                <i class="el-icon-menu"></i>
                <span slot="title">导航二</span>
              </template>
              <el-menu-item index="2-1">选项1</el-menu-item>
              <el-menu-item index="2-2">选项2</el-menu-item>
              <el-menu-item index="2-3">选项3</el-menu-item>
            </el-submenu>
            <el-submenu index="3">
              <template slot="title">
                <i class="el-icon-setting"></i>
                <span slot="title">导航三</span>
              </template>
              <el-menu-item index="3-1">选项1</el-menu-item>
              <el-menu-item index="3-2">选项2</el-menu-item>
              <el-menu-item index="3-3">选项3</el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <el-main style="padding:10px;">
          <router-view />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
export default {
  name: "Dashboard",
  data() {
    return {
      isCollapse: false,
    };
  },
  methods: {
    handleLogout() {
      this.$router.push({ name: "login" });
    },
  },
};
</script>

其间,咱们运用了 el-menu 组件来增加导航菜单,用到了 default-activebackground-colortext-coloractive-text-colorcollapse.sync 等属性来定义菜单的根本属性。

第四步:将前后端连接起来

咱们需求让前后端进行连接,即前端向后端发送恳求,后端回来数据给前端。这儿咱们运用 Axios 来发送 HTTP 恳求,并运用 SpringBoot 供给的 @RestController 注解来处理恳求。

4.1 装备跨域

在 Spring Boot 中,咱们需求先装备跨域,否则前端将无法恳求后台。翻开 com.example.demo 下的 CorsConfig.java 文件,增加跨域装备信息:

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 答应任何域名运用
        corsConfiguration.addAllowedHeader("*"); // 答应任何头
        corsConfiguration.addAllowedMethod("*"); // 答应任何办法(post、get等)
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 对一切接口路径进行跨域设置
        return new CorsFilter(source);
    }
}

4.2 处理恳求

在前面的代码中,咱们现已创立了一个 LoginController类来处理用户登录恳求。咱们还需求创立一些其他的操控层代码,如退出登录、用户信息办理等等。这儿就不一一赘述了,下面是一个样例代码,你能够参阅一下:

@RestController
@RequestMapping("/api")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        User u = userService.checkUser(user.getUsername());
        if (u != null) {
            return ResultFactory.buildFailResult("用户名已被注册!");
        } else {
            // 增加相关事务逻辑,省掉
        }
    }
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody User user) {
        User u = userService.checkUser(user.getUsername());
        if (u == null) {
            return ResultFactory.buildFailResult("用户不存在!");
        } else {
            // 增加相关事务逻辑,省掉
        }
    }
    // 其他相关恳求处理办法,省掉
}

4.3 发送恳求

在前端中,咱们运用 axios 来发送恳求。config.js 文件是咱们的恳求地址的装备文件。登录页面将用户输入的信息打包成恳求体发送到后台接口 /api/login 进行验证,并依据后台回来的数据判断登录是否成功。

import axios from "axios";
import { message } from "ant-design-vue";
import { getToken } from "./auth";
// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000, // request timeout
});
// request interceptor
service.interceptors.request.use(
  (config) => {
    // do something before request is sent
    if (getToken()) {
      config.headers["Authorization"] = "Bearer " + getToken();
    }
    return config;
  },
  (error) => {
    // do something with request error
    console.log(error); // for debug
    return Promise.reject(error);
  }
);
// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */
  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  (response) => {
    const res = response.data;
    // if the custom code is not 20000, it is judged as an error.
    if (res.code !== 200) {
      message.error(res.message || "Error");
      return Promise.reject(new Error(res.message || "Error"));
    } else {
      return res;
    }
  },
  (error) => {
    console.log("err" + error); // for debug
    message.error(error.message);
    return Promise.reject(error);
  }
);
export const login = (data) => {
  return service({
    url: "/api/login",
    method: "post",
    data,
  });
};