SpringBoot入門系列(二十九)如何使用JdbcTemplate操作數(shù)據(jù)庫(kù)?
前面介紹了Mybatis數(shù)據(jù)持久化框架,Mybatis雖然功能強(qiáng)大,但是,使用起來(lái)還是比較復(fù)雜的。所以接下來(lái)介紹一個(gè)簡(jiǎn)單的數(shù)據(jù)持久化框架——JdbcTemplate。
一、什么是JdbcTemplateJDBC作為Java訪問數(shù)據(jù)庫(kù)的API規(guī)范,統(tǒng)一了各種數(shù)據(jù)庫(kù)的訪問方式。但是,直接在Java程序中使用JDBC還是非常復(fù)雜和繁瑣的。所以Spring對(duì)JDBC進(jìn)行了更深層次的封裝,而JdbcTemplate就是Spring提供的一個(gè)操作數(shù)據(jù)庫(kù)的便捷工具。它主要是實(shí)現(xiàn)了數(shù)據(jù)庫(kù)連接的管理,我們可以借助JdbcTemplate來(lái)執(zhí)行所有數(shù)據(jù)庫(kù)操作,例如插入、更新、刪除和從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),并且有效避免直接使用JDBC帶來(lái)的煩瑣編碼。
Spring Boot作為Spring的集大成者,自然會(huì)將JdbcTemplate集成進(jìn)去。Spring Boot針對(duì)JDBC的使用提供了對(duì)應(yīng)的Starter包:spring-boot-starter-jdbc,它其實(shí)就是在Spring JDBC上做了進(jìn)一步的封裝,方便在 Spring Boot 項(xiàng)目中更好地使用JDBC。
1、JdbcTemplate的特點(diǎn)
速度快,相對(duì)于ORM框架,JDBC的方式是最快的。
配置簡(jiǎn)單,Spring封裝的,除了數(shù)據(jù)庫(kù)連接之外,幾乎沒有額外的配置。
使用方便,就像DBUtils工具類,只需注入JdbcTemplate對(duì)象即可。
2、JdbcTemplate的幾種類型的方法
JdbcTemplate雖然簡(jiǎn)單,功能卻非常強(qiáng)大。它提供了非常豐富、實(shí)用的方法,歸納起來(lái)主要有以下幾種類型的方法:
(1)execute方法:可以用于執(zhí)行任何SQL語(yǔ)句,一般用于執(zhí)行DDL語(yǔ)句。
(2)update、batchUpdate方法:用于執(zhí)行新增、修改與刪除等語(yǔ)句。
(3)query和queryForXXX方法:用于執(zhí)行查詢相關(guān)的語(yǔ)句。
(4)call方法:用于執(zhí)行數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程和函數(shù)相關(guān)的語(yǔ)句。
總的來(lái)說(shuō),新增、刪除與修改三種類型的操作主要使用update和batchUpdate方法來(lái)完成。query和queryForObject方法中主要用來(lái)完成查詢功能。execute方法可以用來(lái)執(zhí)行任意的SQL、call方法來(lái)調(diào)用存儲(chǔ)過(guò)程。
二、Spring Boot集成JdbcTemplateSpring Boot集成JDBC很簡(jiǎn)單,需要引入依賴并做基礎(chǔ)配置即可。接下來(lái),我們就以一個(gè)具體的例子來(lái)學(xué)習(xí)如何利用Spring的JdbcTemplate進(jìn)行數(shù)據(jù)庫(kù)操作。
第一步,添加依賴配置
首先,項(xiàng)目pom.xml 配置文件中增加 JDBC等相關(guān)依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
上面的示例,在pom.xml文件中引入spring-boot-starterjdbc依賴。同時(shí),項(xiàng)目中使用 MySQL作為數(shù)據(jù)庫(kù),因此項(xiàng)目中需要引入MySQL驅(qū)動(dòng)包。spring-boot-starter-jdbc則直接依賴于HikariCP和spring-jdbc。
HikariCP是Spring Boot 2.0默認(rèn)使用的數(shù)據(jù)庫(kù)連接池,也是傳說(shuō)中最快的數(shù)據(jù)庫(kù)連接池。
spring-jdbc是Spring封裝對(duì)JDBC操作的工具包。
第二步,創(chuàng)建數(shù)據(jù)庫(kù)及表結(jié)構(gòu)
首先創(chuàng)建jdbctest測(cè)試數(shù)據(jù)庫(kù),然后再創(chuàng)建student表。包括id、name、sex、age等字段,對(duì)應(yīng)的SQL腳本如下:
DROP TABLE IF EXISTS `student`;CREATE TABLE `student` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',`name` varchar(32) DEFAULT NULL COMMENT '姓名',`sex` int DEFAULT NULL,`age` int DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
第三步,配置數(shù)據(jù)源
在application.properties配置MYSQL數(shù)據(jù)庫(kù)連接相關(guān)配置。具體配置如下:
spring.datasource.url=jdbc:mysql://localhost:3306/jdbctest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
上面的示例,數(shù)據(jù)庫(kù)連接配置非常簡(jiǎn)單,包括數(shù)據(jù)庫(kù)連接地址、數(shù)據(jù)庫(kù)用戶名、密碼以及數(shù)據(jù)驅(qū)動(dòng),無(wú)需其他額外配置。在Spring Boot 2.0中,com.mysql.jdbc.Driver已經(jīng)過(guò)期,推薦使用com.mysql.cj.jdbc.Driver。
第四步,使用JdbcTemplate
上面已經(jīng)就把JdbcTemplate整合到Spring Boot項(xiàng)目中,并創(chuàng)建好數(shù)據(jù)。接下來(lái)創(chuàng)建一個(gè)單元測(cè)試類JdbcTests,驗(yàn)證JdbcTemplate操作數(shù)據(jù)庫(kù)。示例代碼如下:
(SpringRunner.class)class JdbcTests {JdbcTemplate jdbcTemplate;void querytest() throws SQLException {List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from student ");System.out.println(list.size());Assert.assertNotNull(list);Assert.assertEquals(1,list.size());}}
上面是簡(jiǎn)單使用JdbcTemplate的測(cè)試示例,Spring的JdbcTemplate是自動(dòng)配置的。使用@Autowired將JdbcTemplate注入到需要的bean中即可直接調(diào)用。
運(yùn)行Run Test或在方法上右鍵|Run ‘querytest’,運(yùn)行測(cè)試方法。運(yùn)行結(jié)果如下圖所示:

如上圖所示,單元測(cè)試方法queryTest運(yùn)行成功,并輸出相應(yīng)的結(jié)果。說(shuō)明JdbcTemplate已經(jīng)連接上數(shù)據(jù)庫(kù),并成功執(zhí)行了數(shù)據(jù)查詢操作。
以上就把JdbcTemplate整合到Spring Boot 項(xiàng)目中了。
第一步,創(chuàng)建實(shí)體類
根據(jù)之前創(chuàng)建的Student表結(jié)構(gòu),創(chuàng)建對(duì)應(yīng)的實(shí)體類Student。具體代碼如下:
public class Student {private Long id;private String name;private int sex;private int age;public Student(){}public Student(String name, int sex, int age) {this.name = name;this.sex = sex;this.age = age;}//省略get、set方法}
需要注意,實(shí)體類的數(shù)據(jù)類型要和數(shù)據(jù)庫(kù)字段一一對(duì)應(yīng)。
第二步,封裝Repository實(shí)現(xiàn)增刪改查
首先,創(chuàng)建StudentRepository接口并定義常用的增刪改查的接口方法,示例代碼如下:
public interface StudentRepository {
??? int save(Student student);
??? int update(Student student);
??? int delete(long id);
??? Student findById(long id);
}上面的示例,在StudentRepository中定義了save、update、delete、findAll和findById等常用方法。
然后,創(chuàng)建StudentRepositoryImpl類,繼承StudentRepository接口,實(shí)現(xiàn)接口中的增刪改查等方法,示例代碼如下:
public class StudentRepositoryImpl implements StudentRepository {private JdbcTemplate jdbcTemplate;}
上面的示例,在StudentRepositoryImpl類上使用 @Repository 注解用于標(biāo)注數(shù)據(jù)訪問組件JdbcTemplate,同時(shí)在類中注入 JdbcTemplate實(shí)例。接下來(lái)逐個(gè)實(shí)現(xiàn)對(duì)應(yīng)的增刪查改方法。
(1)新增
在StudentRepositoryImpl類中實(shí)現(xiàn)StudentRepository接口中的save()方法。示例代碼如下:
@Overridepublic int save(Student student) {return jdbcTemplate.update("INSERT INTO Student(name, sex, age) values(?, ?, ?)",student.getName(),student.getSex(),student.getAge());}
在JdbcTemplate中,除了查詢有幾個(gè)API之外,新增、刪除與修改統(tǒng)一都使用update來(lái)操作,傳入SQL即可。update方法的返回值就是SQL執(zhí)行受影響的行數(shù)。
(2)修改
更新和新增類似,在StudentRepositoryImpl類中實(shí)現(xiàn)StudentRepository接口的update()方法。示例代碼如下:
public int update(Student student) {return jdbcTemplate.update("UPDATE Student SET name = ? , password = ? , age = ? WHERE id=?", student.getName(),student.getSex(),student.getAge(),student.getId());}
(3)刪除
通過(guò)用戶id刪除用戶信息,在StudentRepositoryImpl類中實(shí)現(xiàn)StudentRepository接口的update()方法。示例代碼如下:
public int delete(long id) {return jdbcTemplate.update("DELETE FROM Student where id = ? ",id);}
看到這里大家可能會(huì)有疑問:怎么新增、修改、刪除,都調(diào)用update方法,這跟其他的框架不一樣?嚴(yán)格來(lái)說(shuō),新增、修改、刪除都屬于數(shù)據(jù)寫入,通過(guò)update執(zhí)行對(duì)應(yīng)的SQL語(yǔ)句,實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的變更。
(4)查詢
根據(jù)用戶id查詢用戶信息,同樣在StudentRepositoryImpl類中實(shí)現(xiàn)StudentRepository接口的findById ()方法。示例代碼如下:
public Student findById(long id) {return jdbcTemplate.queryForObject("SELECT * FROM Student WHERE id=?", new Object[] { id }, new BeanPropertyRowMapper<Student>(Student.class));}
上面的示例,JdbcTemplate執(zhí)行查詢相關(guān)的語(yǔ)句使用query方法及queryForXXX方法。查詢對(duì)象使用queryForObject 方法。JdbcTemplate支持將查詢結(jié)果轉(zhuǎn)換為實(shí)體對(duì)象,使用new BeanPropertyRowMapper<Student>(Student.class)對(duì)返回的數(shù)據(jù)進(jìn)行封裝,它通過(guò)名稱匹配的方式,自動(dòng)將數(shù)據(jù)列映射到指定類的實(shí)體類中。
在執(zhí)行查詢操作時(shí),需要有一個(gè)RowMapper將查詢出來(lái)的列和實(shí)體類中的屬性一一對(duì)應(yīng)起來(lái):
如果列名和屬性名都是相同的,那么可以直接使用BeanPropertyRowMapper。
如果列名和屬性名不同,就需要開發(fā)者自己實(shí)現(xiàn) RowMapper 接口,將數(shù)據(jù)列與實(shí)體類屬性字段映射。
第三步,調(diào)用測(cè)試
接下來(lái)對(duì)封裝好的StudentRepository進(jìn)行測(cè)試,測(cè)試StudentRepository中的各個(gè)方法是否正確。創(chuàng)建StudentRepositoryTests類,將studentRepository注入到測(cè)試類中。
class StudentRepositoryImplTest {private StudentRepository studentRepository;void save() {Student student =new Student("weiz",1,30);studentRepository.save(student);}void update() {Student student =new Student("weiz",1,18);student.setId(1L);studentRepository.update(student);}void delete() {studentRepository.delete(1L);}void findById() {Student student = studentRepository.findById(1L);System.out.println("student == " + student.toString());}}
如上面的測(cè)試示例,我們依次執(zhí)行測(cè)試方法,執(zhí)行成功后會(huì)在數(shù)據(jù)庫(kù)查看數(shù)據(jù)是否符合預(yù)期。測(cè)試執(zhí)行正常,則表明StudentRepository中方法正確。

推薦閱讀:
Spring Boot入門系列(十九)集成mybatis,使用注解實(shí)現(xiàn)動(dòng)態(tài)Sql、參數(shù)傳遞等常用操作!
Spring Boot入門系列(十八)mybatis 使用注解實(shí)現(xiàn)增刪改查,無(wú)需xml文件
Spring Boot入門系列(十七)Mybatis創(chuàng)建自定義mapper 實(shí)現(xiàn)多表關(guān)聯(lián)查詢!
Spring Boot入門系列(十六)整合pagehelper,一秒實(shí)現(xiàn)分頁(yè)功能!
Spring Boot入門系列(十五) SpringBoot開發(fā)環(huán)境熱部署的配置
Spring Boot入門系列(十三)統(tǒng)一日志處理!
Spring Boot入門系列(十一)如何整合Mybatis,實(shí)現(xiàn)增刪改查【XML 配置版】
Spring Boot入門系列(十)如何使用攔截器,一學(xué)就會(huì)!
SpringBoot入門系列(三)SpringBoot資源文件屬性配置
SpringBoot入門系列(二)Controller介紹及如何返回json數(shù)據(jù)
SpringBoot入門系列(一)如何快速創(chuàng)建SpringBoot項(xiàng)

