飲水思源:https://spring.io/guides/gs/accessing-data-mysql/
①通過https://start.spring.io/創建項目,添加Spring Web, Spring Data JPA, 和MySQL Driver這三個依賴。
②創建數據庫
打開命令行工具登陸一個可以創建用戶的用戶:
D:\Temp>mysql -uxkfx -p
創建一個新的數據庫:
create database db_example;
創建一個新的用戶:
create user 'springuser'@'%' identified by 'ThePassword';
查看是否創建成功:
mysql> SELECT user,host FROM mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| springuser | % |
| xkfx | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
把新數據庫的所有權限都賦予新用戶:
grant all on db_example.* to 'springuser'@'%';
③編輯application.properties
Spring Data JPA底層默認用hibernate實現。
需要對數據源以及hibernate的一些行爲進行配置:
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.datasource.driver-class-name =com.mysql.cj.jdbc.Driver #spring.jpa.show-sql: true
關於spring.jpa.hibernate.ddl-auto屬性,原文有較詳細說明。
④創建實體(@Entity)模型:
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將自動把實體翻譯成一張表。
⑤創建Repository
您需要創建保存用戶記錄的存儲庫:
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請求,如下所示:
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(); } }
⑦程序入口已經自動創建了,所以直接打包運行程序:
$ mvn package
$ java -jar target/accessingdatamysql-0.0.1-SNAPSHOT.jar
打包過程順利,但是運行過程卻出現了異常。我發現數據庫中已經多了hibernate_sequence和user這兩張表。
錯誤日誌主要信息:
ERROR 12568 --- [ main] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Failed to execute isValid() for connection, configure connection test query (com.mysql.jdbc.Connection.isValid(I)Z).
WARN 12568 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError: com.mysql.jdbc.Connection.isValid(I)Z
對BUG進行復現發現,數據庫中的表是在執行mvn package時創建的,而非執行java命令時創建的。
該BUG已解決,且已更新到上文(2022年3月13日),詳見:https://www.cnblogs.com/xkxf/p/15999655.html
⑧手動測試。
通過curl指令POST一些數據到數據庫:
curl localhost:8080/demo/add -d name=xkfx -d email=1223830128309@qq.com
可以通過curl,也可以通過瀏覽器訪問http://localhost:8080/demo/all去查看數據:
[{"id":1,"name":"xkfx","email":"[email protected]"},
{"id":2,"name":"xk3123fx","email":"[email protected]"},
{"id":3,"name":"xk3123fx","email":"[email protected]"},
{"id":4,"name":"xk3123fx","email":"[email protected]"},
{"id":5,"name":"xk3123123fx","email":"[email protected]"}]
也可以去數據庫驗證。
⑨一些安全性的改變。詳見原文。