Spring中如何操作JDBC的實(shí)現(xiàn)
本篇文章介紹一下在Spring中如何使用JDBC,事實(shí)上,在Spring中使用JDBC和傳統(tǒng)的JDBC或者一些JDBC框架,如:DBUtils的使用沒(méi)有什么區(qū)別,所以Spring中使用JDBC是非常簡(jiǎn)單的。
獲取數(shù)據(jù)庫(kù)連接
在這之前,我們首先通過(guò)Spring獲得對(duì)數(shù)據(jù)庫(kù)的連接,創(chuàng)建一個(gè)Java項(xiàng)目,導(dǎo)入Spring、c3p0、數(shù)據(jù)庫(kù)驅(qū)動(dòng)的jar包即可,然后創(chuàng)建一個(gè)數(shù)據(jù)表做測(cè)試:
create table user( id integer primary key auto_increment, name varchar(20), password varchar(20) );
接下來(lái)創(chuàng)建Spring的配置文件并作如下配置:
<?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-4.0.xsd">
<!-- 導(dǎo)入資源文件 -->
<context:property-placeholder
location="classpath:db.properties" />
<!-- 配置C3P0數(shù)據(jù)源 -->
<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>
</beans>
測(cè)試數(shù)據(jù)庫(kù)連接是否能夠成功獲?。?/p>
public class SpringJDBCTest {
private ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testConnection() throws SQLException {
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource.getConnection());
}
}
運(yùn)行結(jié)果:
com.mchange.v2.c3p0.impl.NewProxyConnection@5d47c63f
能夠成功獲取到數(shù)據(jù)庫(kù)連接。
對(duì)數(shù)據(jù)表進(jìn)行更新操作
傳統(tǒng)的JDBC用法相信大家都很熟悉,在Spring中并沒(méi)有什么特別的,無(wú)非是將Bean的生命周期交給了IOC容器管理,而Spring框架獨(dú)立出了一套API用于數(shù)據(jù)庫(kù)操作(JDBCTemplate)。接下來(lái)分別測(cè)試一下常見(jiàn)的數(shù)據(jù)庫(kù)操作,先將JDBCTemplate類(lèi)放入容器:
<!-- 將JDBCTemplate放入容器 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
該類(lèi)需要一個(gè)參數(shù),參數(shù)值指向剛才配置的dataSource即可,這樣我們就能夠使用JDBCTemplate類(lèi)了,先測(cè)試一下插入操作:
@Test
public void testInsert() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "insert into user(name,password) values(?,?)";
Object[] args = {"zhangsan","12345"};
jdbcTemplate.update(sql,args);
}
執(zhí)行代碼,查詢(xún)表結(jié)果,插入成功。
mysql> select * from user; +----+----------+----------+ | id | name | password | +----+----------+----------+ | 1 | zhangsan | 12345 | +----+----------+----------+ 1 row in set (0.00 sec)
接著測(cè)試一下數(shù)據(jù)表的修改操作:
@Test
public void testUpdate() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "update user set password = ? where id = ?";
Object[] args = {"admin","1"};
jdbcTemplate.update(sql,args);
}
執(zhí)行代碼,查詢(xún)表結(jié)果,修改成功。
mysql> select * from user; +----+----------+----------+ | id | name | password | +----+----------+----------+ | 1 | zhangsan | admin | +----+----------+----------+ 1 row in set (0.00 sec)
數(shù)據(jù)表的刪除操作與其類(lèi)似,不做重復(fù)測(cè)試,接下來(lái)我們測(cè)試一下批量操作:
@Test
public void testBatchInsert() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "insert into user(name,password) values(?,?)";
List<Object[]> batchArgs = new ArrayList();
batchArgs.add(new Object[]{"lisi","123"});
batchArgs.add(new Object[]{"wangwu","1234"});
batchArgs.add(new Object[]{"zhaoliu","12345"});
jdbcTemplate.batchUpdate(sql, batchArgs);
}
此時(shí)的一個(gè)對(duì)象數(shù)組即為一條記錄,批量操作則需要泛型為Object數(shù)組的集合。
執(zhí)行代碼,查詢(xún)表結(jié)果,批量插入成功。
mysql> select * from user; +----+----------+----------+ | id | name | password | +----+----------+----------+ | 1 | zhangsan | admin | | 2 | lisi | 123 | | 3 | wangwu | 1234 | | 4 | zhaoliu | 12345 | +----+----------+----------+ 4 rows in set (0.00 sec)
最后是數(shù)據(jù)表的查詢(xún)操作,首先創(chuàng)建數(shù)據(jù)表對(duì)應(yīng)的User類(lèi):
package com.wwj.spring.jdbc;
public class User {
private Integer id;
private String name;
private String password;
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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
}
}
編寫(xiě)測(cè)試代碼:
@Test
public void testGet() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "select id,name,password from user where id = ?";
RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class);
User user = jdbcTemplate.queryForObject(sql, rowMapper,1);
System.out.println(user);
}
運(yùn)行結(jié)果如下:
User [id=1, name=zhangsan, password=admin]
在Spring中,查詢(xún)的結(jié)果是交給了RowMapper來(lái)處理的,RowMapper用來(lái)指定映射結(jié)果集行數(shù)據(jù)的方式,相對(duì)于傳統(tǒng)的ResultSet來(lái)說(shuō),RowMapper省去了遍歷結(jié)果集的重復(fù)操作,從而使查詢(xún)變得更簡(jiǎn)單。
而查詢(xún)多條數(shù)據(jù)的方式如下:
@Test
public void testGetMore() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "select id,name,password from user where id > ?";
RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
List<User> userList = jdbcTemplate.query(sql, rowMapper,2);
System.out.println(userList);
}
運(yùn)行結(jié)果:
[User [id=3, name=wangwu, password=1234], User [id=4, name=zhaoliu, password=12345]]
有些同學(xué)可能會(huì)想當(dāng)然地認(rèn)為,查詢(xún)多條數(shù)據(jù)要調(diào)用queryForList()方法,事實(shí)上,調(diào)用的是query()方法。需要注意的是,JDBCTemplate提供的API不支持級(jí)聯(lián)屬性。
獲取數(shù)據(jù)表單列的值:
@Test
public void testSingleValue() {
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
String sql = "select name from user where id = ?";
String name = jdbcTemplate.queryForObject(sql, String.class,1);
System.out.println(name);
}
運(yùn)行結(jié)果如下:
zhangsan
整個(gè)增刪改查的過(guò)程其實(shí)都沒(méi)有任何難度,這和之前學(xué)的數(shù)據(jù)庫(kù)操作API區(qū)別并不大,所以也沒(méi)有特別需要講解的地方,通過(guò)一些測(cè)試代碼應(yīng)該就能夠理解了。
使用具名參數(shù)
在經(jīng)典的JDBC用法中,sql參數(shù)是用占位符"?"表示,并且受到位置的限制,定位參數(shù)的問(wèn)題在于,一旦改變參數(shù)的順序,就必須改變參數(shù)的綁定方式。
為了解決這個(gè)問(wèn)題,Spring為我們提供了另一種選擇:使用具名參數(shù)。
使用具名參數(shù)后,sql將按名稱(chēng)而不是位置進(jìn)行指定,具名參數(shù)更易于后期維護(hù),也提升了代碼的可讀性,具名參數(shù)只在NamedParameterJdbcTemplate類(lèi)中得到支持。
要想使用具名參數(shù),首先將NamedParameterJdbcTemplate放入容器:
<!-- 將namedParameterJdbcTemplate放入容器 --> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> <constructor-arg ref="dataSource"></constructor-arg> </bean>
該類(lèi)沒(méi)有無(wú)參的構(gòu)造器,通常使用參數(shù)為DataSource類(lèi)型的構(gòu)造器。
這里以插入數(shù)據(jù)舉例具名參數(shù)的使用:
@Test
public void testNamedParameterJdbcTemplate() {
NamedParameterJdbcTemplate namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
String sql = "insert into user(name,password) values(:name,:psd)";
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "wangweijun");
map.put("psd", "112233");
namedParameterJdbcTemplate.update(sql,map);
}
執(zhí)行代碼,查詢(xún)表結(jié)果,插入成功。
mysql> select * from user; +----+------------+----------+ | id | name | password | +----+------------+----------+ | 1 | zhangsan | admin | | 2 | lisi | 123 | | 3 | wangwu | 1234 | | 4 | zhaoliu | 12345 | | 5 | wangweijun | 112233 | +----+------------+----------+ 5 rows in set (0.00 sec)
雖然具名參數(shù)有很多好處,但無(wú)形中也增加了很多代碼,可以說(shuō)比之前的方式更加復(fù)雜。
當(dāng)然,它還有更簡(jiǎn)單的實(shí)現(xiàn)方式:
@Test
public void testSimpleNamedParameterJdbcTemplate() {
NamedParameterJdbcTemplate namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
String sql = "insert into user(name,password) values(:name,:password)";
User user = new User();
user.setName("zhaoliu");
user.setPassword("223344");
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);
namedParameterJdbcTemplate.update(sql, paramSource);
}
執(zhí)行代碼,查詢(xún)表結(jié)果,插入成功。
mysql> select * from user; +----+------------+----------+ | id | name | password | +----+------------+----------+ | 1 | zhangsan | admin | | 2 | lisi | 123 | | 3 | wangwu | 1234 | | 4 | zhaoliu | 12345 | | 5 | wangweijun | 112233 | | 6 | zhaoliu | 223344 | +----+------------+----------+ 6 rows in set (0.00 sec)
這種方式實(shí)現(xiàn)了通過(guò)對(duì)象自動(dòng)匹配具名參數(shù),前提是具名參數(shù)的參數(shù)名要和類(lèi)中的屬性名相同,該方式相對(duì)于第一種方式要更合理一些,因?yàn)閺那芭_(tái)傳遞過(guò)來(lái)的就是對(duì)象,這樣就可以直接通過(guò)對(duì)象進(jìn)行處理而無(wú)需其它操作。
項(xiàng)目源碼
https://github.com/blizzawang/spring_jdbc
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java異常處理運(yùn)行時(shí)異常(RuntimeException)詳解及實(shí)例
這篇文章主要介紹了 Java異常處理運(yùn)行時(shí)異常(RuntimeException)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下http://time.qq.com/?pgv_ref=aiotime2017-05-05
基于java集合中的一些易混淆的知識(shí)點(diǎn)(詳解)
下面小編就為大家?guī)?lái)一篇基于java集合中的一些易混淆的知識(shí)點(diǎn)(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實(shí)現(xiàn)
這篇文章主要介紹了IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Springboot錯(cuò)誤頁(yè)面和錯(cuò)誤信息定制操作
這篇文章主要介紹了Springboot錯(cuò)誤頁(yè)面和錯(cuò)誤信息定制操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Spring Boot中進(jìn)行 文件上傳和 文件下載功能實(shí)現(xiàn)
開(kāi)發(fā)Wb應(yīng)用時(shí),文件上傳是很常見(jiàn)的一個(gè)需求,瀏覽器 通過(guò) 表單形式 將 文件 以 流的形式傳遞 給 服務(wù)器,服務(wù)器再對(duì)上傳的數(shù)據(jù)解析處理,下面將通過(guò)一個(gè)案例講解使用 SpringBoot 實(shí)現(xiàn) 文件上傳,感興趣的朋友一起看看吧2024-07-07
Java foreach循環(huán)是否可以修改數(shù)據(jù)的值問(wèn)題解決方法
最近在做項(xiàng)目的時(shí)候,需要修改一個(gè)數(shù)組里面各個(gè)元素的值,foreach循環(huán)迭代數(shù)組元素時(shí),不能改變數(shù)組元素的值,這篇文章給大家介紹Java foreach循環(huán)是否可以修改數(shù)據(jù)的值的問(wèn)題及解決方法,感興趣的朋友一起看看吧2024-02-02

