[Super detailed front-end and back-end project construction] Front-end vue3+ts project (introduction of ElementPlus, Axios), back-end springboot construction (create interface to operate mysql database) to achieve front-end and back-end joint debugging

Table of contents


Preface

This project is a simple full-stack project. The front-end project uses vue3, ts, Element Plus, axios and other technology stacks; the back-end project uses springboot, jdbc, mysql, maven and other technologies.


1. Front-end projects

1. Create a project using vue scaffolding

1.1 Check vue version

Enter the command vue -V (V must be capitalized), the version needs to be after 4.5.1

1

1.2 Create a project using vue scaffolding

1. Use the command vue create vue3-element-demo to create a Vue project.
2. Use the up and down keys to select, select Manually select features, and press Enter to configure manually.
Insert image description here
3. Use the up and down keys to select, use the space bar to select (use Babel, TypeScript, Router, Vuex, CSS Pre-processors, Linter / Formatter), and press Enter
Insert image description here

4. Select vue3 and press Enter
Insert image description here
5. Whether to use the Class style decorator, enter [y] here, and then press Enter to confirm;
Insert image description here
6. Whether Babel and TS are used together for modern mode, automatically detected polyfills and translating JSX. Enter [y] here and press Enter to confirm;
Insert image description here
7. Whether to use history routing Mode, enter [n] here to use the default hash mode, and then press Enter to confirm;
Insert image description here
8. Select the CSS preprocessor and press the up and down arrow keys to select. I am used to Less. Then press Enter to confirm;
Insert image description here
9. Select the first ESLint with error prevention only (ESLint with error prevention only)
Insert image description here
Insert image description here
10. Babel, ESLint and other plug-ins Is the configuration configured in a separate file, or are they all in the package.json file? Enter package.json here. You don’t want too many scattered configuration files, and then press Enter to confirm;
Insert image description here
11. Whether to save the feature configuration of the currently created Vue3 project and create a Vue project next time , you can select this feature and press Enter to confirm to complete the creation. This does not need to be saved, enter [n], and then press Enter to confirm;
Insert image description here12. The project is being created;
Insert image description here
The project is created successfully:
Insert image description here
Insert image description here
Run the project
Insert image description here
Insert image description here

2. Delete redundant project files and modify configuration items

2.1. Delete the following files

Insert image description here

2.1. Create index file under views

Insert image description here

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

<style scoped></style>

2.2. Modify the router/index.ts routing file:

Insert image description here
An error will be reported during compilation:
vue eslint报错:Component name “index“ should always be multi-word.eslintvue/multi-word-component-names
Insert image description here
Reason: In addition to the root component (App.vue), the name of the custom component should be composed of multiple words to prevent conflict with html tags.
The solution is to turn off eslint verification and recompile to normal.
lintOnSave: false

Insert image description here

2.3. Modify the App.vue file:

Insert image description here

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<style lang="less">
html,
body,
#app {
    
    
  width: 100%;
  height: 100%;
}
</style>

running result:
Insert image description here

2.4. Initialize page style and clear floats

Create a new css/resset.css file and introduce it into the index.html file to initialize the style.
Insert image description here

/**
 * 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;
 }

Quoted in index.html:
Insert image description here

3. Introduce the ElementPlus component library

3.1. Import dependency packages

npm i element-plus -D
Insert image description here

The first one: mount ElementPlus globally and add it in main.js

Insert image description here

The first one: Import components on demand

Introduced into vue.config.js (import on demand), add the following configuration
Insert image description here

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()],
      }),
    ],
  }
})

Use ElementPlus components in pages

Insert image description here
Effect:
Insert image description here

3. Create a login page

Create a new Login.vue file under view

Insert image description here

<template>
    <div class="container" :class="{ 'sign-up-mode': signUpMode }">
      <!-- form表单容器 -->
      <div class="form-container">
        <div class="signin-signup">
          <!-- 登录 -->
            <el-form
            ref="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-input
                v-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!) return
        formEl.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>


Insert image description here
Insert image description here

4. Package and use Axios

4.1. Install Axios

npm i axios
Insert image description here

4.2. Install NProgress top progress bar

npm i --save-dev @types/nprogress
Insert image description here

4.3. Encapsulation request interception

Create a new utils folder in the src directory, then create a new requestUtil.ts file and write the following code
Insert image description here

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. Cross-domain front-end settings

Configure the following code in vue.config.js:
Insert image description here

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. Configure interface api

Create an api folder in the src directory and create index.ts inside it
Insert image description here

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. Globally encapsulate http requests

Introduce the HTTP request tool in the main.ts file and configure it as a global method
Insert image description here

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

2. Back-end projects

1. Check the installed versions of JDK and maven

Enter java -version in cmd
and mvn -v to check the corresponding installation status
Insert image description here

2. Create springboot project

Create a project through idea's spring initializr. Instead of choosing maven, choose spring initializr for quick creation. Then check the relevant dependencies.
Insert image description here
Insert image description here

Insert image description here

3. Create springboot project successfully

Project created successfully

Insert image description here

4. Configure maven and maven library

Configure local maven library
Insert image description here

5. Load the maven library

Insert image description here

6. Create application.yml

Create a new application.yml under resources, and configure the database name, password, and port. Try not to use 8080 for the port to avoid it being the same as the front-end port.

Insert image description here
Comment out another configuration
Insert image description here

# mysql
spring:
  datasource:
    #MySQL配置
    driverClassName:  com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/easyproject?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
    #数据库名和密码
    username: root
    password: 920724

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.demo.model
server:
  port: 9000

7. Run the project

Insert image description here
The project runs successfully, port 9000
Insert image description here
Insert image description here

8. Create a new WebConfig file to process cross-domain

Create a utils folder, create WebConfig under the utils folder, and add the following configuration
Insert image description here

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 {
    
     // 继承跨域请求的类

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
     // 跨域处理的方法
        registry.addMapping("/**") // 任意访问都允许跨域
                .allowedOrigins("http://localhost:8080", "null") // 跨域来源
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 跨域请求类型
                .maxAge(3600) // 超时时间
                .allowCredentials(true); // 允许携带信息
    }
}

Alt+insert shortcut keys can pop up
Insert image description here

9. Use idea to connect to mysql

For the mysql installation and configuration method, you can refer to another document I wrote:
https://blog.csdn.net/m0_47791238/article/details/134811414?spm=1001.2014.3001.5501

Insert image description here
Insert image description here
Enter mysql username and password:
Insert image description here
Insert image description here

10. Add lombok dependency to pom file

Purpose: To use the @Data annotation
Insert image description here

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

11. Create a bean folder for placing entity objects

Create the bean folder in the project, create a new user entity class, use Data annotations, create constructors and get\set methods
Insert image description here

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. Check the successfully constructed entity objects

Shortcut key alt + 7
Insert image description here

13. Create controller interface

Insert image description here

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 {
    
    
    @Autowired
    UserDao 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. Create dao interface

Insert image description here

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. Create mapper mapping file

Create a mapper folder under resources to store the database mapping file
Create a new UserMapper.xml under the mapper folder
Insert image description here

<?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 easyUser
       	WHERE email=#{
    
    email} AND password=#{
    
    password}
    </select>
</mapper>

3. Test front-end and back-end functions

1. Front-end page interface request

Insert image description here

2. Backend console log printing

Insert image description here

Guess you like

Origin blog.csdn.net/m0_47791238/article/details/134972702