4.2 Spring JDBC Template常用方法介紹【execute()、update()、query()】
本篇文章我們將通過一個學生管理綜合案例來介紹一下Jdbc Template類中的常用方法。
一、項目基本文件創(chuàng)建
1、按照我們1.2節(jié)的方法創(chuàng)建一個Maven項目,并在pom.xml中導入以下依賴:
2、在資源文件夾下創(chuàng)建applicationContext.xml,在里面添加上我們4.1節(jié)中介紹的JDBC配置的XML文件:

完整的文件如下:
這里需要注意我們4.1節(jié)中提到的幾點,時區(qū)、驅(qū)動包名稱、SSL協(xié)議等是否按照要求配置好。
設置數(shù)據(jù)庫用戶名、密碼(自己數(shù)據(jù)庫的,這里作者的用戶名和密碼均為root)
注意這里的JDBC模板的配置:
配置JDBC模板,首先引入dataSource數(shù)據(jù)源,接著給Dao實現(xiàn)類中的私有屬性JDBCtemplate注入jdbctemplate值(注意:對象的注入使用ref屬性)。
3、創(chuàng)建數(shù)據(jù)庫:
數(shù)據(jù)庫SQL語句:
4、創(chuàng)建實體類Student
創(chuàng)建實體類Student,并為其設置4個私有屬性,id、name、sex、born。

分別創(chuàng)建他們的含參、無參構(gòu)造方法,getter、setter方法、toString方法。

完整代碼如下:
5、創(chuàng)建StudentDao接口類,定義對存儲在數(shù)據(jù)庫的數(shù)據(jù)的操作方法。
? ? 這里我們?yōu)榱嗣恳环NJdbc Template類中的方法都照顧到,我會定義較多的數(shù)據(jù)庫操作方法來使用Template類中的方法。
? ? 在StudentDao中定義findAllStudent()、addStudent(Student student)、updateStudent(Student student)、deleteStudent(int id)、findStudentById(int id)
? ? 除此之外,為了介紹execute()方法,我還會單獨創(chuàng)建一個測試類,用于execute()方法的運用。

完整代碼如下:
6、創(chuàng)建實現(xiàn)類StudentDaoImpl
? ? 該實現(xiàn)類用于實現(xiàn)StudentDao中為實現(xiàn)的方法。
? ? 首先我們需要先定義一個私有屬性JdbcTemplate,用該屬性來調(diào)用update方法。
代碼如下:
實現(xiàn)接口中為實現(xiàn)的方法,StudentDaoImpl就創(chuàng)建完成了。
之后再創(chuàng)建測試類,對StudentDaoImpl中的方法進行測試即可。
二、update()、query()、execute()方法介紹(實現(xiàn)StudentDao中未實現(xiàn)的方法)
接下來編寫的update()、query()的代碼將編寫在StudentDaoImpl.java.中
1、Update()方法
在 Spring Jdbc中,update()方法可以完成插入、更新和刪除數(shù)據(jù)的操作。其中幾個常用的update方法的重載如下介紹。

這里最為常用的就是第三個和第四個(一些簡單的查詢也會使用到第一個和第二個)
接下來,我們實現(xiàn)一下使用update方法的數(shù)據(jù)庫操作方法。
1》addStudent()
? ? 首先我們想一下向數(shù)據(jù)庫里面添加數(shù)據(jù)的SQL語句:insert into course(id,name,sex,born) values(1001,'zhangsan',男,2001-1-2);
? ? 這里面需要的參數(shù)是非常多的,尤其是表項比較多的時候。參數(shù)多的話,可以使用我們上面表中提到的 int update(String sql,Object..args)方法,它可以將多個SQL語句中使用到的參數(shù)以一個數(shù)組的形式封裝起來,整體進行參數(shù)傳遞。它返回的int值是受影響的行數(shù),并且需要注意的是,參數(shù)數(shù)組不能為空。
? ? 這樣思路就會很清晰,根據(jù)方法需要的參數(shù),我們肯定需要一個SQL語句,并且需要將SQL語句中的參數(shù)用數(shù)組進行封裝整體傳入,這樣問題就解決了。
代碼如下:
? ? 首先定義SQL語句,用到的參數(shù)使用“?”進行占位,然后定義一個對象類型數(shù)組將SQL語句中使用到的參數(shù)保存于此。這里使用的是 int update(String sql,Object..args)方法,該方法有兩個參數(shù),一個是SQL語句,另一個是SQL語句需要的所有參數(shù)。這里要求SQL語句所需要的參數(shù)不能為空,否則或報錯。
2》updateStudent()
? ? 首先我們想一下向數(shù)據(jù)庫里面添加數(shù)據(jù)的SQL語句:UPDATE student SET name=“zhangsan”,sex=”男“,born=2003-09-08? WHERE id=1
? ? 這里也需要向SQL語句傳遞很多參數(shù),所以思路和上面添加學的生方法是一樣的思路,這里就直接給出代碼來了:
3》deleteStudent(int id)
? ? 首先我們來想一下刪除一個學生的SQL語句:DELETE FROM student WHERE id =1
這里SQL語句中只含有一個參數(shù),并不是有很多參數(shù),所以我們可以使用表中的第三個方法
update(String sql ,PreparedStatementSetter pss),這里的參數(shù)就是一個了。
所以本次的代碼就很簡單了,參數(shù)值不在需要使用getter方法進行獲取,而是直接作為一個形式參數(shù)傳到函數(shù)中。
代碼直接給大家了:
2、query()方法
該方法主要用于處理數(shù)據(jù)庫表的各種查詢操作。具體介紹如下表:

我們實現(xiàn)一下使用query方法的數(shù)據(jù)庫操作方法。
1》findAllStudent()
? ? 首先我們來想一下查找一個數(shù)據(jù)表中所有表項的SQL語句:select * from student 。
在該條語句中,沒有任何的參數(shù)進行傳遞,因此我們可以選用表項中的第一個方法List query(sql,rowMapper),該方法共有兩個參數(shù),其中一個是要被執(zhí)行的SQL語句,另一個是一個rowMapper對象,用于將結(jié)果包裝成一個rowMapper對象,該對象的結(jié)果會與數(shù)據(jù)庫表項屬性一一對應,最終該方法會返回一個List結(jié)果。
? ? 這里思路非常清晰,我們直接定義一個SQL語句,把他傳給query方法,query再返回一個list結(jié)果集,這就是我們想要i的。
直接代碼奉上:

? ? ?這里先定義一個SQL語句,用于查找所有學生,再創(chuàng)建一個RowMapper對象,用于存儲返回的查詢結(jié)果。
2》findStudentById(int id)
? ? 老規(guī)矩,我們還是先想一下根據(jù)id查詢表項的SQL語句:SELECT * FROM student WHERE id=1? .可以看到,這里使用到了一個參數(shù),就是id值。而且我們再細心觀察一下,通過id值找到的表項是單行記錄(id是唯一值)。因此我們使用的query函數(shù)必須可以傳遞SQL語句中的值,還得返回單行記錄才能實現(xiàn)該功能。所以我們可以使用表格中第四個方法? ? ? ? ?queryForObject(sql,rowMapper,id),該方法有三個參數(shù),第一個是要被執(zhí)行的SQL語句,第二個是以List形式返回結(jié)果的rowMapper對象參數(shù),第三個是SQL語句所需要的參數(shù)值。
國際慣例,這里直接將代碼給到大家,大家可以理一下思路:

3、execute()方法
? ? 首先我們來看一下該方法的語法格式:execute(SQL語句),該方法中只存在一個參數(shù),由此我們可以得出該方法的作用就是執(zhí)行SQL語句,至于SQL語句的參數(shù)需要我們直接寫在SQL語句中。由于該方法與sqlyog或者navicat中執(zhí)行SQL語句的方法非常像,這里就舉一個簡單的例子給大家了解一下該方法的使用方法。
例子:插入學生信息:
從這里我們可以看到使用execute方法只需要i在測試類中初始化spring容器、在spring容器中獲取JdbcTemplate實例用于調(diào)用execute方法,在其中插入SQL語句就可以執(zhí)行。
三、編寫測試類,對上述方法進行逐一驗證
1、addStudent()
編寫addStudentTest
運行測試類:

數(shù)據(jù)庫:

2、updateStudent()
創(chuàng)建Student_Update_Test.java
運行測試類:

數(shù)據(jù)庫:

3、deleteStudent(int id)
創(chuàng)建測試類Student_Delete_Test()
運行結(jié)果:

數(shù)據(jù)庫:

4、findAllStudent()
創(chuàng)建測試類Student_Find_All_Test.java
運行測試類:

5、findStudentById(int id)
創(chuàng)建測試類Student_Find_By_Id_Test().java
運行測試類:

查詢成功。
? ? 到這里,我們對于三種常用方法的介紹就告一段落了,接下來我會介紹一下我在項目中遇到的一些問題。
四、代碼調(diào)試(DeBug)
1、查詢結(jié)果中,生日這一屬性為null。

我這里的錯誤原因是因為實體類的屬性名和數(shù)據(jù)庫的字段名稱沒有一一對應,簡單來說就是Student類里面寫的是birthday,而數(shù)據(jù)庫中寫的確是born。
這里我將他們改成一致的名稱就可以了。

運行結(jié)果:

2、參數(shù)傳遞錯誤:
錯誤截圖:

錯誤信息:
關(guān)鍵性信息翻譯:
可以看到,某一個函數(shù)的形參有兩個,但是傳參的時候第二個參數(shù)是空的。
根據(jù)提示信息可以看到是(StudentDaoImpl.java:45)文件的45行出現(xiàn)了問題。
問題鎖定:

就是這個update方法第二參數(shù)為空,我嘗試輸出該屬組對象,只能輸出其地址,于是我仔細檢查了一下,發(fā)現(xiàn)是典型的語法錯誤:

數(shù)組在定義時,沒有加上大括號,導致數(shù)組構(gòu)建失敗,從而使得第二個參數(shù)為空導致錯誤。

修改完成后再次運行

五、知識拓展
1、常用SQL語句格式
2、JDBC驅(qū)動配置小細節(jié):
JDBC驅(qū)動配置小細節(jié):較新版本的Java需要使用的JDBC的驅(qū)動為:com.mysql.cj.jdbc.Driver。并且需要設置時區(qū)serverTimezone=GMT%2B8
3、BeanPropertyRowMapper 的用法
將數(shù)據(jù)庫查詢結(jié)果轉(zhuǎn)換為Java類對象。 常應用于使用Spring的JdbcTemplate查詢數(shù)據(jù)庫,獲取List結(jié)果列表,數(shù)據(jù)庫表字段和實體類自動對應。
以上就是本篇文章的所有內(nèi)容,感謝你能看到這里。歡迎大家關(guān)注,一起學習Spring,一起進步。