Accessing data with MySQL筆記

飲水思源: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]"}]

也可以去數據庫驗證。

 

⑨一些安全性的改變。詳見原文。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章