JdbcTemplate的基本使用
1、JdbcTemplate的基本介紹
JdbcTemplate 是 Spring 對 JDBC 的封裝,目的是使JDBC更加易于使用,JdbcTemplate是Spring的一部分。JdbcTemplate 處理了資源的建立和釋放,它幫助我們避免一些常見的錯誤,比如忘了總要關閉連接。他運行核心的JDBC工作流,如Statement的建立和執行,而我們只需要提供SQL語句和提取結果即可。
Spring為了簡化數據庫訪問,主要做了以下幾點工作:
- 提供了簡化的訪問JDBC的模板類,不必手動釋放資源;
- 提供了一個統一的 DAO 類以實現 Data Access Object 模式;
- 把
SQLException封裝為DataAccessException,這個異常是一個RuntimeException,并且讓我們能區分SQL異常的原因,例如,DuplicateKeyException表示違反了一個唯一約束; - 能方便地集成Hibernate、JPA和MyBatis這些數據庫訪問框架。
1.1、為什么要使用jdbctemplate
如果直接使用JDBC的話,需要我們加載數據庫驅動、創建連接、釋放連接、異常處理等一系列的動作,繁瑣且代碼看起來不直觀。而使用 jdbctemplate 則無需關注加載驅動、釋放資源、異常處理等一系列操作,我們只需要提供 sql 語句并且提取最終結果即可,大大方便我們編程開發。此外,Spring提供的JdbcTempate能直接數據對象映射成實體類,不再需要獲取ResultSet去獲取值、賦值等操作,提高開發效率;
1.2、jdbctemplate常用方法
jdbcTemplate主要提供的5類方法及使用:
(1)execute() 方法:可以執行任何SQL語句,一般用于執行DDL語句。
(2)update(sqlStr, 參數列表) 方法:用于執行新增、修改、刪除等語句。
(3)batchUpdate() 方法:用于執行批處理相關語句,batchUpdate方法第二參數是一個元素為 Object[] 數組類型的 List 集合。
(4)query() 方法及 queryForXXX() 方法:用于執行查詢相關語句,查詢結果為基本數據類型或者是單個對象一般使用 queryForObject()
- queryForInt():查詢一行數據并返回 int 型結果。例子:jdbcTemplate.queryForInt("select count(*) from user")
- queryForObject(sqlStr, 指定的數據類型, 參數列表):查詢一行任何類型的數據,最后一個參數指定返回結果類型。例子:jdbcTemplate.queryForObject("selct count(*) from user", Integer.class)
- queryForMap(sqlStr, 參數列表):查詢一行數據并將該行數據轉換為 Map 返回。將會將列名作為key,列值作為 value 封裝成 map。當查詢出來的行數大于1時會報錯。例子:jdbcTemplate.queryForMap("select * from user where username = ?", "aaa");
- List<Map<String, Object>> queryForList(sqlStr, 參數列表):將查詢結果集封裝為 list 集合,該集合的每一條元素都是一個 map。
- query(sqlStr, RowMapper對象, 參數列表):查詢多行數據,并將結果集封裝為元素是 JavaBean 的 list。(注意,指定的JavaBean的屬性最好不要是基本類型,因為查詢出來的結果可能是null,而null賦值為基本數據類型將會報錯。比如int最好定義為Integer)
(5)call() 方法:用于執行存儲過程、函數相關語句。
2、JdbcTemplate的基本使用
2.1、新增數據(jdbcTemplate.update)
我們用 jdbcTemplate.update(sqlStr, 參數列表) 的方法來新增數據。
先導入以下依賴包。Spring框架的JdbcTemplate在spring-jdbc的jar包中,,除了要導入這個 jar 包外,還需要導入一個 spring-tx的jar包(它是和事務相關的)。當然連接池的jar包也不能忘記,這里使用的是 druid。

maven 依賴如下:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.8</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.12</version> </dependency> <!-- Spring-jdbc 用于配置JdbcTemplate --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.6.RELEASE</version> </dependency> <!--事務--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies>
然后在 spring 的 xml 配置文件中配置數據庫連接池和 JdbcTemplate,同時我們也開啟組件掃描。另外我們可以通過一個 jdbc.properties 配置文件來維護數據庫的連接配置。
下面假設我們操作的是 test 數據庫里面的 user 表,表結構如下:

jdbc.properties 配置文件內容:
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/test
prop.username=root
prop.password=123456
spring 的 xml 配置文件內容如下,文件命名可自定義,比如下面我們將其命名為 bean01.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--開啟組件掃描--> <context:component-scan base-package="test, service, dao"></context:component-scan> <!--引入外部配置文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置數據庫連接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClass}"></property> <!--通過${}使用外部配置文件的值--> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.username}"></property> <property name="password" value="${prop.password}"></property> </bean> <!-- 配置JdbcTmplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 注入dataSource --> <property name="dataSource" ref="dataSource"></property> <!-- <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>--> <!-- 也可以用構造函數寫法 --> </bean> </beans>
新建一個實體類 User :
package entity; public class User { private int id; private String name; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
新建一個 UserServiceImpl 類:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public void addUser(User user) { userDao.addUser(user); } }
新建一個 UserDaoImpl 類:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public void addUser(User user) { //創建SQL語句 String sql = "insert into user values(?, ?, ?)"; //調用方法執行SQL int updateRow = jdbcTemplate.update(sql, user.getId(), user.getName(), user.getPassword()); System.out.println(updateRow); } }
驗證代碼:
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; import entity.User; import service.UserService; import service.UserServiceImpl; public class Test01 { ApplicationContext ioc = new ClassPathXmlApplicationContext("bean01.xml"); //JdbcTemplate jdbcTemplate= ioc.getBean(JdbcTemplate.class); //我們也可以直接通過獲取到的jdbctemplate進行SQL操作,上面使用UserServiceImpl和UserDaoImpl只是為了更符合MVC分層的規范 //jdbcTemplate.update(sqlStr); @Test public void test1() { User user = new User(); user.setId(5); user.setName("AA"); user.setPassword("112233"); UserService userService = ioc.getBean(UserServiceImpl.class); userService.addUser(user); //執行增加方法 } }
執行上面 test1 方法,可以看到輸出如下:

即對一行數據起了作用,可以看到表數據發生了更改:

2.1.1、批量增加(batchUpdate)
批量增加可以使用 jdbcTemplate.batchUpdate() 方法,示例如下:
UserServiceImpl 增加批量增加方法:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public void addBath(List<Object[]> userList) { userDao.addBath(userList); } }
UserDaoImpl 增加批量增加方法:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.Arrays; import java.util.List; @Repository public class UserDaoImpl implements UserDao { //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public void addBath(List<Object[]> userList) { String sql = "insert into user values(?, ?, ?)"; int[] ints = jdbcTemplate.batchUpdate(sql, userList); //batchUpdate方法第二個參數是集合,該集合元素是數組,數組里面的每個值對應著添加到數據庫表里面的字段值。該方法返回影響行數數組 System.out.println(Arrays.toString(ints)); } }
驗證:
package test; import entity.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.UserService; import service.UserServiceImpl; import java.util.ArrayList; import java.util.List; public class TestMain { ApplicationContext ioc = new ClassPathXmlApplicationContext("bean01.xml"); @Test public void test2() { List<Object[]> userList = new ArrayList<>(); Object[] arr1 = {1, "name1", "password1"}; Object[] arr2 = {2, "name2", "password2"}; Object[] arr3 = {3, "name3", "password3"}; userList.add(arr1); userList.add(arr2); userList.add(arr3); UserService userService = ioc.getBean(UserServiceImpl.class); userService.addBath(userList); } }
2.2、修改和刪除數據(jdbcTemplate.update)
修改和刪除跟上面的新增操作一樣,只是SQL語句不同而已。
UserServiceImpl 增加修改和刪除方法:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public void updateUser(User user) { userDao.updateUser(user); } @Override public void deleteUser(int userId) { userDao.deleteUser(userId); } }
UserDaoImpl 增加修改刪除方法:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public void updateUser(User user) { String sql = "update user set name=?, password=? where id=?"; int updateRow = jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getId()); System.out.println(updateRow); } @Override public void deleteUser(int userId) { String sql = "delete from user where id=?"; int updateRow = jdbcTemplate.update(sql, userId); System.out.println(updateRow); } }
驗證代碼:
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import entity.User; import service.UserService; import service.UserServiceImpl;public class Test01 { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean01.xml"); //修改操作 @Test public void test1() { User user = new User(); user.setId(2); user.setName("AA"); user.setPassword("112233"); UserService userService = applicationContext.getBean(UserServiceImpl.class); userService.updateUser(user); } //刪除操作 @Test public void test2() { UserService userService = applicationContext.getBean(UserServiceImpl.class); userService.deleteUser(5); } }
2.2.1、批量修改和刪除(batchUpdate)
批量修改和批量刪除都可以使用 jdbcTemplate.batchUpdate() 方法,該用于執行批處理相關語句,batchUpdate() 方法第二參數是一個元素為 Object[] 數組類型的 List 集合。
示例如下。UserServiceImpl 增加批量修改和刪除方法:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; //批量修改 @Override public void updateBatch(List<Object[]> listArg) { userDao.updateBatch(listArg); } //批量刪除 @Override public void deleteBath(List<Object[]> listArg) { userDao.deleteBath(listArg); } }
UserDaoImpl 增加批量修改和刪除方法:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.Arrays; import java.util.List; @Repository public class UserDaoImpl implements UserDao { //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; //批量修改 @Override public void updateBatch(List<Object[]> listArg) { String sql = "update user set name=?, password=? where id=?"; int[] ints = jdbcTemplate.batchUpdate(sql, listArg); System.out.println(Arrays.toString(ints)); } //批量刪除 @Override public void deleteBath(List<Object[]> listArg) { String sql = "delete from user where id=?"; int[] ints = jdbcTemplate.batchUpdate(sql, listArg); System.out.println(Arrays.toString(ints)); } }
驗證:
package test; import entity.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.UserService; import service.UserServiceImpl; import java.util.ArrayList; import java.util.List; public class TestMain { ApplicationContext ioc = new ClassPathXmlApplicationContext("bean01.xml"); //批量修改 @Test public void test3() { List<Object[]> userList = new ArrayList<>(); Object[] arr1 = {"name1changed", "password1", 1}; Object[] arr2 = {"name2changed", "password2", 2}; Object[] arr3 = {"name3changed", "password3", 3}; userList.add(arr1); userList.add(arr2); userList.add(arr3); UserService userService = ioc.getBean(UserServiceImpl.class); userService.updateBatch(userList); } //批量刪除 @Test public void test4() { List<Object[]> userList = new ArrayList<>(); Object[] arr1 = {6}; Object[] arr2 = {7}; userList.add(arr1); userList.add(arr2); UserService userService = ioc.getBean(UserServiceImpl.class); userService.deleteBath(userList); } }
2.3、查詢數據
2.3.1、查詢返回某個值(queryForObject)
queryForObject(sqlStr, 指定的數據類型, 參數列表):查詢一行任何類型的數據,最后一個參數指定返回結果類型。
比如查詢 user 表內數據總數:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public int getUserCount() { return userDao.getUserCount(); } }
UserDaoImpl 代碼:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public int getUserCount() { String sql = "select count(*) from user"; int userCount = jdbcTemplate.queryForObject(sql, int.class); //第二個參數是返回類型的class return userCount; } }
驗證:
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; import service.UserService; import service.UserServiceImpl; public class Test01 { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean01.xml"); //查詢數量 @Test public void test4() { UserService userService = applicationContext.getBean(UserServiceImpl.class); int userCount = userService.getUserCount(); System.out.println(userCount); //將輸出user表內數據總數 } }
2.3.2、查詢返回一個JavaBean(queryForObject)
比如查詢 user 表內某一條數據,然后我們可以將該數據封裝成一個 User 對象:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User getUserInfo(int userId) { return userDao.getUserInfo(userId); } }
UserDaoImpl 代碼:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public User getUserInfo(int userId) { String sql = "select * from user where id=?"; // rowMapper 是一個接口,可以使用這個接口里面的實現類完成數據的封裝,規定每一行記錄和JavaBean的屬性如何映射 User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), userId); return user; } }
驗證:
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; import service.UserService; import service.UserServiceImpl; public class Test01 { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean01.xml"); @Test public void test3() { UserService userService = applicationContext.getBean(UserServiceImpl.class); User user = userService.getUserInfo(2); System.out.println(user.getName()); } }
2.3.2、查詢返回集合(query)
query(sqlStr, RowMapper對象, 參數列表):查詢多行數據,并將結果集封裝為元素是 JavaBean 的 list。(注意,指定的 JavaBean 的屬性最好不要是基本類型,因為查詢出來的結果可能是null,而null賦值為基本數據類型將會報錯。比如int最好定義為Integer)
比如查詢 user 表內的所有數據,并且將數據都封裝成 User 對象:
package service; import dao.UserDao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public List<User> getAllUser() { return userDao.getAllUser(); } }
UserDaoImpl 代碼:
package dao; import entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.List; @Repository public class UserDaoImpl implements UserDao{ //注入JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; @Override public List<User> getAllUser() { String sql = "select * from user"; List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class)); return userList; } }
驗證:
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; import service.UserService; import service.UserServiceImpl; import java.util.List; public class Test01 { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean01.xml"); //查詢全部數據 @Test public void test5() { UserService userService = applicationContext.getBean(UserServiceImpl.class); List<User> userList = userService.getAllUser(); for (User user: userList) { System.out.println(user.getName()); } } }

浙公網安備 33010602011771號