這一篇的主要內容是引入數據庫並實現通過數據庫驗證用戶名與密碼。
本篇目錄
一、引入數據庫
之前說過數據庫的採用是 MySQL,算是比較主流的選擇,從性能和體量等方面都比較優秀,當然也有一些弊端,但數據庫不是我們這裏討論的重點,暫時能用就行。
1.安裝數據庫
我的 MySQL 版本是 5.7,官方下載頁面是
https://dev.mysql.com/downloads/mysql/5.7.html#downloads
安裝教程我隨便搜了一篇,可以參考
https://blog.csdn.net/ma524654165/article/details/77855431
目前最新的版本是 8.0,也可以下載最新版本,使用最新版本需要做三處修改:
一、修改後端項目 pom.xml
的 mysql 依賴配置
二、爲數據庫設置一個長密碼,而不能用簡單的 admin
等
三、修改 mysql 的時區爲 +8:00
操作 MySQL 有很多種方式,可以用官方的 Command Line Client、Workbench,也可以用其它的一些界面化軟件,比如 Navicat 等。如果之前沒有接觸過數據庫,可以先用 Navicat,比較直觀。安裝方法參照這個博文:
https://blog.csdn.net/wypersist/article/details/79834490
我真是個好人啊,到處推薦別人的文章。。。
2.使用 Navicat 創建數據庫與表
下面的內容主要針對初次使用數據庫的讀者,有經驗的讀者可以直接執行下面的 sql 語句,記得先新建一個數據庫,名稱最好叫 white_jotter,方便以後的配置。
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '123');
按照上面貼出來的教程安裝完 MySQL 和 Navicat 後,打開 Navicat,點擊連接 -> MySQL,新建數據庫連接
在彈出的界面中配置相關信息,如果之前安裝數據庫是按照上面的教程來的話,連接名隨便起一個,主機名、端口、用戶名都不用修改,密碼是 root,其實我習慣設置成 admin,但看上面的教程是 root,這個項目無所謂,但記住實際的項目千萬不要設置這麼簡單的密碼,有不少企業的數據庫密碼還真就是 admin,被脫褲了才反應過來。。。
輸入之後可以點擊測試連接按鈕測試一下,然後確定。
雙擊在左側出現的連接 WJ,就打開了這個連接。安裝完 MySQL 會有幾個默認的數據庫,這些不要動,我們在連接(即 WJ)上右鍵新建一個數據庫,命名爲 white_jotter,字符集選擇 UTF-8,排序規則選擇 utf8_general_ci 即可。
創建之後左側就會出現一個名爲 white_jotter 的數據庫,雙擊它,點擊“表”,然後點擊“新建表”按鈕,就進入了表設計界面。
爲了完成登錄驗證,我們需要一個用戶表,一般命名爲 user,表裏面暫定設計 3 個字段,分別是 id、username、password。
表設計界面默認有一個“欄位”,我們可以在這個欄位中加入第一個需要的字段,即用戶的 id,其設置如下
箭頭指向的地方不要漏了。最後那把小鑰匙的意思是主鍵,可以點擊上面的主鍵按鈕或者直接點擊這個空白的欄位設置。
然後再添加第二、三個欄位,配置如下:
最後點擊保存,把表命名爲 user,這樣我們就有了第一張表。之後也可以在對象界面中選中表並點擊“設計表”按鈕重新設計。
接下來,我們雙擊 user 表,進入表中,添加一行用戶信息,id 爲 1,賬號是 admin,密碼是 123,也可以隨便按照自己喜好添加。
可以看到下面自動執行了一條 SQL 語句。這裏多說一句,真實的項目中,用戶信息可不能這麼存,直接把賬號密碼寫上去太危險了,一般的做法是存儲密碼等信息的 hash 值。
OK,到現在爲止,數據庫的操作就完成了。
二、使用數據庫驗證登錄
上一篇中我們直接在後端的控制器中用如下語句判斷了用戶名和密碼的正確性:
if (!Objects.equals("admin", username) || !Objects.equals("123456", requestUser.getPassword())) {
String message = "賬號密碼錯誤";
System.out.println("test");
return new Result(400);
} else {
return new Result(200);
}
使用數據庫驗證的邏輯其實也類似,大概是如下過程:
第一步,獲得前端發送過來的用戶名和密碼信息
第二步,查詢數據庫中是否存在相同的一對用戶名和密碼
第三步,如果存在,返回成功代碼(200),如果不存在,返回失敗代碼(400)
這裏的語句很簡單,但在修改之前還需要一些準備工作。
1.項目相關配置
打開我們的後端項目 wj
,首先修改 pom.xml
,配置我們需要的依賴。爲了方便以後的開發,我直接把我的配置粘貼上來,大家可以把原來的所有配置刪除掉,再粘貼我的。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.evan</groupId>
<artifactId>wj</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wj</name>
<description>White Jotter - Your Mind Palace</description>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- springboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot tomcat 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 熱部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- springboot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- elastic search -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- 用了 elasticsearch 就要加這麼一個,不然要com.sun.jna.Native 錯誤 -->
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
<!-- thymeleaf legacyhtml5 模式支持 -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<!-- 測試支持 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- tomcat的支持.-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.23</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version> 4.12</version>
</dependency>
<!-- commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- hsqldb -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
粘貼過去之後,IDE 會彈出提示,點擊 Import Changes 或 Enable Auto-Import 都可以。
接下來就等待依賴的自動安裝。過程可能比較長。如果自動安裝的過程沒有執行,可以在 pom.xml
上右鍵,選擇 Maven -> Reimport 。
配置完依賴後,還需要配置數據庫。打開 src\main\resources\application.properties
,在原來的基礎上,添加如下語句
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/white_jotter?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none
注意端口、數據庫名、用戶名、密碼要與你想使用的數據庫一致。
2.登錄控制器
配置完成後,我們就可以完善登錄控制器了。
User 類
首先,我們修改 User 類代碼如下,以建立對數據庫的映射。
package com.evan.wj.pojo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
@Entity
@Table(name = "user")
@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
int id;
String username;
String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
上面使用了一些註解,其中
@Entity 表示這是一個實體類
@Table(name=“user”) 表示對應的表名是 user
爲了簡化對數據庫的操作,我們使用了 Java Persistence API(JPA),對於 @JsonIgnoreProperties({ “handler”,“hibernateLazyInitializer” }),解釋起來比較複雜,下面的話看不懂可以忽略:
因爲是做前後端分離,而前後端數據交互用的是 json 格式。 那麼 User 對象就會被轉換爲 json 數據。 而本項目使用 jpa 來做實體類的持久化,jpa 默認會使用 hibernate, 在 jpa 工作過程中,就會創造代理類來繼承 User ,並添加 handler 和 hibernateLazyInitializer 這兩個無須 json 化的屬性,所以這裏需要用 JsonIgnoreProperties 把這兩個屬性忽略掉。
UserDAO
Data Access Object(數據訪問對象,DAO)即用來操作數據庫的對象,這個對象可以是我們自己開發的,也可以是框架提供的。這裏我們通過繼承 JpaRepository
的方式構建 DAO。
首先新建一個 package,命名爲 dao
,然後創建 Java Class,命名爲 UserDAO
,選擇種類爲 Interface
代碼如下
package com.evan.wj.dao;
import com.evan.wj.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDAO extends JpaRepository<User,Integer> {
User findByUsername(String username);
User getByUsernameAndPassword(String username,String password);
}
這裏關鍵的地方在於方法的名字。由於使用了 JPA,無需手動構建 SQL 語句,而只需要按照規範提供方法的名字即可實現對數據庫的增刪改查。
如 findByUsername
,就是通過 username
字段查詢到對應的行,並返回給 User 類。
這裏我們構建了兩個方法,一個是通過用戶名查詢,一個是通過用戶名及密碼查詢。
UserService
新建 package,命名爲 service
,新建 Java Class,命名爲 UserService
,代碼如下
package com.evan.wj.service;
import com.evan.wj.dao.UserDAO;
import com.evan.wj.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
UserDAO userDAO;
public boolean isExist(String username) {
User user = getByName(username);
return null!=user;
}
public User getByName(String username) {
return userDAO.findByUsername(username);
}
public User get(String username, String password){
return userDAO.getByUsernameAndPassword(username, password);
}
public void add(User user) {
userDAO.save(user);
}
}
這裏實際上是對 UserDAO
進行了二次封裝,一般來講,我們在 DAO 中只定義基礎的增刪改查操作,而具體的操作,需要由 Service 來完成。當然,由於我們做的操作原本就比較簡單,所以這裏看起來只是簡單地重命名了一下,比如把 “通過用戶名及密碼查詢並獲得對象” 這種方法命名爲 get
。
LoginController
登錄控制器是我們功能的核心部分,儘管它十分簡單。邏輯上面已經講過了,具體的實現,就是通過 UserService
提供的 get
方法查詢數據庫,如果返回的對象爲空,則驗證失敗,否則就驗證成功。代碼如下
package com.evan.wj.controller;
import com.evan.wj.pojo.User;
import com.evan.wj.result.Result;
import com.evan.wj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;
@Controller
public class LoginController {
@Autowired
UserService userService;
@CrossOrigin
@PostMapping(value = "/api/login")
@ResponseBody
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
username = HtmlUtils.htmlEscape(username);
User user = userService.get(username, requestUser.getPassword());
if (null == user) {
return new Result(400);
} else {
return new Result(200);
}
}
}
這個沒有其它要說的,忘記了怎麼回事的話可以回過頭看下上一篇文章
Vue.js + Spring Boot 前後端分離項目實踐(三):前後端結合測試(登錄頁面開發)
我們的項目會在很長一段時間內採取這種簡單的三層架構(DAO + Service + Controller),希望大家能慢慢體會這三個模塊的分工。這裏我簡單總結一下,先有個初步印象:
- DAO 用於與數據庫的直接交互,定義增刪改查等操作
- Service 負責業務邏輯,跟功能相關的代碼一般寫在這裏,編寫、調用各種方法對 DAO 取得的數據進行操作
- Controller 負責數據交互,即接收前端發送的數據,通過調用 Service 獲得處理後的數據並返回
在實踐中我們傾向於讓 Controller 顯得清涼一些,以方便代碼的閱讀者尋找分析功能的入口。但由於教程中各個層的迭代並不是同步的,可能會暫時捨棄這個原則,後期會逐漸重構。
3.測試
同時運行前端項目 wj-vue
與後端項目 wj
,訪問 http://localhost:8080/#/login
,輸入用戶名 admin
,密碼 123456
,我去,沒進去!沒進去就對了,因爲數據庫中 admin
的密碼式 123
啊。
重新輸入密碼 123
,成功進入 localhost:8080/#/index
OK,截至目前,前後端、數據庫之間的關係都打通了。下一篇我打算講講怎麼做表面功夫,即通過 Element 優化前端的界面。
查看系列文章目錄:
https://learner.blog.csdn.net/article/details/88925013