【超详细前后端项目搭建】前端vue3+ts项目(引入ElementPlus、Axios)、后端springboot搭建(创建接口操作mysql数据库)实现前后端联调

目录

  • 前言
  • 一、前端项目
    • 1、使用vue脚手架创建项目
      • 1.1检查vue版本
      • 1.2 使用vue脚手架创建项目
    • 2、删除项目多余文件,修改配置项目
      • 2.1、删除以下文件
      • 2.1、在views下创建index文件
      • 2.2、修改router/index.ts路由文件:
      • 2.3、修改App.vue文件:
      • 2.4、初始化页面样式以及清除浮动
    • 3、引入ElementPlus 组件库
      • 3.1、导入依赖包
        • 第一种:全局挂载ElementPlus,在main.js中添加
        • 第一种:按需导入组件
      • 在页面中使用ElementPlus组件
    • 3、创建登录页面
    • 4、封装并使用 Axios
      • 4.1、安装Axios
      • 4.2、安装NProgress顶部进度条
      • 4.3、封装请求拦截
      • 4.4、前端设置跨域
      • 4.5、配置接口api
      • 4.6、将http请求全局封装
  • 二、后端项目
    • 1、检查JDK和maven的安装版本
    • 2、创建springboot项目
    • 3、创建springboot项目成功
    • 4、配置maven和maven库
    • 5、加载maven库
    • 6、创建application.yml
    • 7、运行项目
    • 8、新建WebConfig文件处理跨域
    • 9、使用idea连接mysql
    • 10、在pom文件添加lombok依赖
    • 11、创建bean文件夹,用于放置实体对象
    • 12、查看构造成功成功的实体对象
    • 13、创建controller接口
    • 14、创建dao接口
    • 15、创建mapper映射文件
  • 三、测试前后端功能
    • 1、前端页面接口请求
    • 2、后端控制台日志打印


前言

本项目为简易的全栈项目,其中前端项目使用到了vue3、ts、Element Plus、axios等技术栈;后端项目使用到了springboot、jdbc、mysql、maven等技术


一、前端项目

1、使用vue脚手架创建项目

1.1检查vue版本

输入命令vue -V(V要大写),版本需要在4.5.1之后

1

1.2 使用vue脚手架创建项目

1、使用命令vue create vue3-element-demo 创建Vue项目。
2、通过上下键选择,选择 Manually select features,按回车,手动进行配置。
在这里插入图片描述
3、通过上下键选择,通过空格键选中(使用Babel,TypeScript,Router、Vuex、CSS Pre-processors、Linter / Formatter),按回车
在这里插入图片描述

4、选择vue3按回车
在这里插入图片描述
5、是否使用 Class 风格装饰器,此处输入【y】,然后回车确认;
在这里插入图片描述
6、Babel 和 TS 是否一起使用,用于现代模式、自动检测的 polyfills 和转译 JSX,此处输入【y】,然后回车确认;
在这里插入图片描述
7、是否使用history路由模式,此处输入【n】,即使用默认的 hash 模式,然后回车确认;
在这里插入图片描述
8、选择 CSS 预处理器,按上下方向键来选择,笔者习惯了 Less,然后回车确认;
在这里插入图片描述
9、选择第一个ESLint with error prevention only(仅具有错误预防功能的ESLint)
在这里插入图片描述
在这里插入图片描述
10、Babel、ESLint 等插件的配置是单独的文件进行配置,还是都在 package.json 文件里面?此处输选择 package.json 咯,并不想太多零散的配置文件,然后回车确认;
在这里插入图片描述
11、是否保存当前创建 Vue3 项目的特性配置,下次再创建 Vue 项目的时候,可以选择该特性,然后回车确认即可创建完成。这个可以不用保存,输入【n】,然后回车确认;
在这里插入图片描述12、项目创建中;
在这里插入图片描述
项目创建成功:
在这里插入图片描述
在这里插入图片描述
运行项目
在这里插入图片描述
在这里插入图片描述

2、删除项目多余文件,修改配置项目

2.1、删除以下文件

在这里插入图片描述

2.1、在views下创建index文件

在这里插入图片描述

<template><div>我的首页</div>
</template><script lang="ts">export default {name: 'Index'}
</script><style scoped></style>

2.2、修改router/index.ts路由文件:

在这里插入图片描述
编译时会有报错:
vue eslint报错:Component name “index“ should always be multi-word.eslintvue/multi-word-component-names
在这里插入图片描述
原因:除了根组件(App.vue)外,自定义组件名称应该由多单词组成,防止和html标签冲突。
解决方法,关闭eslint校验,重新编译就正常了
lintOnSave: false

在这里插入图片描述

2.3、修改App.vue文件:

在这里插入图片描述

<template><div id="app"><router-view/></div>
</template><style lang="less">
html,
body,
#app {width: 100%;height: 100%;
}
</style>

运行效果:
在这里插入图片描述

2.4、初始化页面样式以及清除浮动

新建css/resset.css文件,并在index.html文件中引入,初始化样式
在这里插入图片描述

/*** Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)* http://cssreset.com*/html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,time, mark, audio, video{margin: 0;padding: 0;border: 0;font-size: 100%;font: inherit;font-weight: normal;vertical-align: baseline;}/* HTML5 display-role reset for older browsers */article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section{display: block;}ol, ul, li{list-style: none;}blockquote, q{quotes: none;}blockquote:before, blockquote:after,q:before, q:after{content: '';content: none;}table{border-collapse: collapse;border-spacing: 0;}/* custom */a{color: #7e8c8d;text-decoration: none;-webkit-backface-visibility: hidden;}::-webkit-scrollbar{width: 5px;height: 5px;}::-webkit-scrollbar-track-piece{background-color: rgba(0, 0, 0, 0.2);-webkit-border-radius: 6px;}::-webkit-scrollbar-thumb:vertical{height: 5px;background-color: rgba(125, 125, 125, 0.7);-webkit-border-radius: 6px;}::-webkit-scrollbar-thumb:horizontal{width: 5px;background-color: rgba(125, 125, 125, 0.7);-webkit-border-radius: 6px;}html, body{width: 100%;font-family: "Arial", "Microsoft YaHei", "黑体", "宋体", "微软雅黑", sans-serif;}body{line-height: 1;-webkit-text-size-adjust: none;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}html{overflow-y: scroll;}/*清除浮动*/.clearfix:before,.clearfix:after{content: " ";display: inline-block;height: 0;clear: both;visibility: hidden;}.clearfix{*zoom: 1;}/*隐藏*/.dn{display: none;}

index.html中引用:
在这里插入图片描述

3、引入ElementPlus 组件库

3.1、导入依赖包

npm i element-plus -D
在这里插入图片描述

第一种:全局挂载ElementPlus,在main.js中添加

在这里插入图片描述

第一种:按需导入组件

vue.config.js中引入(按需导入方式),添加如下配置
在这里插入图片描述

const { defineConfig } = require('@vue/cli-service');
const AutoImport = require('unplugin-auto-import/webpack');
const Components = require('unplugin-vue-components/webpack');
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
module.exports = defineConfig({transpileDependencies: true,//关闭eslint校验lintOnSave: false,configureWebpack: {plugins: [AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],}
})

在页面中使用ElementPlus组件

在这里插入图片描述
效果:
在这里插入图片描述

3、创建登录页面

在view下新建Login.vue文件

在这里插入图片描述

<template><div class="container" :class="{ 'sign-up-mode': signUpMode }"><!-- form表单容器 --><div class="form-container"><div class="signin-signup"><!-- 登录 --><el-formref="ruleFormRef":model="loginUser":rules="rules"label-width="100px"class="login-form sign-in-form"><el-form-item label="邮箱" prop="email"><el-input v-model="loginUser.email" placeholder="Enter Email..." /></el-form-item><el-form-item label="密码" prop="password"><el-inputv-model="loginUser.password"type="password"placeholder="Enter Password..."/></el-form-item><el-form-item><el-button type="primary" class="submit-btn" @click="submitForm(ruleFormRef)">提交</el-button></el-form-item><!-- 找回密码 --><el-form-item><p class="tiparea">忘记密码<a>立即找回</a></p></el-form-item></el-form></div></div><!-- 左右切换动画 --><div class="panels-container"><div class="panel left-panel"><div class="content"><h3>Row,row,row your boat</h3><p>Gentlely down the stream</p><button @click="signUpMode = !signUpMode" class="btn transparent">注册</button></div></div><div class="panel right-panel"><div class="content"><h3>Merrily,merrily,merrily,merrily,</h3><p>Life is but a dream</p><button @click="signUpMode = !signUpMode" class="btn transparent">登录</button></div></div></div></div></template><script lang="ts" setup>import { ref, reactive, toRefs, getCurrentInstance } from 'vue'import type { FormInstance, FormRules } from 'element-plus'// Vue3语法糖// 通过解构getCurrentInstance,获取this,这里的this就是ctx// const { ctx } = getCurrentInstance()const { proxy } = getCurrentInstance()// 登录/注册模式const signUpMode = ref(false)const ruleFormRef = ref<FormInstance>()// 登录表单const loginUser = reactive({email: '',password: ''})// 校验规则const rules = reactive({email: [{required: true,type: 'email',message: 'email格式错误',trigger: 'blur'}],password: [{ required: true, message: '密码不得为空', trigger: 'blur' },{ min: 6, max: 30, message: '密码长度必须在6到30之间', trigger: 'blur' }]})// 触发登录方法const submitForm  = (formEl: FormInstance | undefined) => {if(!formEl!) returnformEl.validate((valid) => {if (valid) {console.log('submit!')const data = proxy.$http.getUserPassword(loginUser)console.log('data', data)} else {console.log('error submit!')return false}})}</script><style scoped>.container {position: relative;width: 100%;min-height: 100vh;background-color: #fff;overflow: hidden;}.form-container {position: absolute;left: 0;top: 0;width: 100%;height: 100%;}.signin-signup {position: relative;top: 50%;left: 75%;transform: translate(-50%, -50%);width: 44%;transition: 1s 0.7s ease-in-out;display: grid;grid-template-columns: 1fr;z-index: 5;}/* 左右切换动画 */.social-text {padding: 0.7rem 0;font-size: 1rem;}.social-media {display: flex;justify-content: center;}.social-icon {height: 46px;width: 46px;display: flex;justify-content: center;align-items: center;margin: 0 0.45rem;color: #333;border-radius: 50%;border: 1px solid #333;text-decoration: none;font-size: 1.1rem;transition: 0.3s;}.social-icon:hover {color: #4481eb;border-color: #4481eb;}.btn {width: 150px;background-color: #5995fd;border: none;outline: none;height: 49px;border-radius: 49px;color: #fff;text-transform: uppercase;font-weight: 600;margin: 10px 0;cursor: pointer;transition: 0.5s;}.btn:hover {background-color: #4d84e2;}.panels-container {position: absolute;height: 100%;width: 100%;top: 0;left: 0;display: grid;grid-template-columns: repeat(2, 1fr);}.container:before {content: '';position: absolute;height: 2000px;width: 2000px;top: -10%;right: 48%;transform: translateY(-50%);background-image: linear-gradient(-45deg, #4481eb 0%, #04befe 100%);transition: 1.8s ease-in-out;border-radius: 50%;z-index: 6;}.image {width: 100%;transition: transform 1.1s ease-in-out;transition-delay: 0.4s;}.panel {display: flex;flex-direction: column;align-items: flex-end;justify-content: space-around;text-align: center;z-index: 6;}.left-panel {pointer-events: all;padding: 3rem 17% 2rem 12%;}.right-panel {pointer-events: none;padding: 3rem 12% 2rem 17%;}.panel .content {color: #fff;transition: transform 0.9s ease-in-out;transition-delay: 0.6s;}.panel h3 {font-weight: 600;line-height: 1;font-size: 1.5rem;}.panel p {font-size: 0.95rem;padding: 0.7rem 0;}.btn.transparent {margin: 0;background: none;border: 2px solid #fff;width: 130px;height: 41px;font-weight: 600;font-size: 0.8rem;}.right-panel .image,.right-panel .content {transform: translateX(800px);}/* ANIMATION */.container.sign-up-mode:before {transform: translate(100%, -50%);right: 52%;}.container.sign-up-mode .left-panel .image,.container.sign-up-mode .left-panel .content {transform: translateX(-800px);}.container.sign-up-mode .signin-signup {left: 25%;}.container.sign-up-mode form.sign-up-form {opacity: 1;z-index: 2;}.container.sign-up-mode form.sign-in-form {opacity: 0;z-index: 1;}.container.sign-up-mode .right-panel .image,.container.sign-up-mode .right-panel .content {transform: translateX(0%);}.container.sign-up-mode .left-panel {pointer-events: none;}.container.sign-up-mode .right-panel {pointer-events: all;}@media (max-width: 870px) {.container {min-height: 800px;height: 100vh;}.signin-signup {width: 100%;top: 95%;transform: translate(-50%, -100%);transition: 1s 0.8s ease-in-out;}.signin-signup,.container.sign-up-mode .signin-signup {left: 50%;}.panels-container {grid-template-columns: 1fr;grid-template-rows: 1fr 2fr 1fr;}.panel {flex-direction: row;justify-content: space-around;align-items: center;padding: 2.5rem 8%;grid-column: 1 / 2;}.right-panel {grid-row: 3 / 4;}.left-panel {grid-row: 1 / 2;}.image {width: 200px;transition: transform 0.9s ease-in-out;transition-delay: 0.6s;}.panel .content {padding-right: 15%;transition: transform 0.9s ease-in-out;transition-delay: 0.8s;}.panel h3 {font-size: 1.2rem;}.panel p {font-size: 0.7rem;padding: 0.5rem 0;}.btn.transparent {width: 110px;height: 35px;font-size: 0.7rem;}.container:before {width: 1500px;height: 1500px;transform: translateX(-50%);left: 30%;bottom: 68%;right: initial;top: initial;transition: 2s ease-in-out;}.container.sign-up-mode:before {transform: translate(-50%, 100%);bottom: 32%;right: initial;}.container.sign-up-mode .left-panel .image,.container.sign-up-mode .left-panel .content {transform: translateY(-300px);}.container.sign-up-mode .right-panel .image,.container.sign-up-mode .right-panel .content {transform: translateY(0px);}.right-panel .image,.right-panel .content {transform: translateY(300px);}.container.sign-up-mode .signin-signup {top: 5%;transform: translate(-50%, 0);}}@media (max-width: 570px) {form {padding: 0 1.5rem;}.image {display: none;}.panel .content {padding: 0.5rem 1rem;}.container {padding: 1.5rem;}.container:before {bottom: 72%;left: 50%;}.container.sign-up-mode:before {bottom: 28%;left: 50%;}}/* 控制login & register显示 */form {padding: 0rem 5rem;transition: all 0.2s 0.7s;overflow: hidden;}form.sign-in-form {z-index: 2;}form.sign-up-form {opacity: 0;z-index: 1;}/* register */.loginForm,.registerForm {margin-top: 20px;background-color: #fff;padding: 20px 40px 20px 20px;border-radius: 5px;box-shadow: 0px 5px 10px #cccc;}.submit-btn {width: 100%;}.tiparea {text-align: right;font-size: 12px;color: #333;width: 100%;}.tiparea a {color: #409eff;}</style>

在这里插入图片描述
在这里插入图片描述

4、封装并使用 Axios

4.1、安装Axios

npm i axios
在这里插入图片描述

4.2、安装NProgress顶部进度条

npm i --save-dev @types/nprogress
在这里插入图片描述

4.3、封装请求拦截

在 src 目录新建 utils 文件夹,再新建 requestUtil.ts 文件,写上以下代码
在这里插入图片描述

import axios from 'axios'
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import { ElMessage } from 'element-plus'const http = axios.create({baseURL: 'http://localhost:9000',timeout: 300 * 1000, // 请求超时时间设置为300秒
})const NETWORK_ERROR = '网络错误,请联系开发人员'/*** 请求拦截器*/
http.interceptors.request.use((req) => {console.log('请求拦截器 =>', req)Nprogress.start()return req;
}, (error) => {Nprogress.done()return Promise.reject(error);
});/*** 响应拦截器*/
http.interceptors.response.use(function (res) {console.log('响应拦截器 =>', res)Nprogress.done()if (res.status == 200) {return res.data} else {ElMessage.error((NETWORK_ERROR))return Promise.reject(NETWORK_ERROR)}
});export default http

4.4、前端设置跨域

在vue.config.js中配置如下代码:
在这里插入图片描述

const { defineConfig } = require('@vue/cli-service');
// const AutoImport = require('unplugin-auto-import/webpack');
// const Components = require('unplugin-vue-components/webpack');
// const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
module.exports = defineConfig({transpileDependencies: true,//关闭eslint校验lintOnSave: false,// ElementPlus按需导入方式// configureWebpack: {//   plugins: [//     AutoImport({//       resolvers: [ElementPlusResolver()],//     }),//     Components({//       resolvers: [ElementPlusResolver()],//     }),//   ],// }devServer: {open: true,host: 'localhost',port: 8080,https: false,// 设置跨域proxy: {'/api': {target: 'http://localhost:9000',ws: true,changeOrigin: true,pathRewrite: {'^api': ''}}}}
})

4.5、配置接口api

在src目录下创建api文件夹,里面创建index.ts
在这里插入图片描述

import http from '@/utils/requestUtils'export default {/*** 根据用户邮箱、密码查询用户信息*/getUserPassword(data: any) {return http.post('/api/getUserPassword',data,{headers: {'Content-Type': 'application/json'},})},/*** 保存用户信息*/saveUser(data: any) {return http.post('/api/saveUser',data,{headers: {'Content-Type': 'application/json'},})},
}

4.6、将http请求全局封装

在 main.ts 文件引入HTTP请求工具并配置为全局方法
在这里插入图片描述

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import axios from 'axios'
import apiServe from '@/api'const app = createApp(App)app.use(store)
app.use(router)
app.use(ElementPlus)
app.mount('#app')app.config.globalProperties.$http = apiServe
app.config.globalProperties.$axios = axios

二、后端项目

1、检查JDK和maven的安装版本

在cmd输入 java -version
和mvn -v检查对应的安装情况
在这里插入图片描述

2、创建springboot项目

通过idea的spring initializr创建工程,不选择maven而是选择spring initializr快捷创建。然后去勾选相关依赖。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3、创建springboot项目成功

项目创建成功

在这里插入图片描述

4、配置maven和maven库

配置本地maven库
在这里插入图片描述

5、加载maven库

在这里插入图片描述

6、创建application.yml

在resources下面新建application.yml,并配置数据库名,密码,以及端口,端口尽量不要使用8080,避免和前端端口相同了

在这里插入图片描述
注释掉另外一个配置
在这里插入图片描述

# mysql
spring:datasource:#MySQL配置driverClassName:  com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/easyproject?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC#数据库名和密码username: rootpassword: 920724mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.example.demo.model
server:port: 9000

7、运行项目

在这里插入图片描述
项目运行成功,端口9000
在这里插入图片描述
在这里插入图片描述

8、新建WebConfig文件处理跨域

创建utils文件夹,在utils文件夹下创建WebConfig,并添加以下配置
在这里插入图片描述

package com.springboot.userlogin.springbootdemo.utils;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;// 使用注解说明是全局配置类
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter { // 继承跨域请求的类@Overridepublic void addCorsMappings(CorsRegistry registry) { // 跨域处理的方法registry.addMapping("/**") // 任意访问都允许跨域.allowedOrigins("http://localhost:8080", "null") // 跨域来源.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 跨域请求类型.maxAge(3600) // 超时时间.allowCredentials(true); // 允许携带信息}
}

alt+insert快捷键可以弹出
在这里插入图片描述

9、使用idea连接mysql

mysql安装配置方法可以参照我写的另外一个文档:
https://blog.csdn.net/m0_47791238/article/details/134811414?spm=1001.2014.3001.5501

在这里插入图片描述
在这里插入图片描述
输入mysql用户名和密码:
在这里插入图片描述
在这里插入图片描述

10、在pom文件添加lombok依赖

目的:为了使用@Data注解
在这里插入图片描述

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency>

11、创建bean文件夹,用于放置实体对象

在项目中创建bean文件夹,新建user实体类,使用Data注解,创建构造方法和get\set方法
在这里插入图片描述

package com.springboot.userlogin.springbootdemo.bean;import lombok.Data;@Data
public class User {private int id;private String username;private String password;private String email;private String role;private boolean state;//    public User() {
//    }//    public User(String username, String password, String email, String role, boolean state) {
//        this.username = username;
//        this.password = password;
//        this.email = email;
//        this.role = role;
//        this.state = state;
//    }
//
//    public int getId() {
//        return id;
//    }
//
//    public String getUsername() {
//        return username;
//    }
//
//    public String getPassword() {
//        return password;
//    }
//
//    public String getEmail() {
//        return email;
//    }
//
//    public String getRole() {
//        return role;
//    }
//
//    public boolean getState() {
//        return state;
//    }
//
//    public void setId(int id) {
//        this.id = id;
//    }
//
//    public void setUsername(String username) {
//        this.username = username;
//    }
//
//    public void setPassword(String password) {
//        this.password = password;
//    }
//
//    public void setEmail(String email) {
//        this.email = email;
//    }
//
//    public void setRole(String role) {
//        this.role = role;
//    }
//
//    public void setState(boolean state) {
//        this.state = state;
//    }
}

12、查看构造成功成功的实体对象

快捷键 alt + 7
在这里插入图片描述

13、创建controller接口

在这里插入图片描述

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LoginController {@AutowiredUserDao userDao;@PostMapping("/api/getUserPassword") // @RequestMapping注解创建接口public String userLogin(@RequestBody User user) { // @RequestBody注解方便找到user实体System.out.println("User : " + user);String str = "error";int count = userDao.getUserByMassage(user.getEmail(), user.getPassword());if (count > 0) {str = "ok";}return str;}
}

14、创建dao接口

在这里插入图片描述

package com.springboot.userlogin.springbootdemo.dao;import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;@Repository
@Mapper
public interface UserDao {int getUserByMassage(@Param("email") String email, @Param("password") String password);
}

15、创建mapper映射文件

在resources下面创建mapper文件夹,用于存放数据库的映射文件
在mapper文件夹下新建UserMapper.xml
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--对应dao层接口文件的目录-->
<mapper namespace="com.springboot.userlogin.springbootdemo.dao.UserDao"><!--  id值为UserDao接口方法名; --><select id="getUserByMassage" resultType="java.lang.Integer">SELECT count(id) FROM easyUserWHERE email=#{email} AND password=#{password}</select>
</mapper>

三、测试前后端功能

1、前端页面接口请求

在这里插入图片描述

2、后端控制台日志打印

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

气候变化与环境保护:全球研究与未来趋势

导言 气候变化和环境保护是当今社会亟待解决的全球性难题。本文将深入探讨这一主要流行研究方向的发展历程、遇到的问题、解决过程&#xff0c;以及未来的可用范围&#xff0c;着重分析在各国的应用和未来的研究趋势&#xff0c;以探讨在哪些方面能够取得胜利&#xff0c;以及在…

PySpark中DataFrame的join操作

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

期货开平规则(期货交易开平规则解析)

什么是期货开平规则 期货开平规则&#xff0c;简单来说是指期货交易中的开仓和平仓所遵循的一系列规定。具体而言&#xff0c;开仓是指买入或卖出期货合约&#xff0c;建立一个新的持仓&#xff1b;平仓则是指买入或卖出相应数量的期货合约&#xff0c;用以解除原有持仓。开平…

什么是数据仪表板?数据可视化仪表盘怎么制作?

在数据经济时代&#xff0c;分析数据是每个企业做出最佳决策的关键。但是&#xff0c;手动分析和解释大量数据是不可行的。数据可视化对于分析数据中存在的各种有价值信息至关重要&#xff0c;包括可见趋势和隐藏趋势等。仪表盘显示可视化趋势和信息&#xff0c;例如 KPI、趋势…

简易实现 STL--list

实现 list 的主要思想及过程 首先&#xff0c;实现过程中的所有代码必须放在自己定义的命名空间中。 定义一个结点的结构体类模板&#xff0c;结点的数据类型就应该是模板类型 T&#xff0c;定义的 next指针和 prev指针都应该是模板指针类型&#xff0c;并且结构体类中药有构…

2017年第六届数学建模国际赛小美赛A题飓风与全球变暖解题全过程文档及程序

2017年第六届数学建模国际赛小美赛 A题 飓风与全球变暖 原题再现&#xff1a; 飓风&#xff08;也包括在西北太平洋被称为“台风”的风暴以及在印度洋和西南太平洋被称为“严重热带气旋”&#xff09;具有极大的破坏性&#xff0c;往往造成数百人甚至数千人死亡。   许多气…

UE4移动端最小包优化实践

移动端对于包大小有着严苛的要求,然而UE哪怕是一个空工程打出来也有90+M,本文以一个复杂的工程为例,探索怎么把包大小降低到最小。 一、工程简介 工程包含代码、插件、资源、iOS原生库工程。 二、按官方文档进行基础优化 官方文档 1、勾选Use Pak File和Create comp…

YOLOv5性能评估指标->mAP、Precision、Recall、FPS、Confienc (讲解论文关注的主要指标)

简介 这篇博客&#xff0c;主要给大家讲解我们在训练yolov5时生成的结果文件中各个图片及其中指标的含义&#xff0c;帮助大家更深入的理解&#xff0c;以及我们在评估模型时和发表论文时主要关注的参数有那些。本文通过举例训练过程中的某一时间的结果来帮助大家理解&#xf…

npm安装依赖报错ERESOLVE unable to resolve dependency tree(我是在taro项目中)(node、npm 版本问题)

换了电脑之后新电脑安装包出错 &#x1f447;&#x1f447;&#x1f447; npm install 安装包报错 ERESOLVE unable to resolve dependency tree 百度后尝试使用 npm install --force 还是报错 参考 有人说是 node 版本和 npm 版本的问题 参考 新电脑 node版本&#xff1a;16.1…

ros2机器人常规控制流程

The joint_state_publisher reads the robot_description parameter from the parameter server, finds all of the non-fixed joints and publishes a JointState message with all those joints defined.也就是说如果我们不需要控制机器人运动&#xff0c;只需要一个节点就可…

自学精灵--专业的编程学习网站

这是我看过的最靠谱的编程学习网站&#xff0c;名字是&#xff1a;自学精灵&#xff0c;网站是&#xff1a;learn.skyofit.com。&#xff08;某度搜"自学精灵"也可找到此站&#xff0c;搜不到可以用必应搜&#xff09;。 自学精灵是全网最强的学习平台&#xff0c;我…

STM32 OLED 显示原理的讲解以及OLED显示汉字与图片的代码

STM 32 OLED 显示原理的讲解以及OLED显示汉字与图片的代码 本文主要涉及OLED显示原理的讲解以及OLED显示汉字与图片的代码。 文章目录 STM 32 OLED 显示原理的讲解以及OLED显示汉字与图片的代码一、 OLED简介1.1 OLED 的特点1.2 OLED 8080并行接口信号线说明1.3 OLED控制器SSD1…

UE5 runtime模式下自定义视口大小和位置并跟随分辨率自适应缩放

本文旨在解决因UI问题导致屏幕中心位置不对的问题 处理前的现象&#xff1a;如果四周UI透明度都为1&#xff0c;那么方块的位置就不太对&#xff0c;没在中心 处理后的现象&#xff1a; 解决办法&#xff1a;自定义大小和视口偏移 创建一个基于子系统的类或者蓝图函数库(什么类…

使用opencv实现图像中几何图形检测

1 几何图形检测介绍 1.1 轮廓(contours) 什么是轮廓&#xff0c;简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具&#xff0c;在OpenCV 中使用轮廓发现相关函数时候要求输入图像是二值图像&#xff0c;这…

Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现

Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用修复建议 总结 漏洞名称 漏洞描述 在Apache Tomcat中发现了一个被归类为关键的漏洞&#xff0c;该漏洞在8.5.4(Application Server Soft ware)以下。受影响的是组…

Windows下安装MongoDB实践总结

本文记录Windows环境下的MongoDB安装与使用总结。 【1】官网下载 官网下载地址&#xff1a;Download MongoDB Community Server | MongoDB 这里可以选择下载zip或者msi&#xff0c;zip是解压后自己配置&#xff0c;msi是傻瓜式一键安装。这里我们分别对比进行实践。 【2】ZI…

车载V2X方案的选型分享

ACX200T面向 5G车联网C-V2X 应用的安全芯片&#xff0c;满足V2X场景下消息认证的专用安全芯片&#xff0c;该款芯片采用公司自主的 高速硬件加密引擎 &#xff0c;支 持国家标准SM1、SM2、SM3、SM4密码算法&#xff0c;同时支持国际ECDSA、AES、SHA-1密码算法。可实现网联汽车云…

使用包、Crate 和模块管理项目(下)

1、使用 use 关键字将路径引入作用域 在之前的示例中我们引用模块中的函数或者结构体之类的&#xff0c;都是需要用到相对路径或者绝对路径去引用&#xff0c;然尔在这里&#xff0c;有一种方法可以简化这个过程。我们可以使用 use 关键字创建一个短路径&#xff0c;然后就可以…

云原生扫盲篇

What 云原生加速了应用系统与基础设施资源之间的解耦,向下封装资源以便将复杂性下沉到基础设施层;向上支撑应用,让开发者更关注业务价值 云原生是一种构建和运行应用程序的方法,也是一套技术体系和方法论. Cloud 表示应用程序位于云中而不是传统的数据中心Native表示应用程序从…

C# NPOI导出datatable----Excel模板画图表

1、创建Excel模板 2、安装NPOI管理包 3、创建工作簿 &#xff08;XLSX和XLS步骤一样&#xff0c;以XLS为例&#xff09; IWorkbook workbook null; string time DateTime.Now.ToString("yyyyMMddHHmmss"); string excelTempPath Application.StartupPath "…