目錄
寫在前面
一、什么是JdbcTemplate?
二、JdbcTemplate框架搭建
1、匯入所需jar包
2、配置JDBC資料源
(1)、直接在中配置資料源
(2)、引入外部組態檔
3、配置JdbcTemplate物件
三、持久化層操作詳解
1、增刪改操作
2、批量增刪改操作
3、查詢單行資料
4、查詢多行資料
5、查詢單一指定數值
四、使用具名引數的JdbcTemplate
1、宣告具名引數類
2、具名引數的普通使用
3、通過SqlParameterSource物件傳入數值
五、自動裝配JdbcTemplate并實作Dao
六、寫在最后
寫在前面
Hello,你好呀,我是灰小猿,一個超會寫bug的程式猿!
用堅持締造技術、用指尖敲動未來!愿我們每一次敲動鍵盤,都能讓生活變得更智能、世界變得更有趣!
在使用Spring進行業務邏輯層處理時,你是否有想過,如此強大的Spring框架在對資料庫相關的業務處理時,是否有更加便捷的操作呢?Spring框架又能將傳統JDBC資料庫的操作優化到什么樣的程度呢?
今天我就來和大家一起探究一下針對JDBC資料庫操作的一個輕量級框架—JdbcTemplate,教你一篇文掌握Spring JDBC框架的核心,

一、什么是JdbcTemplate?
Spring的JdbcTemplate可以被看作是一個小型的輕量級持久化層框架,為了使JDBC操作更加便捷,Spring在JDBC API上定義了一個抽象層,以此來建立了一個JDBC存取框架,
它作為Spring JDBC框架的核心,設計目的是為不同型別的JDBC操作提供模版方法,以至于通過這種方式,在盡可能保留靈活性的前提下,將資料庫存取的作業量降低到最低,
現在對于什么是jdbcTemplate你應該比較了解了吧?那么接下來我就來和大家詳細的聊一聊這個輕量級的框架是如何使用的,
二、JdbcTemplate框架搭建
使用JdbcTemplate進行資料庫的相關操作是需要提前搭建好相關環境配置的,那么我們就先來講一下如何在spring中配置JdbcTemplate,
1、匯入所需jar包
我們知道平常在進行框架的搭建的時候都是需要依賴相關的Jar包來實作的,那么JdbcTemplate又需要哪些jar包呢?我給大家按照作用羅列并整理了出來,
①IOC容器所需要的JAR包
- commons-logging-1.1.1.jar
- spring-beans-4.0.0.RELEASE.jar
- spring-context-4.0.0.RELEASE.jar
- spring-core-4.0.0.RELEASE.jar
- spring-expression-4.0.0.RELEASE.jar
②JdbcTemplate所需要的JAR包
- spring-jdbc-4.0.0.RELEASE.jar
- spring-orm-4.0.0.RELEASE.jar
- spring-tx-4.0.0.RELEASE.jar
③資料庫驅動和資料源
- c3p0-0.9.1.2.jar
- mysql-connector-java-5.1.7-bin.jar
以上這些jar包,包括SSM開發所需的所有jar包我給大家整理了出來,下載就能使用,
SSM框架Jar包下載
現在匯入了所有所依賴的jar包,接下來就是利用這些資源搭建接下來的JdbcTemplate框架了,
2、配置JDBC資料源
既然是對資料庫的操作,那么就一定是需要資料源的,我們以MySQL資料庫為例進行資料源的配置操作,關于在IOC中對bean的賦值我之前也和大家講過,所以我們可以直接在IOC容器中配置出資料源,連接到指定的資料庫,這里需要借助CombopooledDataSource類,并在其中給user、password、jdbcurl、driverclass等這幾個屬性賦值,同時我們配置上連接池中的最大連接數量和最小連接數量(當然這兩個屬性也是可以不用配置的),
在這里配置資料源對屬性的賦值其實也有兩種方式:
一種是直接將連接資訊在<bean></bean>標簽中寫死,
第二種是將資料源的連接資訊寫在單獨的一個檔案中,然后引入外部組態檔,這里我將兩種方法都介紹給大家:
(1)、直接在<bean></bean>中配置資料源
使用這種方法只需要直接在value中將屬性的值寫死就可以了,同時寫入資料源的id,代碼如下:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"/>
<property name="password" value="admin"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jdbc_template"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="20"/>
</bean>
(2)、引入外部組態檔
第二種方式是引入外部帶有資料源連接資訊的組態檔,然后利用引入外部組態檔的標簽將資料源資訊引入進來,再利用${}運算式將資料值賦值給屬性,使用這種方法的好處就是在資料源變更的時候方便更改變更資訊,直接在資料源的檔案中更新即可,不需要在IOC容器中更改代碼,
這種方法需要我們首先建立資料源資訊的組態檔,如jdbcconfig.properties,當然你還可以定義成其他名字,如“xxx.properties”,但是一般都要以“.properties”為檔案后綴,檔案中寫入資料源資訊:
jdbc.user=root
jdbc.password=ADMIN
jdbc.jdbcurl=jdbc:mysql://localhost:3306/jdbc_template
jdbc.driverClass=com.mysql.jdbc.Driver
在IOC容器中使用標簽context:property-placeholder引入外部組態檔“jdbcconfig.properties”,
<!-- 添加外部組態檔 -->
<context:property-placeholder location="classpath:jdbcconfig.properties"/>
注意:這里的class表示類路徑下的檔案,
之后按照同樣的方式在容器中<bean></bean>標簽下配置資料源,但是現在賦值是使用“${}”獲取到的jdbcconfig.properties中的配置資料,代碼如下:
<!-- 設定資料庫配置
在這里要注意:
$是用于讀取組態檔中的資訊
#是用于spring應用
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcurl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
</bean>
3、配置JdbcTemplate物件
在我們配置好資料源之后,就是配置JdbcTemplate物件了,由于JdbcTemplate物件只是一個JDBC的操作模版,因此它需要引入外部要操作的資料源,具體操作是在IOC中為JdbcTemplate類的dataSource屬性賦予資料源,
代碼如下:
<!-- 建立一個jdbcTemplate連接 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
直到這里,JdbcTemplate這個“輕量級”框架才算搭建配置完成了,接下來就能正常使用JdbcTemplate進行資料庫中的相關操作了,我們先來寫一個測驗陳述句分別測驗一下在普通連接和使用JdbcTemplate連接的情況下,資料庫連接是否正常:
public class JdbcTest {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
// 通過普通方法來獲取資料庫連接
@Test
public void test() throws SQLException {
System.out.println("jdbc_template執行");
DataSource bean = context.getBean(DataSource.class);
Connection connection = bean.getConnection();
System.out.println("普通方法來獲取資料庫連接:" + connection);
}
/**
* 通過jdbcTemplate來獲取資料庫連接
* 實驗:測驗資料源
* */
@Test
public void test01() {
System.out.println("jdbcTemplate來獲取資料庫連接:" + jdbcTemplate);
}
}
運行出現如下資訊,表示連接正常:

確認資料庫連接正常之后,現在才是到了JdbcTemplate使用的核心部分,敲黑板!到重點咯!!!

三、持久化層操作詳解
JdbcTemplate有專門的操作函式來實作不同的增刪改查操作,接下來我將通過如下資料表“員工表employee”來給大家介紹一下他們的具體使用:

1、增刪改操作
非常神奇的是,JdbcTemplate的增刪改操作是使用同一個方法來完成的,即:
JdbcTemplate.update(String, Object...)
該方法最常用的有兩個引數:
第一個引數String傳入需要執行的SQL陳述句,
第二個引數Object...傳入sql陳述句中需要帶的引數,使用object...的意思就是后面可能不止一個引數,該方法會有一個int型別的回傳值,表示有多少行資料被修改了,下面我通過一個實體來給大家演示一下;
例:將emp_id=5的記錄的salary欄位更新為1300.00
首先我們需要寫出相應的sql陳述句,陳述句中需要傳入引數的位置使用“?”表示,之后呼叫update方法來實作修改操作,并回傳被修改的行數:
/** 修改資料庫的資料表中的資料 * 將emp_id=5的記錄的salary欄位更新為1300.00*/ // @Test public void test02() { String sql = "UPDATE employee SET salary=? WHERE emp_id=?"; int update = jdbcTemplate.update(sql, 1300.00, 5); System.out.println("更新成功!" + update); }
以上是一個修改操作,對于洗掉和添加操作使用同樣的方式即可,
2、批量增刪改操作
上面是對于普通的單條資料的增刪改操作,但是如果有大量的資料需要執行同一個操作呢?一個一個的來豈不是太麻煩了嘛?所以針對這一情況JdbcTemplate還特意提供了批量的增刪改方法,方便我們對大量資料的操作,具體使用是這樣的,
通過呼叫以下函式來實作:
JdbcTemplate.batchUpdate(String, List<Object[]>)
該方法會回傳一個int型別的陣列,陣列中存放著每次執行sql陳述句所修改的行數,
其中的String仍然表示要執行的sql陳述句,
但是Object[]封裝了SQL陳述句每一次執行時所需要的引數,而在List集合封裝了SQL陳述句多次執行時的所有引數,
我們通過下面這個實體來驗證這一方法的操作:
例:向employee表中批量插入資料
首先需要將sql陳述句寫好,然后將需要傳遞的引數寫入到list集合中,之后再將sql陳述句和list集合傳入batchUpdate()方法即可,
/** * 批量插入資料 * */ @Test public void test03() { String sql = "INSERT INTO employee(emp_name,salary) VALUES(?,?)"; List<Object[]> batchArgs = new ArrayList<Object[]>(); batchArgs.add(new Object[]{"張三","999"}); batchArgs.add(new Object[]{"李四","1999"}); batchArgs.add(new Object[]{"王五","2999"}); int[] batchUpdate = jdbcTemplate.batchUpdate(sql, batchArgs); for (int i : batchUpdate) { System.out.println(i); } }
3、查詢單行資料
上面我們了解了在jdbcTemplate中如何進行增刪改操作,那么CRUD四兄弟怎么能少看查找這么重要的操作呢?這不它來了!!!

在jdbcTemplate中查詢資料其實是十分簡單的,但是他為什么不與其他三個操作共同使用同一個操作方法呢?
原因其實很簡單,還不就是增刪改操作會對資料表進行修改而回傳int型的修改行數,而查詢操作不會對資料表修改,同時回傳其他型別的查詢結果!
首先我們來看一下如何查詢單行資料,在jdbcTemplate中查詢單行資料所使用的函式是:
JdbcTemplate.queryForObject(String, RowMapper<Department>, Object...)
該方法的引數中String同樣的表示要執行查找的sql陳述句,
但是這里有一個坑要注意:中間傳遞的引數 RowMapper<Department>這個是什么呢?其實這里值的是要傳遞需要回傳的bean物件的型別,但是在進行真正的使用的時候我們并不是通過RowMapper<Department>來映射要回傳的bean物件的,而是通過它的子類BeanPropertyRowMapper,他們的繼承關心是這樣的:
在使用BeanPropertyRowMapper映射所回傳的bean物件時,能夠找到該物件并映射成功則回傳,如果找不到就報錯,
第三個引數object...還是表示傳入的查詢引數,
下面看這樣一個實體你就明白了,
例:查詢emp_id=5的資料庫記錄,封裝為一個Java物件回傳,
/** * 查詢資料庫中的單條資料 * 實驗4:查詢emp_id=5的資料庫記錄,封裝為一個Java物件回傳 * 創建的javabean中的欄位要和資料表中的欄位名一樣,否則就需要進行映射 * 查詢單條資料使用 queryForObject,但是中間需要使用BeanPropertyRowMapper映射需要生成的bean物件 * 在查找不到的時候會報錯 * * */ @Test public void test04() { String sql = "SELECT * FROM employee WHERE emp_id=?"; Employee employee = null; try { employee = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class),5); } catch (Exception e) { // TODO: handle exception } System.out.println(employee); }
4、查詢多行資料
與查詢單行資料不同,查詢多行資料需要使用的方法是:
JdbcTemplate.query(String, RowMapper<Department>, Object...)
但是其中所傳遞的引數是一樣的,唯一不同是該方法回傳的是一個陣列串列,其中包含了查詢到的每一條資料,
如下面這個實體:
例:查詢salary>4000的資料庫記錄,封裝為List集合回傳,
/** * 查詢資料庫中的多條資料 * 實驗5:查詢salary>4000的資料庫記錄,封裝為List集合回傳 * */ @Test public void test05() { String sql = "SELECT * FROM employee WHERE salary>?"; List<Employee> employees = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class),4000); for (Employee employee : employees) { System.out.println(employee); } }
5、查詢單一指定數值
現在我們知道了如何查詢單條資料,也知道了如何查詢多條資料,但是這些資料回傳的都是成行的資料,假如說我們只想得到某一行的資料呢?
那也好辦,jdbcTemplate有一個專門的方法用來回傳需要查詢單一數值,
JdbcTemplate.queryForObject(String, Class, Object...)
該方法中有一個回傳值是class,它表示要回傳的資料的型別,比如是int型別還是double型別,同時方法回傳查詢到的該數值,
如下面這里實體:
例:查詢employee表中最大的salary,
該方法很顯然是回傳一個具體的數值,而且還是沒有引數的,那么我們在進行引數的傳遞的時候就不需要傳遞后面的object...型別引數,
/** * 查詢資料表中的資料,但是只回傳一個數值 * 實驗6:查詢最大salary * */ @Test public void test06() { String sql = "SELECT MAX(salary) FROM employee"; Double quDouble = jdbcTemplate.queryForObject(sql, Double.class); System.out.println(quDouble); }
以上就是使用jdbcTemplate實作不同增刪改查操作的全部方法了,但是操作jdbcTemplate還有一種方式,就是將sql陳述句中的“?”用具體的引數來表示,接下來我們來介紹一下這種方式執行sql陳述句,
四、使用具名引數的JdbcTemplate
接下來要介紹的這個JdbcTemplate的操作方式與上面的有一點不太一樣,這里使用了一個具名引數來表示sql陳述句中需要傳入的引數,那么什么是具名引數呢?
具名引數:指具有名字的引數,引數不再是占位符,而是一個變數名
語法格式:“:引數名”
使用該具名引數之后,spring會自動的從傳入的引數中查找具有相應名稱的引數,并將它的值賦值給sql陳述句,
而Spring有一個支持具名引數功能的jdbcTemplate,即NamedParameterJdbcTemplate類,在在Spring中可以通過NamedParameterJdbcTemplate類的物件使用帶有具名引數的SQL陳述句,
1、宣告具名引數類
使用NamedParameterJdbcTemplate類的方式與普通的JdbcTemplate類似,都需要在ioc中宣告,如下所示:
<!-- 建立一個帶有具名引數支持的jdbcTemplate -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
2、具名引數的普通使用
我們以插入陳述句為例,來演示一下具名引數的使用,
傳統的sql陳述句是這樣的:
INSERT INTO employee(emp_name,salary) values(?,?)
使用具名引數的sql陳述句是這樣的;
INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)
如下面這個實體:
例:使用帶有具名引數的SQL陳述句插入一條員工記錄,并以Map形式傳入引數值,
/** * 實驗7:使用帶有具名引數的SQL陳述句插入一條員工記錄,并以Map形式傳入引數值 * 占位符查引數:?的順序千萬不能錯,傳參的時候一定要注意 * */ @Test public void test07() { String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)"; Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("emp_name", "趙六"); paramMap.put("salary", 998.12); int updateNum = jdbcTemplate2.update(sql, paramMap); System.out.println(updateNum); }
這里有一點需要注意的是:無論是使用普通的sql陳述句、還是使用帶具名引數的sql陳述句,傳入的引數的順序都需要和sql陳述句中引數的順序一致,否則就會出現引數呼叫錯誤,這一點一定需要注意!
3、通過SqlParameterSource物件傳入數值
通過SqlParameterSource物件傳入數值其實也就是需要將引數以javabean的形式傳入,但是又有了需要注意的地方,
注意:在使用sqlParmeterSource進行資料庫中資料裝填的時候,一定要注意values后面的引數名稱和bean中的引數名稱對應
否則就會報如下錯誤:
No value supplied for the SQL parameter 'emp_Name': Invalid property 'emp_Name' of bean class [com.spring.beans.Employee]: Bean property 'emp_Name' is not readable or has an invalid getter method:
下面以一個實體來說明通過SqlParameterSource物件傳入引數,
例:使用帶有具名引數的SQL陳述句插入一條員工記錄,通過SqlParameterSource物件傳入引數,
/** * 實驗8:重復實驗7,以SqlParameterSource形式傳入引數值 * */ @Test public void test08() { String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)"; Employee employee = new Employee(); employee.setEmp_name("吳九"); employee.setSalary(997.7); int updateNum = jdbcTemplate2.update(sql, new BeanPropertySqlParameterSource(employee)); System.out.println(updateNum); }
五、自動裝配JdbcTemplate并實作Dao
由于JdbcTemplate類是執行緒安全的,所以可以在IOC容器中宣告它的單個實體,并將這個實體注入到所有的Dao實體中,在Dao類中將JdbcTemplate實作自動裝配,并在其中實作增刪改查方法,通過自動裝配的jdbcTemplate可以在Dao中減少代碼的操作,更加輕松的實作增刪改查操作,
通過該方法自動裝配JdbcTemplate并實作Dao的步驟我給大家總結了出來:
- 建立dao類
- 書寫其中的方法
- 利用包掃描將其自動裝配
- 從IOC容器中獲取dao類
- 實作其中回應的資料庫操作的方法
下面通過實體進行驗證,
例:創建BookDao,自動裝配JdbcTemplate物件,并實作一個添加添加操作,
在Dao類中,我們使用@Autowired注解自動裝配jdbcTemplate,并實作一個資料添加的方法:
@Repository public class EmployeeDao { // 將jdbcTemplate自動注入 @Autowired JdbcTemplate jdbcTemplate; /** * 保存資料到資料表 * */ public int saveEmployee(Employee employee) { String sql = "insert into employee(emp_name,salary) values(?,?)"; return jdbcTemplate.update(sql, employee.getEmp_name(),employee.getSalary()); } }
使用測驗方法進行測驗:
/**
* 實驗9:創建BookDao,自動裝配JdbcTemplate物件
* */
@Test
public void test09() {
Employee employee = new Employee();
employee.setEmp_name("王八");
employee.setSalary(888.7);
int saveEmployeeNum = employeeDao.saveEmployee(employee);
System.out.println(saveEmployeeNum);
}
這樣通過自動裝配JdbcTemplate并實作Dao的作業就完成了,這種方式避免了重復的創建jdbcTemplate,而且減少了代碼量,
六、寫在最后
叮叮!到這里,Spring的JdbcTemplate框架全部的操作使用就跟大家講解完畢了,
其中包括從普通的JdbcTemplate搭建,到實作簡單的CURD、再到復雜的具名引數,希望小伙伴們通過這一篇文章就能掌握JdbcTemplate的使用教程,同時在學習程序中有遇到不理解或者不會的地方,歡迎留言提出,我們一起學習!
再先進的技術都需要一鍵一鍵的敲出來,奮斗吧!致奔波在Java道路上的每一位“創造者”!
我是灰小猿,我們下期見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/293592.html
標籤:java
下一篇:猜數字游戲 - Java版


