Spring Boot最好的學習方法就是實戰訓練,今天我們用很短的時間啟動我們第一個Spring Boot應用,並且連接我們的MySQL數據庫. 我將假設讀者為幾乎零基礎,在實戰講解中會滲透Spring框架中的一些知識點,並提供相關官方文檔鏈接, 讓我們一起在實戰中高效學習。
在這個實戰學習中, 我們將使用Spring Boot
與MySQL
數據庫構建一個簡單的登陸系統,功能包含注冊賬戶和登陸兩個功能,並用Spring Boot
官方推薦使用的thymeleaf
模板來生成簡單的前端頁面。 我們將使用Spring Boot
與MySQL
數據庫構建一個簡單的登陸系統,功能包含注冊賬戶和登陸兩個功能,並用Spring Boot
官方推薦使用的thymeleaf
模板來生成簡單的前端頁面。
看完該文章, 你將學會:
- 使用MySQL shell工具連接到MySQL server, 創建一個用戶, 並創建一個數據庫.
- 學習在Spring中配置並連接到你的MySQL數據庫.
- 學習並掌握Jpa的Entity, Repository的使用方法.
配置MySQL數據庫
第一步我們需要將MySQL數據庫下載到電腦里, 下載地址: 下載MySQL完整工具包
在頁面中點擊紅線框住的部分:
點進去, 拉到頁面下方, 點擊紅框部分右側的download
:
下載后, 按照安裝包提示的步驟操作, 安裝完畢后, 你會獲得幾個新應用, 我們只用其中一個, 它是:
它是MySQL的命令行工具, 我們用它來操作我們的MySQL數據庫.
但是我們不直接點開它, 我們在Windows自帶的Command Prompt中使用它.
- 打開Command Prompt, 輸入:
mysql -u root -p
進入Mysql命令行工具, 會提示你輸入密碼:
輸入在安裝過程中設置的密碼, 進入mysql命令行工具.
- 創建一個MySQL用戶, 在命令行中輸入命令(其實是SQL語句):
CREATE USER 'niudai'@'localhost' IDENTIFIED BY 'niudai';
這個語句的目的是創建一個用戶名為'niudai', 登陸密碼為'niudai'的MySQL數據庫管理員, 用這個賬號可以管理我們的數據庫, 也就是說如果你要管理數據庫, 你必須要有這么一個賬號.
- 再輸入如下語句:
CREATE DATABASE springdb;
熟悉SQL語言的同學應該很熟悉上面這句, 就是創建一個名為springdb
的數據庫, 這個數據庫就是我們的Spring Boot應用要連接的.
- 賦予剛創建的用戶名為"niudai"的用戶管理
springdb
數據庫的所有權限:
GRANT ALL ON springdb.* TO 'niudai'@'localhost';
創建一個Spring Boot應用
https://start.spring.io/這是Spring官網的依賴,把你所需要的依賴打包下載到本地,然后用idea打開即可。
我們所需要的四個依賴, 全是Spring Boot官方支持的庫, 知識點講解:
Thymeleaf
是現代服務端的Java模板引擎, 我們用它來生成HTML頁面.JPA
是Java Persistence API, 也就是Java持久層API, 它的本質是一套將Java的對象映射到數據庫中的關系表的標准, 而Spring-Boot
的JPA
依賴包含一個重要子依賴, 你一定聽過它的名字:Hibernate
. 它是JPA
的具體實現, 也是Spring Boot
的默認JPA
實現.官方文檔相關知識點閱讀MySQL
是用來實現從Java到MySQL連接的一個中間件.Web
是Spring Boot
重要核心組件, 網絡應用的必須品, 它包含了Tomcat
容器,Spring MVC
等核心組件.
所以我們也可以看到Spring Boot
其實相當於一個依賴打包器, 比如網絡模塊, 大家都需要Tomcat
容器, 也需要Spring MVC
框架, 那索性就放到一個包里, 也就是Web
包, 這樣一個依賴就解決了問題.
配置application.properties文件
application.properties
文件的作用有點類似於pom
, 但也不太一樣, pom
是管理你應用和其他庫的依賴關系,
而application.properties
則是去設置, 或是配置這些依賴, 是Spring應用的重要組成部分.
該文件可以在maven工程的src/main/java/resources/applicatio.properties
下找到.
在該文件中輸入如下屬性:
spring.datasource.username=niudai
spring.datasource.password=niudai
spring.datasource.url=jdbc:mysql://localhost:3306/springdb
spring.jpa.hibernate.ddl-auto=create
講解:
第三行的url
就是我們數據庫的地址, 3306
是MySQL默認的本地端口, 而springdb
正是我們之前創建的數據庫.
第一行和第二行聲明了我們之前創建的用戶名密碼和賬戶名, 都為niudai
第四行的create
為開發模式, 就是每次應用啟動都重新創建一個新表, 原有的表會清空, 開發結束后可以將其設置為none
.
聲明了這些之后, 啟動應用后, Spring
會自動用上述的信息連接並登陸你的MySQL
中名為springdb
的數據庫.
創建你的Entity(編寫代碼開始)
什么是Entity
呢? 說白了就是會被映射到數據庫中的Java Object
, 比如我們將要創建的User
類.
在src/main/java/
下創建一個文件User.java
:
package org.springframework.gsloggingdatamysql; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; private String name; private String email; private String password; @Override public String toString() { return "{" + " id='" + getId() + "'" + ", name='" + getName() + "'" + ", email='" + getEmail() + "'" + ", password='" + getPassword() + "'" + "}"; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } }
加了@Entity
注解, Spring
框架會得知這個類是一個Entity
, Hibernate
會把這個類映射到數據庫中的關系表, 這個關系表的列與User
的所有屬性一一對應.
相當於SQL語言中的:
CREATE TABLE User(id int, name varchar(255), email varchar(255), password varchar(255));
創建UserRepository
如果說User代表每個用戶, 或是用戶的信息, 那么UserRepository就代表儲存這些用戶的"庫", 我們創建一個UserRepository.java
, 注意它是一個接口, 也就是Interface
, 而不是Class
. 繼承JpaRepository接口也可以。
package org.springframework.gsloggingdatamysql; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User, Integer> { List<User> findByEmail(String email); void deleteByEmail(String email); }
你可能會疑惑這只是一個接口, 並沒有具體實現, 如何完成對User信息的儲存, 但事實上你只需聲明這個接口, 剩下的交給Spring
, 它會自動為你進行它的實現.
該類繼承了CrudRepository
, 也就是支撐"增刪改查"的一個Repository, 你可以在別的地方直接調用這個接口的方法, 方法名有規范, 比如你想通過郵箱查找, 那你就使用findByEmail(String email)
方法, Spring
會自動幫你將findByEmail
轉換成SQL語言中的`SELECT * FROM UserRepository WHERE email = 'email'
創建你的UserController
Controller
是接受用戶的url
請求, 將url
映射到某個具體的方法, 處理url
請求, 再返回一個Model
的東西, 是Spring MVC
中的C
層.
知識點: Spring MVC中的三層分別是Model
, View
, Controller
. 當用戶向你的服務器發送了請求后, 比如HTTP請求, Controller
先將請求映射到某個方法上, 方法根據該請求進行相應處理, 返回Model
, 這個Model
可以被理解成一個抽象的數據模型, 它儲存了網頁必須包含的信息, 但是它不是網頁本身, Model
會被送到View
層, 也就是用戶界面層, View
層將自己本身的模板和Model
內部的數據結合成為完整的一個頁面, 作為response
返還給用戶, 用戶便看到了你的頁面,.
但是現在隨着前后端的分離, View
層的意義已經不大,作為后端開發, 主要專注於Model
和Controller
.
創建一個文件: UserController.java
:
package org.springframework.gsloggingdatamysql; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class UserController { private static final Logger log = LoggerFactory.getLogger(UserController.class); @Autowired private UserRepository userRepository; @GetMapping(path="/add") // Map ONLY GET REQUESTs. public @ResponseBody String addNewUser (@RequestParam String name , @RequestParam String email, @RequestParam String password, User user) { // @ResponseBody means the returned String is a response, not a view name. user.setName(name); user.setEmail(email); user.setPassword(password); userRepository.save(user); log.info(user.toString()+" saved to the repo"); return "Saved"; } /** * 登陸方法, 用戶輸入郵箱和密碼, 查詢數據庫檢驗是否有該賬戶,如果有, * 返回原先頁面 ,登陸成功。 * @param email 用戶郵箱 * @param password 用戶密碼 * @param model Spring MVC中的Model,用來儲存經過controller處理后的信息,再由View層渲染 * 得到前端頁面。 * @return */ @GetMapping(path = "/login") public String login(@RequestParam String email, @RequestParam String password, Model model) { List<User> users = userRepository.findByEmail(email); // 如果數據庫中未查到該賬號: if (users == null) { log.warn("attempting to log in with the non-existed account"); return "該用戶不存在"; } else { User user = users.get(0); if (user.getPassword().equals(password)) { // 如果密碼與郵箱配對成功: model.addAttribute("name", user.getName()); log.warn(user.toString()+ " logged in"); } else { // 如果密碼與郵箱不匹配: model.addAttribute("name", "logging failed"); log.warn