本指南指導您創建連接到MySQL數據庫的Spring應用程序(與大多數其他指南和許多示例應用程序使用的內存中的嵌入式數據庫相反)。它使用Spring Data JPA訪問數據庫,但這只是許多可能的選擇之一(例如,您可以使用普通的Spring JDBC)。
你將建立什麼
您將創建一個MySQL數據庫,構建一個Spring應用程序,並將其連接到新創建的數據庫。
MySQL使用GPL許可,因此使用它發佈的任何二進制程序也必須使用GPL。參見GNU通用公共許可證。
你需要什麼
-
MySQL版本5.6或更高。如果安裝了Docker,那麼將數據庫作爲容器運行可能會很有用。
-
大約15分鐘
-
最喜歡的文本編輯器或IDE
-
jdk1.8或更高
-
Gradle 4+或Maven 3.2+
如何完成本指南
與大多數Spring入門指南一樣,您可以從頭開始並完成每個步驟,或者可以繞過您已經熟悉的基本設置步驟。無論哪種方式,您最終都會得到工作代碼。
-
要從頭開始,先從Spring Initializr開始。
-
要跳過基本步驟,請做以下步驟:
下載並解壓縮本指南的源存儲庫,或者使用Git克隆它:
Git clone https://github.com/springing-guides/gs-accessing-datamysql.git
cd到 gs-accessing-data-mysql/initial
跳轉以創建數據庫。
完成後,可以根據代碼檢查結果 gs-accessing-data-mysql/complete
從Spring Initializr開始
對於所有Spring應用程序,都應該從Spring Initializr開始。Initializr提供了一種快速獲取應用程序所需的所有依賴項的方法,併爲您進行了大量設置。這個示例需要Spring Web Starter、Spring Data JPA和MySQL驅動程序依賴項。下圖顯示了爲這個示例項目設置的Initializr:
創建數據庫
打開一個終端(Microsoft Windows中的命令提示符)並打開一個可以創建新用戶的MySQL客戶端。
例如,在Linux系統上,使用以下命令:
$ sudo mysql --password
它以root用戶身份連接到MySQL,並允許用戶從所有主機訪問。對於生產服務器,這不是推薦的方法。
要創建一個新的數據庫,在mysql提示符下運行以下命令:
mysql> create database db_example; -- Creates the new database
mysql> create user 'springuser'@'%' identified by 'ThePassword'; -- Creates the user
mysql> grant all on db_example.* to 'springuser'@'%'; -- Gives all privileges to the new user on the newly created database
創建application.properties文件
Spring Boot爲您提供所有設置的默認值。例如,默認數據庫是H2。因此,當您希望使用任何其他數據庫時,您必須在application.properties中定義連接屬性。
創建一個名爲src/main/resources/application的資源文件。屬性,如下表所示:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword
在這裏,spring.jpa.hibernate.ddl-auto可以是none、update、create或create-drop。有關詳細信息,請參閱Hibernate文檔。
-
none: MySQL的默認值。數據庫結構未作任何更改。
-
update:Hibernate根據給定的實體結構更改數據庫。
-
create:每次創建數據庫,但在關閉時不刪除它。
-
create-drop:創建數據庫,並在SessionFactory關閉時刪除它。
必須從create或update開始,因爲還沒有數據庫結構。在第一次運行之後,您可以根據程序需求將其切換爲update或none。當您想要對數據庫結構進行一些更改時,請使用update。
H2和其他嵌入式數據庫的默認值是create-drop。對於其他數據庫,比如MySQL,默認值是none。
在數據庫處於生產狀態之後,將其設置爲none,從連接到Spring應用程序的MySQL用戶那裏撤銷所有特權,只允許MySQL用戶SELECT, UPDATE, INSERT 和 DELETE,這是一個很好的安全實踐。你可以在這篇指南的最後讀到更多。
創建@Entity模型
您需要創建實體模型,如下所示(在src/main/java/ com/example/accessingdatamysl/user.java):
package com.example.accessingdatamysql;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity // This tells Hibernate to make a table out of this class
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Hibernate自動將實體轉換爲表。
創建存儲庫
您需要創建存儲用戶記錄的存儲庫,如下所示(在src/main/java/ com/example/accessingdatamysl/userrepository.java):
package com.example.accessingdatamysql;
import org.springframework.data.repository.CrudRepository;
import com.example.accessingdatamysql.User;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface UserRepository extends CrudRepository<User, Integer> {
}
Spring在同名的bean中自動實現了這個存儲庫接口(在案例中有一個變化——它被稱爲userRepository)。
創建一個控制器
你需要創建一個控制器來處理HTTP請求到你的應用程序,如下所示(在src/main/java/ com/example/accessingdatamysl/maincontroller.java):
package com.example.accessingdatamysql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller // This means that this class is a Controller
@RequestMapping(path="/demo") // This means URL's start with /demo (after Application path)
public class MainController {
@Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
@PostMapping(path="/add") // Map ONLY POST Requests
public @ResponseBody String addNewUser (@RequestParam String name
, @RequestParam String email) {
// @ResponseBody means the returned String is the response, not a view name
// @RequestParam means it is a parameter from the GET or POST request
User n = new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
@GetMapping(path="/all")
public @ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
}
前面的示例顯式地爲這兩個端點指定了POST和GET。默認情況下,@RequestMapping映射所有HTTP操作。
創建一個應用程序類
Spring Initializr爲應用程序創建一個簡單的類。下面的清單顯示了Initializr爲這個示例創建的類(在src/main/java/com/example/accessingdatamysql/AccessingDataMysqlApplication.java):
package com.example.accessingdatamysql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
對於本例,不需要修改AccessingDataMysqlApplication類。
@SpringBootApplication是一個方便的註釋,添加了以下所有內容:
-
@Configuration:標記類作爲應用程序上下文bean定義的源。
-
@EnableAutoConfiguration:告訴Spring Boot根據類路徑設置、其他bean和各種屬性設置開始添加bean。例如,如果spring-webmvc在類路徑中,這個註釋將應用程序標記爲web應用程序並激活關鍵行爲,比如設置一個DispatcherServlet。
-
@ComponentScan:告訴Spring在com/example包中尋找其他組件、配置和服務,讓它找到控制器。
main()方法使用Spring引導的Spring application. run()方法來啓動應用程序。您注意到沒有一行XML嗎?也沒有web.xml文件。這個web應用程序是100%純Java的,您不必配置任何管道或基礎設施。
構建一個可執行JAR
您可以使用Gradle或Maven從命令行運行該應用程序。您還可以構建一個包含所有必要的依賴項、類和資源的可執行JAR文件並運行它。構建可執行jar使得在整個開發生命週期中,跨不同環境,等等,將服務作爲應用程序進行發佈、版本和部署變得更加容易。
如果你使用Gradle,你可以使用./gradlew bootRun來運行這個應用程序。或者,您可以使用./gradlew build構建JAR文件,然後運行JAR文件,如下所示:
java -jar build/libs/gs-accessing-data-mysql-0.1.0.jar
如果使用Maven,可以使用./mvnw spring-boot:run來運行應用程序。或者,您可以使用./mvnw clean包構建JAR文件,然後運行JAR文件,如下所示:
java -jar target/gs-accessing-data-mysql-0.1.0.jar
這裏描述的步驟創建了一個可運行的JAR。您還可以構建一個經典的WAR文件。
運行應用程序時,將顯示日誌記錄輸出。服務應該在幾秒鐘內啓動並運行。
測試應用程序
現在應用程序正在運行,您可以使用curl或類似的工具對其進行測試。你有兩個HTTP端點,你可以測試:
GET localhost:8080/demo/all
:得到所有的數據
POST localhost:8080/demo/add
: 向數據添加一個用戶
下面的curl命令添加了一個用戶:
$ curl localhost:8080/demo/add -d name=First -d [email protected]
答覆如下:
Saved
以下命令顯示所有用戶:
$ curl 'localhost:8080/demo/all'
答覆如下:
[{"id":1,"name":"First","email":"[email protected]"}]
進行一些安全性更改
在生產環境中,您可能會受到SQL注入攻擊。黑客可以注入DROP表或任何其他破壞性的SQL命令。因此,作爲一種安全實踐,在向用戶公開應用程序之前,應該對數據庫進行一些更改。
下面的命令撤銷與Spring應用程序關聯的用戶的所有特權:
mysql> revoke all on db_example.* from 'springuser'@'%';
現在,Spring應用程序不能在數據庫中執行任何操作。
應用程序必須有一些特權,所以使用下面的命令來授予應用程序所需的最小特權:
mysql> grant select, insert, delete, update on db_example.* to 'springuser'@'%';
刪除所有特權並授予某些特權將使Spring應用程序獲得僅更改數據庫數據而不是結構(模式)所需的特權。
當你想改變數據庫:
-
重新批准權限。
-
將
spring.jpa.hibernate.ddl-auto
更改爲update。 -
重新運行您的應用程序。
然後重複這裏顯示的兩個命令,使您的應用程序在生產中再次安全使用。更好的方法是使用專門的遷移工具,比如Flyway或Liquibase。
總結
恭喜你!您剛剛開發了一個綁定到MySQL數據庫的Spring應用程序,並準備投入生產!