spring-JdbcTemplate學習總結
1、持久層總圖

spring 框架提供很多操作模板類
- 操作關系型資料:
- JdbcTemplate
- HibernateTemplate
- 操作 nosql 資料庫:
- RedisTemplate
- 操作訊息佇列:
- JmsTemplate
Mybatis 與 Spring-JdbcTemplate 的選擇
- 小型專案
- Spring-JdbcTemplate 的性能更好,更適合管理域的sql陳述句
- 大型專案
- mybatis可以將sql陳述句批量的管理起來,還可以達到sql的重用
- mybatis還做資料庫的驅動注冊加載,資料庫連接的創建與銷毀等資料庫的管理
- 可以讓開發人員更關注于業務,更適合在業務域使用
2、JdbcTemplate:概述
- spring 框架中提供的一個物件,是對原始 Jdbc API 物件的簡單封裝
- 導包:spring-jdbc-5.0.2.RELEASE.jar、spring-tx-5.0.2.RELEASE.jar(事務)
3、JdbcTemplate:作用
- 用于和資料庫進行互動,實作對資料庫表的 CRUD操作
4、JdbcTemplate:物件
- 創建 spring16_JdbcTemplate 的工程,演示 JdbcTemplate物件的創建和使用
1. 撰寫 賬戶物體類
- 對應 spring_test 資料庫中的 account賬戶表創建賬戶物體類,并實作序列化介面
// 賬戶的物體類
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
public Account() {
}
public Account(Integer id, String name, Float money) {
this.id = id;
this.name = name;
this.money = money;
}
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 Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
2. 撰寫 Pom.xml 檔案
- 匯入 spring-context、spring-jdbc、spring-tx、mysql 的依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.idea.spring</groupId>
<artifactId>spring16_JdbcTemplate</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.8</version>
</dependency>
</dependencies>
</project>
3. 撰寫 JdbcTemplate類
-
資料源的選擇與配置:
-
使用 spring的內置資料源:DriverManagerDataSource 類
-
配置 C3P0 資料源:
- 匯入 c3p0 的 Jar包
- 組態檔中配置資料源:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> -
配置 DBCP 資料源:
- 匯入 dbcp 的 Jar包
- 組態檔中配置資料源:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean>
-
-
撰寫 JdbcTemplate1 類:
// JdbcTemplate的最基本用法
public class JdbcTemplateDemo1 {
public static void main(String[] args){
// 準備資料源:spring的內置資料源
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_test");
ds.setUsername("root");
ds.setPassword("123456");
//1.創建JdbcTemplate物件
JdbcTemplate jt = new JdbcTemplate();
// 給jt設定資料源
jt.setDataSource(ds);
//2.執行操作
jt.execute("insert into account(name,money) values('ccc',1000)");
}
}
=================================================================
運行結果: 插入賬戶 ccc 成功
4. 發現、解決問題
-
問題:
- 資料源的設定被固定,并且是以 Set 方法設定資料源的基本資訊
- JdbcTemplate 物件是以 建構式 創建
-
解決方式:
-
可以在 Spring框架的 IOC組態檔中直接配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置資料源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> </beans> -
引入外部組態檔
配置屬性檔案 jdbc.properties:
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring_test jdbc.username=root jdbc.password=123456方式一:
<bean> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties"/> </bean>方式二:
<context:property-placeholder location="classpath:jdbc.properties"/> -
-
運行 JdbcTemplateDemo2 類:
// JdbcTemplate的最基本用法
public class JdbcTemplateDemo2 {
public static void main(String[] args){
//1.獲取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.獲取物件
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執行操作
jt.execute("insert into account(name,money) values('ddd',2000)");
}
}
- 運行結果:插入賬戶 ddd 成功
- 用組態檔的方式:創建 JdbcTemplate 物件并呼叫 execute ( ) 方法,避免資料源資訊固定的弊端
5、JdbcTemplate:CRUD
- 創建 JdbcTemplateDemo3 類,測驗 JdbcTemplate物件的 CRUD操作
1. 獲取容器和物件
//1.獲取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.獲取物件
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
2. 保存
- 呼叫 update ( Insert 陳述句、引數 ) 方法
jt.update("insert into account(name,money) values(?,?)","eee",3333f);
3. 更新
- 呼叫 update ( update 陳述句、引數 ) 方法
jt.update("update account set name = ? , money = ? where id = ?","test",4567f,10);
3. 洗掉
- 呼叫 update ( delete 陳述句、引數 ) 方法
jt.update("delete from account where id = ? ",8);
4. 查詢所有

① 方式一:
- 手動創建 AccountRomMapper 類繼承 RowMapper
// 定義 Account 的封裝策略
class AccountRomMapper implements RowMapper<Account>{
@Override
// 把結果集中的資料封裝到Account中,然后由spring把每個Account加到集合中
public Account mapRow(ResultSet resultSet, int i) throws SQLException {
Account account = new Account();
account.setId(resultSet.getInt("id"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getFloat("money"));
return account;
}
}
- 呼叫 query( 查詢陳述句、new RowMapper ( )、引數)方法
List<Account> accounts = jt.query("select * from account where money > ? ",new AccountRomMapper(),1000f);
for (Account account : accounts) {
System.out.println(account);
}
② 方式二:
- Spring框架提供的 BeanPropertyRowMapper< 封裝型別 >( .class位元組碼 )
- 呼叫 query(查詢陳述句、new BeanPropertyRowMapper<>()、引數)方法
List<Account> accounts = jt.query("select * from account where money > ? ",new BeanPropertyRowMapper<Account>(Account.class),1000f);
for(Account account : accounts) {
System.out.println(account);
}
5. 與 QueryRunner 區別
- QueryRunner 的 query ( ) 方法回傳的結果只有一個泛型
- Spring-JdbcTemplate 的 query ( ) 方法回傳的結果可以是泛型、集合等

6. 查詢一個
- 查詢單個記錄時,與查詢多條記錄時呼叫方法相同
- 呼叫 query ( 查詢陳述句+條件、new BeanPropertyRowMapper<>(),引數 )
- 也存在專門查詢單條記錄的方法,只不過使用較少
List<Account> accounts = jt.query("select * from account where id = ? ",new BeanPropertyRowMapper<Account>(Account.class),1);
System.out.println(accounts.isEmpty()?"沒有內容":accounts.get(0));
7. 查詢回傳一行一列
- 呼叫 queryForObject(查詢陳述句、結果型別、引數)方法
Long count = jt.queryForObject("select count(*) from account where money > ?", Long.class, 1000f);
System.out.println(count);
- 問題:spring-jdbc版本過新,無法查詢到結果,會報例外
- 解決:將 spring-jdbc 的 Jar包版本選用低版本的,即可查詢成功
6、JdbcTemplate:Dao 使用
- 創建 jdbcTemplateDemo4 類,演示 JdbcTemplate 在 Dao持久層的使用
1. 撰寫 賬戶持久層
- 撰寫 賬戶持久層介面 AccountDao
// 賬戶的持久層介面
public interface AccountDao {
// 根據Id查詢賬戶
Account findAccountById(Integer accountId);
// 根據名稱查詢賬戶
Account findAccountByName(String accountName);
// 更新賬戶
void updateAccount(Account account);
}
- 撰寫 賬戶持久層介面實作類 AccountDaoImpl
// 賬戶的持久層實作類
public class AccountDaoImpl implements AccountDao {
private JdbcTemplate jdbcTemplate;
// Set方法等待spring注入
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId);
return accounts.isEmpty()?null:accounts.get(0);
}
@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName);
if(accounts.isEmpty()){
return null;
}else if(accounts.size()>1){
throw new RuntimeException("結果集不唯一");
}else {
return accounts.get(0);
}
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
}
}
2. 方法測驗
- 在 JdbcTemplateDemo4 類中,對 Dao層方法進行測驗
// JdbcTemplate的CRUD操作
public class JdbcTemplateDemo4 {
public static void main(String[] args){
//1.獲取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.獲取 accountDao物件
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
//3.執行方法
Account account1 = accountDao.findAccountById(1);
System.out.println(account1);
Account account2 = accountDao.findAccountByName("ccc");
System.out.println(account2);
account2.setMoney(9999f);
accountDao.updateAccount(account2);
}
}
3. 發現問題
- 問題:Dao類有很多,每個Dao介面實作類中,都存在重復代碼
private JdbcTemplate jdbcTemplate;
// Set方法等待spring注入
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
-
解決:
- 每個Dao介面實作類繼承 spring框架提供的 JdbcDaoSupport 類
import org.springframework.jdbc.core.support.JdbcDaoSupport;
4. 解決問題
-
使用情況不同:
-
當使用 注解配置時,不繼承 JdbcDaoSupport 類,使用注解等待 spring框架自動依賴注入
// 賬戶的持久層實作類 // 演示基于注解配置時,不需要繼承 JdbcDaoSupport類,直接使用注解配置等待注入即可 @Repository public class AccountDaoImpl2 implements AccountDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public Account findAccountById(Integer accountId) { List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId); return accounts.isEmpty()?null:accounts.get(0); } @Override public Account findAccountByName(String accountName) { List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName); if(accounts.isEmpty()){ return null; }else if(accounts.size()>1){ throw new RuntimeException("結果集不唯一"); }else { return accounts.get(0); } } @Override public void updateAccount(Account account) { jdbcTemplate.update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId()); } } -
當使用 XML配置時,繼承 spring框架提供的 JdbcDaoSupport 類
- 修改 bean.xml 檔案中,向 AccountDaoImpl1 類中注入 dataSource 資料源即可
<bean id="accountDao" class="dao.Impl.AccountDaoImpl1"> <property name="dataSource" ref="dataSource"></property> </bean>// 賬戶的持久層實作類 // 演示繼承 spring框架提供的 JdbcDaoSupport 類 public class AccountDaoImpl1 extends JdbcDaoSupport implements AccountDao { @Override public Account findAccountById(Integer accountId) { List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId); return accounts.isEmpty()?null:accounts.get(0); } @Override public Account findAccountByName(String accountName) { List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName); if(accounts.isEmpty()){ return null; }else if(accounts.size()>1){ throw new RuntimeException("結果集不唯一"); }else { return accounts.get(0); } } @Override public void updateAccount(Account account) { super.getJdbcTemplate().update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId()); } }
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/94463.html
標籤:其他
上一篇:CTF-i春秋-Web-Zone
