iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
Software Development

Spring Boot 零基礎入門系列 第 26

Spring Boot 零基礎入門 (26) - Spring JDBC 的用法 (上) - 執行 INSERT、UPDATE、DELETE sql

  • 分享至 

  • xImage
  •  

賀!此系列文榮獲 2023 iThome 鐵人賽《優選》獎項,正在規劃出書中,感謝大家的支持🙏,同名課程「Java 工程師必備!Spring Boot 零基礎入門」也已在 Hahow 平台上架

哈囉大家好,我是古古

在上一篇文章中,我們有在 Spring Boot 中載入了 Spring JDBC 的功能,並且也設定好了 MySQL 資料庫的連線資訊

所以接著這一篇文章,我們就會接著來介紹,要如何使用 Spring JDBC 的功能,去執行 sql 語法,進而去操作資料庫內部的數據

Spring JDBC 根據 sql 分成兩大類:update 和 query


在 Spring JDBC 中,會根據 sql 的語法去區分成兩大類,分別是 update 系列和 query 系列

  • 在 update 系列的方法中,可以去執行 INSERT、UPDATE、DELETE 這三種 sql 語法
  • 而在 query 系列的方法中,只能執行 SELECT 這一種 sql 語法

https://ithelp.ithome.com.tw/upload/images/20231010/20151036uLqGI6FodS.png

因此之後大家如果想要執行的是 INSERT sql,那就是得使用 update() 來執行,而想要執行 SELECT sql 的話,那就是得改用 query() 來執行

由於這兩種方法使用起來會有一點不一樣,因此接下來就會分成兩篇文章,分別來介紹這兩種方法的用法,而這一篇就會先來介紹 update() 系列的用法

補充:怎麼背哪個 sql 用哪個方法來執行?

在上面的圖中有提到,INSERT、UPDATE、DELETE sql 得用 update() 方法來執行,而 SELECT sql 得用 query() 方法來執行,不過這個對應關係是不用特別背的,其實他是可以透過「方法的名稱」去推敲出這件事

譬如說 update() 方法,他所代表的是「更新資料庫中的數據」的意思,而以下這三種情境

  • INSERT sql:在資料庫中新增一筆數據
  • UPDATE sql:修改資料庫中已存在的數據
  • DELETE sql:刪除資料庫中的數據

廣義上來說,都是去「改變資料庫中儲存的數據」,因此 INSERT、UPDATE、DELETE 這三種 sql 語法,就都可以使用 update() 方法來執行

而另外一個 query() 方法,他所代表的,則是「查詢資料庫中的數據」的意思,因此他就只會對應到 SELECT sql,專門負責去查詢資料庫中的資料

所以在使用 Spring JDBC 去執行 sql 語法時,是不用特別背哪一個 sql 要使用哪一個方法來執行的,只需要從名稱上面去推敲即可!

update() 的基本用法


在前面有提到,update() 方法是可以去執行 INSERT、UPDATE、DELETE 這三種 sql 語法,而要使用 update() 方法的話,基本上可以分成 4 個步驟

步驟一:注入一個 NamedParameterJdbcTemplate

首先第一步,就是在你的 Bean 裡面,先去注入一個 NamedParameterJdbcTemplate 進來

因此我們就可以在 StudentController 裡面,先使用 @Autowired,去注入 NamedParameterJdbcTemplate 這個 Bean 進來

@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

https://ithelp.ithome.com.tw/upload/images/20231010/201510362Bj1Yzm6ZM.png

這個 NamedParameterJdbcTemplate 是 Spring JDBC 自動幫我們生成的 Bean,他會負責去處理和資料庫溝通的所有事項,因此我們後續就通通都會透過 NamedParameterJdbcTemplate,去幫我們執行 sql 語法

所以換句話說的話,只要你使用的是 Spring JDBC,那你基本上就都是在跟 NamedParameterJdbcTemplate 打交道,了解他所提供的用法有哪些

補充:此張截圖中的其他程式(像是 @RestController@RequestMapping),是屬於 Spring MVC 的功能,如果對此部分不太了解,可以參考此系列文 Day 13~Day 23 的相關介紹

步驟二:撰寫 sql 語法

注入好 NamedParameterJdbcTemplate 進來之後,接著第二步,就是去寫出想要執行的 sql 語法,所以我們就可以去創建一個 String 類型的變數 sql,並且在裡面寫上到時候想要執行的 sql 語法

像是下方就是去寫了一個 INSERT sql 出來,因此到時候 Spring JDBC 就會去執行這一條 sql,在 student table 中插入一筆「id 為 3、並且 name 為 John」的數據

String sql = "INSERT INTO student(id, name) VALUES (3, 'John')";

https://ithelp.ithome.com.tw/upload/images/20231010/20151036IfvqMOOH5N.png

步驟三:新增一個 Map<String, object> 的 map 變數

接著第三步,是去新增一個類型為 Map<String, object> 的 map 變數出來,因此可以寫出如下的程式:

Map<String, Object> map = new HashMap<>();

補充:這篇文章的後面會詳細介紹這個 map 變數的用途,因此目前就先照抄即可

https://ithelp.ithome.com.tw/upload/images/20231010/20151036Vxr4Ua7htN.png

步驟四:使用 update() 方法

當前面的步驟都完成之後,最後一步,就是去使用 namedParameterJdbcTemplate 的 update() 方法,並且把上面所新增的 sql 和 map 這兩個變數,依照順序的給傳進去

namedParameterJdbcTemplate.update(sql, map);

https://ithelp.ithome.com.tw/upload/images/20231010/20151036KmIwdKdtAe.png

只要完成了這四個步驟,到時候當前端請求過來,然後 Spring Boot 運行到第 24 行的 update() 方法時,這時候 update() 方法就會去執行 sql 參數中所儲存的 sql 語法(即是 INSERT INTO student(id, name) VALUES (3, 'John')),在 MySQL 資料庫中插入一筆新的數據了!

實際測試

完成上述的程式之後,我們也可以運行起這個 Spring Boot 程式,然後實際到 API Tester 中,填入以下的請求:

https://ithelp.ithome.com.tw/upload/images/20231011/20151036ayj3qNPJw9.png

填寫完畢後按下右側的 Send 鍵發起 Http request,接著就可以回到 IntelliJ 上,然後開啟右側的 student table

https://ithelp.ithome.com.tw/upload/images/20231011/201510367QWXJgKAIs.png

這時就可以在 student table 中,看到多出了一筆「id 為 3、並且 name 為 John」的數據,而這就表示我們成功的透過了 Spring JDBC 的 update() 方法,在 Spring Boot 中執行 sql 語法,去新增一筆數據到資料庫中了!

https://ithelp.ithome.com.tw/upload/images/20231011/201510361OFpRAXKQ3.png

update() 中的 map 參數用法


透過上面的介紹,我們現在已經可以透過下面這種寫法,在 Spring Boot 程式中去執行 sql 語法,進而去修改資料庫中的數據了

https://ithelp.ithome.com.tw/upload/images/20231011/201510366HMtGaBsKK.png

不過,在上面的 「步驟三:新增一個 Map<String, object> 的 map 變數」,我們當時是先跳過沒有介紹,現在可以回頭來介紹這個 map 變數的用法

這個 map 變數的用途,是去 「放 sql 語法裡面的變數的值」,這句話聽起來是有點抽象,所以我們可以直接透過一個例子來看一下 map 變數的用法

例子:根據前端的參數,動態的決定 sql 中的值

在上面那段程式中,我們是直接寫死一條 sql 語法 INSERT INTO student(id, name) VALUES (3, 'John') 在程式裡面,因此不管前端傳了什麼參數過來,我們始終都是只能夠在資料庫中,去新增一筆「id 為 3、並且 name 為 John」的數據

但是這樣子的寫法就非常的不彈性,因為如果我們想要改成是去新增一筆「id 為 4、name 為 Bob」的數據的話,就得停止先 Spring Boot,然後修改程式,然後再重新運行 Spring Boot,就會變得非常麻煩

因此,假設我們想要「動態的決定」當前 sql 語法中的值的話,那就需要依靠 map 這個變數來幫忙了!

前置準備

了解了 map 變數的大概用途之後,我們可以先做一些前置準備,去接住前端傳過來的參數

因此可以先創建一個 Student class 出來,並且在裡面創建兩個變數 id 和 name(和其對應的 getter 和 setter),程式如下:

public class Student {

    private Integer id;
    private String name;

    // getter 和 setter
    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;
    }
}

接著在 StudentController 裡,在 insert() 方法的參數部分,使用 @RequestBody,去接住前端傳過來的參數

https://ithelp.ithome.com.tw/upload/images/20231011/20151036WtJcMJdKyx.png

補充:到這邊為止,都只是運用了 Spring MVC 的相關技術,這部分可以參考 Day 19 - 取得請求參數 (上) - @RequestParam、@RequsetBody 的介紹

修改 sql 語法、添加 map 變數中的值

接住前端所傳遞的變數之後,接著我們就可以來運用 map 變數,將前端所傳過來的 id 和 name 的值,插入一筆數據到資料庫中

這裡有兩個地方要修改:

  1. sql 語法:將「3 和 John」的地方,改成「:studentId:studentName
  2. map 變數:在 map 變數中 put 兩組 key-value 的值進去

https://ithelp.ithome.com.tw/upload/images/20231011/201510362eca9tOt3r.png

在 Spring JDBC 裡面,只要在 sql 語法中加上了「:」,就表示這是一個「sql 中的變數」

  • 譬如說像是 :studentId,就表示我們指定這是一個 sql 中的變數,名字叫做 studentId
  • 而又像是 :studentName,就表示我們指定這又是另一個 sql 中的變數,名字則是叫做 studentName

因此我們也是可以透過這個邏輯,在同一句 sql 語法裡面,添加無數個 sql 中的變數的,只需要在名字前面加上「:」即可

https://ithelp.ithome.com.tw/upload/images/20231011/20151036sLBBEeWl8f.png

而在 sql 中的這些 :studentId:studentName 變數,他們的值,我們就可以在 map 裡面去做指定

在使用 map 變數時,前面要放的是「sql 變數的名字」,後面放的則是「這個 sql 變數的值是多少」

譬如說我們想要指定 :studentId 這個 sql 變數的值是 5 的話,那麼就可以寫成是:

map.put("studentId", 5);

又或者是我們想要指定 :studentId 這個 sql 變數的值是 10 的話,那麼就可以寫成是:

map.put("studentId", 10);

再或者,我們想要指定 :studentId 這個 sql 變數的值,是「前端傳過來的 id 的值」的話,那麼就可以寫成是:

map.put("studentId", student.getId());

因此我們就可以透過 map 變數,動態的去決定 sql 中的變數的值了!

https://ithelp.ithome.com.tw/upload/images/20231011/20151036k5Yw9xFHlx.png

實際測試

完成上述的程式之後,我們也是可以重新運行 Spring Boot 程式,然後實際到 API Tester 中來測試一下

因為我們把 Spring Boot 程式改成「會根據前端所傳的 id 和 name 的值,插入一筆數據到資料庫中」,因此我們可以在 API Tester 中填入以下的參數,嘗試插入一筆「id 為 4、name 為 Bob」的數據到資料庫

https://ithelp.ithome.com.tw/upload/images/20231011/201510364RbuTKvAZZ.png

填寫完畢後按下右側的 Send 鍵發起 Http request,接著就可以回到 IntelliJ 上,然後開啟右側的 student table

這時就可以在 student table 中,看到多出了一筆「id 為 4、並且 name 為 Bob」的數據了!

https://ithelp.ithome.com.tw/upload/images/20231011/20151036H2WNvHya9X.png

因此這就表示,我們就成功的透過了 update() 方法的 map 參數,動態的去決定 sql 語法中的變數了!可喜可賀!

小結:update() 方法的用法


所以總結來說,想要使用 update() 方法,去執行 INSERT、UPDATE、DELETE 這三種 sql 的話,只要填入以下兩個參數即可:

  1. sql 參數:放想要執行的 sql 語法
  2. map 參數:動態的決定 sql 變數中的值

https://ithelp.ithome.com.tw/upload/images/20231012/20151036RmJz8kKHCM.png

總結


這篇文章先介紹了 Spring JDBC 中的兩大核心方法:update 和 query,並且也詳細介紹了 update 方法的基本用法,以及 update 的 map 參數用法,所以大家以後就可以透過這個寫法,在 Spring Boot 程式中去執行 INSERT、UPDATE、DELETE 這三類的 sql 語法了

那麼下一篇文章,我們就會接著來介紹 Spring JDBC 的另一個核心方法:query 方法,那我們就下一篇文章見啦!

相關連結



上一篇
Spring Boot 零基礎入門 (25) - 資料庫連線設定、IntelliJ 資料庫管理工具介紹
下一篇
Spring Boot 零基礎入門 (27) - Spring JDBC 的用法 (下) - 執行 SELECT sql
系列文
Spring Boot 零基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言