Technologieaustausch

vue3 Springboot Mybatis MySQL-Projekt Übung – Implementierung einfacher Anmelde- und Registrierungsfunktionen

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Hier ist eine Projektimplementierung von vue3+springboot+mybatis+mysql, die einfach die Anmelde- und Registrierungsfunktionen der Front-End- und Back-End-Trennung implementiert. Die Haupttools sind: Idee, Navicat

Inhaltsverzeichnis

1. Erstellen Sie ein Vue3-Projekt und eine Erstkonfiguration

Erstellen Sie ein vue3-Projekt

2. Ändern Sie die Projektstruktur

1) Ursprüngliche Verzeichnisstruktur

2) Geänderte Verzeichnisstruktur

​Bearbeiten und schreiben Sie die Login-Registrierungsseite

1) LoginAndRegister.vue

2) Startseite.vue

3) Router

4) Login.css

5) Anzeige der Anmelderegistrierungsseite

2. Erstellen Sie ein Springboot+MySQL+Mybatis-Projekt und stellen Sie eine Verbindung zur Datenbank her

3. Schreiben Sie Anmelde- und Registrierungs-Backend-Funktionen

1. Anmeldelogik

2. Registrierungslogik

3. Backend-Codeteil

4. Führen Sie das Projekt aus


1. Erstellen Sie ein Vue3-Projekt und eine Erstkonfiguration

1. Erstellen Sie ein vue3-Projekt

Um ein Projekt zu erstellen, können Sie sich auf einen meiner Artikel beziehen:

Erstellen Sie ein benutzerdefiniertes Vue3-Projekt mit dem Blog IDEA_idea vue3-CSDN

Anfängliche Verzeichnisstruktur nach der Erstellung:

2. Ändern Sie die Projektstruktur

Zuerst müssen Sie die ursprüngliche Verzeichnisstruktur ändern

1) Ursprüngliche Verzeichnisstruktur

VermögenswerteBilder posten

KomponentenZwischenkomponenten, meist wiederverwendbar

Routerist die Route, in der die Dateipfade aller Hauptseiten konfiguriert werden

speichernWird im Allgemeinen für die Vuex-Statusverwaltung verwendet, z. B. zum Speichern von Token usw.

AnsichtenMitte ist die Hauptseite

App.vueEs ist die Stammkomponente der Vue-Anwendung.

Haupt-JSEs handelt sich um die Eintragsdatei der Anwendung, die normalerweise zum Einführen von Abhängigkeiten wie Vue und Vue-Router verwendet wird.

2) Geänderte Verzeichnisstruktur

Um die Anmelde- und Registrierungsfunktion zu implementieren, lautet die geänderte Verzeichnisstruktur:


3. Schreiben Sie die Login-Registrierungsseite

1) LoginAndRegister.vue

Erstellen Sie LoginAndRegister.vue im Komponentenordner, um die Anmelde- und Registrierungsseite und -funktionen zu implementieren. Hier erstelle ich nur eine .vue-Datei für die Anmeldung und Registrierung, in der v-if verwendet wird, um zu bestimmen, ob die Anmeldeblock- und Registrierungsblockelemente vorhanden sind enthalten.

Grundeinstellungen

v-if="loginShow"为true, v-if="registerShow"为false

Schaltet zwischen wahr und falsch um, wenn zum Umschalten auf die Schaltfläche geklickt wird.

Nach erfolgreicher Registrierung wechseln Sie zurück zum Login-Bereich.

Aus Gründen der Bequemlichkeit und Benutzergewohnheiten umfassen die Benutzerattribute zwar ID, Benutzername, Passwort, Telefonnummer und Geschlecht, bei der Registrierung werden jedoch nur der Benutzername und das Passwort eingegeben und die Funktion wird einfach implementiert. Das Passwort ist nicht verschlüsselt nicht sicher genug. Ich werde den Artikel erneut aktualisieren, um über eine sicherere Anmelde- und Registrierungsmethode sowie darüber zu schreiben, wie persönliche Daten nach der Anmeldung vervollständigt werden.

LoginAndRegister.vue:

  1. <template>
  2. <div class="container">
  3. <div class="login-box" v-if="loginShow">
  4. <!-- 菱形群-->
  5. <div class="decoration1 decoration"></div>
  6. <div class="decoration2 decoration"></div>
  7. <div class="decoration3 decoration"></div>
  8. <div class="decoration4 decoration"></div>
  9. <div class="decoration5 decoration"></div>
  10. <div class="decoration decoration4 decoration6"></div>
  11. <div class="decoration decoration7 decoration2"></div>
  12. <div class="decoration decoration8 decoration3"></div>
  13. <div class="login-title">
  14. <h1>Login</h1>
  15. </div>
  16. <div class="login-part">
  17. <input class="login-input" v-model="username" placeholder="Username" />
  18. <input class="login-input" type="password" v-model="password" placeholder="Password" />
  19. <button class="login-button" @click="login">Login</button>
  20. <div>
  21. 还未注册?点击<a class="change-link" @click="changeToRegister">这里</a>注册
  22. </div>
  23. </div>
  24. </div>
  25. <div class="login-box" v-if="registerShow">
  26. <!-- 菱形群-->
  27. <div class="decoration1 decoration"></div>
  28. <div class="decoration2 decoration"></div>
  29. <div class="decoration3 decoration"></div>
  30. <div class="decoration4 decoration"></div>
  31. <div class="decoration5 decoration"></div>
  32. <div class="decoration decoration4 decoration6"></div>
  33. <div class="decoration decoration7 decoration2"></div>
  34. <div class="decoration decoration8 decoration3"></div>
  35. <div class="login-title">
  36. <h1>Register</h1>
  37. </div>
  38. <div class="login-part">
  39. <input class="login-input" v-model="username" placeholder="Username" />
  40. <input class="login-input" type="password" v-model="password" placeholder="Password" />
  41. <button class="login-button" @click="register">Register</button>
  42. <span class="change-link" @click="changeToLogin">返回登录</span>
  43. </div>
  44. </div>
  45. <!-- <div class="decoration decoration1"></div>-->
  46. <!-- <div class="decoration decoration2"></div>-->
  47. <!-- <div class="decoration decoration3"></div>-->
  48. <!-- <div class="decoration decoration4"></div>-->
  49. </div>
  50. </template>
  51. <script>
  52. import { ref } from 'vue'
  53. import { useRouter } from 'vue-router' // 导入 useRouter
  54. import '../style/Login.css' // 导入css
  55. export default {
  56. name: 'LoginVue',
  57. setup () {
  58. const username = ref('')
  59. const password = ref('')
  60. const phone = ref('')
  61. const loginShow = ref(true)
  62. const registerShow = ref(false)
  63. const router = useRouter()
  64. const changeToRegister = async () => {
  65. loginShow.value = false
  66. registerShow.value = true
  67. }
  68. const changeToLogin = async () => {
  69. loginShow.value = true
  70. registerShow.value = false
  71. }
  72. const login = async () => {
  73. console.log('Login with:', username.value, password.value)
  74. try {
  75. const formData = new FormData()
  76. formData.append('username', username.value)
  77. formData.append('password', password.value)
  78. const response = await fetch('http://localhost:8081/api/user/login', {
  79. method: 'POST',
  80. body: formData
  81. })
  82. const data = await response.json()
  83. if (response.ok) {
  84. console.log('Link success', data)
  85. if (data.code === 200) {
  86. // 登录成功
  87. alert('登录成功!')
  88. await router.push('/home')
  89. } else {
  90. alert(data.msg)
  91. }
  92. } else {
  93. console.error('Link failed', data)
  94. }
  95. } catch (error) {
  96. console.error('Error login', error)
  97. }
  98. }
  99. const register = async () => {
  100. console.log('Register with:', username.value, password.value)
  101. try {
  102. const formData = new FormData()
  103. formData.append('username', username.value)
  104. formData.append('password', password.value)
  105. const response = await fetch('http://localhost:8081/api/user/register', {
  106. method: 'POST',
  107. body: formData
  108. })
  109. const data = await response.json()
  110. if (response.ok) {
  111. if (data.code === 200) {
  112. console.log('Register success', data)
  113. alert('注册成功!')
  114. await changeToLogin()
  115. } else {
  116. console.log('Register failed', data)
  117. alert(data.msg)
  118. }
  119. } else {
  120. console.error('Register failed', data)
  121. }
  122. } catch (error) {
  123. console.error('Error during register', error)
  124. }
  125. }
  126. return { username, password, phone, login, loginShow, registerShow, changeToRegister, register, changeToLogin }
  127. }
  128. }
  129. </script>
  130. <style>
  131. </style>

2) Startseite.vue

Home.vue ist die Hauptseite, zu der nach erfolgreicher Anmeldung gesprungen wird.

Startseite.vue:

  1. <template>
  2. 首页<br><br>
  3. <button class="login-button" @click="signOut">退出登录</button>
  4. </template>
  5. <script>
  6. import { useRouter } from 'vue-router'
  7. export default {
  8. name: 'HomeVue',
  9. setup () {
  10. const router = useRouter()
  11. const signOut = async () => {
  12. await router.push('/')
  13. }
  14. return { signOut }
  15. }
  16. }
  17. </script>
  18. <style scoped>
  19. </style>

3) Router

Konfiguration der Seitenweiterleitung: Umleitung zur Anmeldeseite, wenn der Pfad / lautet, /login die Anmeldeseite und /home die Startseite ist.

index.js:

  1. import { createRouter, createWebHistory } from 'vue-router'
  2. import Login from '../components/LoginAndRegister.vue'
  3. import Home from '../views/Home.vue'
  4. const routes = [
  5. {
  6. path: '/',
  7. redirect: '/login'
  8. },
  9. {
  10. path: '/login',
  11. name: 'Login',
  12. component: Login
  13. },
  14. {
  15. path: '/home',
  16. name: 'Home',
  17. component: Home
  18. }
  19. ]
  20. const router = createRouter({
  21. history: createWebHistory(process.env.BASE_URL),
  22. routes
  23. })
  24. export default router

4) Login.css

CSS-Design für die Login-Registrierungsseite.

Login.css:

  1. *{
  2. margin: 0;
  3. padding: 0;
  4. }
  5. .container{
  6. height: 100vh;
  7. display: flex;
  8. justify-content: center;
  9. align-items: center;
  10. overflow: hidden;
  11. position: relative;
  12. }
  13. .login-box{
  14. background-color: white;
  15. padding: 40px 100px;
  16. border-radius: 8px;
  17. box-shadow: 0 0 5px 1px gainsboro;
  18. position: relative;
  19. }
  20. .login-part{
  21. display: flex;
  22. flex-direction: column;
  23. justify-content: center;
  24. margin-top: 20px;
  25. gap: 20px;
  26. }
  27. .login-input{
  28. width: 250px;
  29. height: 30px;
  30. border-radius: 8px;
  31. }
  32. .login-button{
  33. height: 40px;
  34. border-radius: 8px;
  35. background-color: #2c3e50;
  36. color: white;
  37. transition: 0.5s;
  38. }
  39. .login-button:hover{
  40. background-color: darkcyan;
  41. font-size: 15px;
  42. transition: 0.5s;
  43. }
  44. .login-button:active{
  45. background-color: darkslateblue;
  46. }
  47. .change-link{
  48. color: #00BFFF;
  49. text-decoration: underline;
  50. }
  51. .change-link:hover{
  52. color: cornflowerblue;
  53. }
  54. .decoration {
  55. position: absolute;
  56. width: 200px;
  57. height: 200px;
  58. background: linear-gradient(to left, #FDF5E6, #96CDCD );
  59. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  60. z-index: 1;
  61. }
  62. .decoration1 {
  63. top: 150px;
  64. left: -210px;
  65. }
  66. .decoration2 {
  67. top: 20px;
  68. right: -20px;
  69. width: 100px; /* 第二个菱形的大小 */
  70. height: 100px;
  71. background: linear-gradient(to right, #FFF5EE, #E6E6FA);
  72. }
  73. .decoration3 {
  74. top: 50px;
  75. right: -180px;
  76. width: 200px; /* 第三个菱形的大小 */
  77. height: 200px;
  78. background: linear-gradient(to right, #7FFFD4, cadetblue);
  79. }
  80. .decoration4 {
  81. top: 200px;
  82. right: -200px;
  83. width: 500px; /* 第三个菱形的大小 */
  84. height: 500px;
  85. z-index: -1;
  86. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  87. background: linear-gradient(to right, #FFFACD, #00BFFF);
  88. }
  89. .decoration5 {
  90. top: -100px;
  91. right: 200px;
  92. width: 400px; /* 第三个菱形的大小 */
  93. height: 400px;
  94. z-index: -1;
  95. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  96. background: linear-gradient(to right, #AFEEEE, #00BFFF);
  97. }
  98. .decoration6 {
  99. top: 10px;
  100. right: -680px;
  101. }
  102. .decoration7 {
  103. top: -170px;
  104. right: -500px;
  105. }
  106. .decoration8 {
  107. top: -140px;
  108. right: -655px;
  109. }

5) Anzeige der Anmelderegistrierungsseite

Die rautenförmigen Blöcke sind zufällig angeordnet und sehen zunächst so aus:

Später habe ich noch ein paar rautenförmige Blöcke hinzugefügt und ihre Positionen und Farben geändert. Der Endeffekt ist wie folgt:

2. Erstellen Sie ein Springboot+MySQL+Mybatis-Projekt und stellen Sie eine Verbindung zur Datenbank her

Verwenden Sie Springboot, MySQL und Mybatis, um einfach ein Back-End-Projekt zu erstellen und eine Verbindung zur Datenbank herzustellen. Referenz:

Idee, Spring Boot + MySQL + MyBatis-Projekt erstellt und zeigt den Inhalt der Datenbanktabelle auf der Webseite an._idea zeigt die Datenbank auf der Webseite an – CSDN-Blog

Ergänzung zum Artikel:

Wenn Sie Schwierigkeiten haben, bei jeder Erstellung einer Entitätsklasse Set- und Get-Methoden zu schreiben, können Sie in pom.xml die folgenden Abhängigkeiten hinzufügen:

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. </dependency>

Verwenden Sie dann die Annotation @Data in der Entitätsklasse, um das Schreiben der Set- und Get-Methoden zu überspringen:

Der Prozess ist fast derselbe, aber die Daten, die ich dieses Mal erstellt habe, sind unterschiedlich. Der Hauptgrund ist, dass sich die Attribute und Daten der Benutzertabelle geändert haben (der Unterschied ist nicht groß, sodass die Suppe die Medizin nicht verändert):

Es ist ein Problem aufgetreten: Maven lädt weiterhin Abhängigkeiten herunter, aber es erfolgt lange Zeit keine Antwort

Beim Erstellen des Projekts ist jedoch ein Fehler aufgetreten. Diesmal habe ich das Back-End-Projekt zum ersten Mal erstellt. Infolgedessen wurden nach dem Start von Maven weiterhin verschiedene Abhängigkeiten heruntergeladen -ins, und es kam lange Zeit keine Antwort:

Lösung:

Ich habe den Cache geleert und die Idee neu gestartet, aber sie hatte kaum Wirkung.

Später stellte ich fest, dass es daran liegen könnte, dass Maven standardmäßig ein ausländisches Zentrallager verwendet und ich die Idee des Maven-Plug-Ins verwendet habe, sodass die Download-Geschwindigkeit sehr langsam wäre.

Also habe ich Maven lokal heruntergeladen, siehe Tutorial:

Maven-Download- und Installations-Tutorial (sehr detailliert)_Maven-Installation-CSDN-Blog

Laden Sie es gemäß dem Tutorial herunter und ändern Sie die URL des Bildes im Maven-Installationspfad-&gt;conf-&gt;settings.xml. Ich habe die Umgebungsvariablen jedoch nicht direkt in der Idee unter file-&gt;settings-&gt; festgelegt Build, Execution, Deployment-&gt;Build Tools-&gt;Ändern Sie in Maven den Maven-Home-Pfad in den lokalen Pfad:

Nach der Änderung ist die Download-Geschwindigkeit tatsächlich viel schneller.

Die Verzeichnisstruktur des endgültigen Backend-Projekts ist wie folgt:

3. Schreiben Sie Anmelde- und Registrierungs-Backend-Funktionen

1. Anmeldelogik

Erhalten Sie die vom Frontend übergebenen ausgefüllten Informationen, einschließlich Benutzername und Passwort, und fragen Sie basierend auf dem Benutzernamen und dem Passwort in der Datenbank ab. Wenn der Benutzer gefunden wird, bedeutet dies, dass der Benutzer existiert und der Benutzername und das Passwort übereinstimmen . Die Anmeldung ist erfolgreich, andernfalls schlägt sie fehl.

2. Registrierungslogik

Erhalten Sie die vom Frontend übergebenen Füllinformationen, einschließlich Benutzername und Passwort. Nachdem Sie festgestellt haben, dass die Eingabeinformationen nicht leer sind, suchen Sie zunächst nach dem Benutzernamen in der Datenbank schlägt fehl und es werden Fehlerinformationen zurückgegeben. Benutzer können sich registrieren und den Datensatz in die Datenbank einfügen. Nach erfolgreicher Registrierung wird der Anmeldeblock angezeigt und der Registrierungsblock ausgeblendet.

3. Backend-Codeteil

Darunter resources-&gt;mapper-&gt;UserMapper.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  4. <mapper namespace="com.example.demo.mapper.UserMapper" >
  5. <resultMap id="result" type="com.example.demo.entity.User">
  6. <result property="id" column="id" />
  7. <result property="username" column="username" />
  8. <result property="password" column="password" />
  9. <result property="phone" column="phone" />
  10. <result property="gender" column="gender"/>
  11. </resultMap>
  12. <!-- 通过用户名和密码查找对应用户,用于登录-->
  13. <select id="findUserByNameAndPwd" resultMap="result" parameterType="User">
  14. select * from user
  15. where username = #{username}
  16. and password = #{password}
  17. </select>
  18. <!-- 通过用户名查找对应用户,用于注册检验用户名是否已存在-->
  19. <select id="findUserByName" resultMap="result" parameterType="User">
  20. select * from user
  21. where username = #{username}
  22. </select>
  23. <!-- 添加用户-->
  24. <insert id="addUser" parameterType="User">
  25. insert into user (username, password)
  26. values ( #{username}, #{password} )
  27. </insert>
  28. </mapper>

java-&gt;com.example.demo-&gt;mapper-&gt;UserMapper.java:

  1. package com.example.demo.mapper;
  2. import com.example.demo.entity.User;
  3. import org.apache.ibatis.annotations.Mapper;
  4. @Mapper
  5. public interface UserMapper {
  6. // 通过用户名和密码查找对应用户
  7. public User findUserByNameAndPwd(User user);
  8. // 通过用户名查找用户
  9. public User findUserByName(User user);
  10. // 添加用户
  11. public void addUser(User user);
  12. }

java-&gt;com.example.demo-&gt;service-&gt;UserService.java:

  1. package com.example.demo.service;
  2. import com.example.demo.entity.User;
  3. public interface UserService {
  4. // 通过用户名和密码查找对应id
  5. public User findUserByNameAndPwd(User user);
  6. // 通过用户名查找用户
  7. public User findUserByName(User user);
  8. // 添加用户
  9. public void addUser(User user);
  10. }

java-&gt;com.example.demo-&gt;service-&gt;UserServiceImpl.java:

  1. package com.example.demo.service;
  2. import com.example.demo.entity.User;
  3. import com.example.demo.mapper.UserMapper;
  4. import jakarta.annotation.Resource;
  5. import org.springframework.stereotype.Service;
  6. @Service
  7. public class UserServiceImpl implements UserService {
  8. @Resource
  9. private UserMapper userMapper;
  10. // 通过用户名和密码查找对应id
  11. @Resource
  12. public User findUserByNameAndPwd(User user){
  13. return userMapper.findUserByNameAndPwd(user);
  14. }
  15. // 通过用户名查找用户
  16. @Resource
  17. public User findUserByName(User user){
  18. return userMapper.findUserByName(user);
  19. }
  20. // 添加用户
  21. @Resource
  22. public void addUser(User user){
  23. userMapper.addUser(user);
  24. }
  25. }

java-&gt;com.example.demo-&gt;controller-&gt;UserController.java:

  1. package com.example.demo.controller;
  2. import com.example.demo.entity.User;
  3. import com.example.demo.result.Result;
  4. import com.example.demo.service.UserService;
  5. import jakarta.annotation.Resource;
  6. import org.springframework.web.bind.annotation.*;
  7. @RestController
  8. @RequestMapping("/api/user")
  9. public class UserController {
  10. @Resource
  11. UserService userService;
  12. // 登录
  13. @CrossOrigin
  14. @PostMapping(value = "/login")
  15. public Result login(@ModelAttribute("user") User user){
  16. String username=user.getUsername();
  17. String password=user.getPassword();
  18. System.out.println("Login received username: " + username);
  19. System.out.println("Login received password: " + password);
  20. User userCheck = new User();
  21. userCheck.setUsername(username);
  22. userCheck.setPassword(password);
  23. System.out.println(userCheck.getUsername() + " " + userCheck.getPassword());
  24. try{
  25. User findUser = userService.findUserByNameAndPwd(userCheck);
  26. if(findUser != null){
  27. return Result.success(findUser);
  28. }else {
  29. return Result.failure(401,"用户名或密码错误");
  30. }
  31. }catch (Exception e){
  32. return Result.failure(500,"服务器异常");
  33. }
  34. }
  35. // 注册
  36. @CrossOrigin
  37. @PostMapping(value = "/register")
  38. public Result register(@ModelAttribute("user") User user){
  39. // String username = "222";
  40. // String password = "222";
  41. User userCheck = new User();
  42. userCheck.setUsername(user.getUsername());
  43. userCheck.setPassword(user.getPassword());
  44. if(userCheck.getUsername() == null || userCheck.getUsername().isEmpty() || userCheck.getPassword() == null || userCheck.getPassword().isEmpty()){
  45. System.out.println("用户名或密码不可为空");
  46. return Result.failure(201,"用户名和密码不可为空");
  47. }else {
  48. System.out.println("Register received username: " + userCheck.getUsername());
  49. System.out.println("Register received password: " + userCheck.getPassword());
  50. try{
  51. // 先在数据库中查找是否已有用户名相同的用户
  52. User findUser = userService.findUserByName(userCheck);
  53. if(findUser != null){
  54. // 用户名已存在
  55. return Result.failure(202,"用户名已存在!");
  56. }
  57. else {
  58. // 新用户,数据库添加记录
  59. userService.addUser(userCheck);
  60. return Result.success(userCheck);
  61. }
  62. }catch (Exception e) {
  63. return Result.failure(500, "服务器异常");
  64. // }
  65. }
  66. }
  67. }
  68. }

4. Führen Sie das Projekt aus

Das Front-End und das Back-End werden separat ausgeführt und gestartet. Hier habe ich den Back-End-Port in application.properties auf 8081 geändert, und das Front-End ist der Standard 8080. Nachdem die Front- und Back-End-Projekte erfolgreich ausgeführt wurden, geben Sie http:/ ein. /localhost:8080 im Browser, überprüfen Sie es im Netzwerk der Entwicklertools, stellen Sie erfolgreich eine Verbindung zum Backend her, und beim Anmelden und Registrieren für die Testeingabe können verschiedene Eingabeaufforderungsinformationen und Popup-Eingabeaufforderungen erfolgreich zurückgegeben werden:

Nach erfolgreicher Anmeldung: