JdbcTemplate-01
看一個實際需求:
如果希望使用spring框架做專案,Spring框架如何處理對資料庫的操作呢?
-
方案一:使用之前的JdbcUtils類
-
方案二:spring提供了一個操作資料庫(表)的功能強大的類JdbcTemplate,我們可以通過ioc容器來配置一個JdbcTemplate物件,使用它來完成對資料庫表的各種操作,
1.基本介紹
JdbcTemplate APIs:下載的檔案-spring-5.3.8-dist\spring-framework-5.3.8\docs\javadoc-api\index.html
- 通過Spring可以配置資料源,從而完成對資料表的操作
- JdbcTemplate 是 spring 提供的訪問資料庫的技術,可以將 JDBC 的常用操作封裝為模板方法,
2.使用實體
需求說明:使用 Spring 的方式來完成 JdbcTemplate 配置和使用
一、搭建環境:
-
引入JdbcTemplate 需要的jar包(Spring5)
-
創建資料庫spring和表monster
-- 創建資料庫
CREATE DATABASE spring;
USE spring;
-- 創建表monster
CREATE TABLE monster(
id INT PRIMARY KEY,
`name` VARCHAR(64) NOT NULL DEFAULT '',
skill VARCHAR(64) NOT NULL DEFAULT ''
)CHARSET=utf8;
INSERT INTO monster VALUES(100,'青牛怪','吐火');
INSERT INTO monster VALUES(200,'黃袍怪','吐煙');
INSERT INTO monster VALUES(300,'蜘蛛怪','吐絲');
二、配置DataSource
- 創建組態檔src/jdbc.properties(key值隨意)
在spring的ioc容器中,可以通過屬性檔案給bean注入值
jdbc.user=root
jdbc.pwd=123456
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
- 創建容器組態檔src/JdbcTemplate_ioc.xml
<!--引入外部的屬性檔案-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置資料源物件-DataSource-->
<bean id="dataSource">
<!--給資料源物件配置屬性值-->
<property name="user" value="https://www.cnblogs.com/liyuelian/archive/2023/01/30/${jdbc.user}"/>
<property name="password" value="https://www.cnblogs.com/liyuelian/archive/2023/01/30/${jdbc.pwd}"/>
<property name="driverClass" value="https://www.cnblogs.com/liyuelian/archive/2023/01/30/${jdbc.driver}"/>
<property name="jdbcUrl" value="https://www.cnblogs.com/liyuelian/archive/2023/01/30/${jdbc.url}"/>
</bean>
- 測驗連接
@Test
public void testDatasourceByJdbcTemplate() throws SQLException {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//因為 ComboPooledDataSource實作了 DataSource介面,這里使用介面型別來獲取物件
DataSource dataSource = ioc.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println("獲取到連接connection=" + connection);
connection.close();
}
成功連接:
- 配置 JdbcTemplate_ioc.xml,將資料源分配給 JdbcTemplate bean物件
<!--配置JdbcTemplate物件-->
<bean id="jdbcTemplate">
<!--給JdbcTemplate物件配置DataSource屬性-->
<property name="dataSource" ref="dataSource"/>
</bean>
2.1添加資料
@Test
public void addDataByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//1.添加方式
String sql = "insert into monster values(400,'紅孩兒','風火輪')";
jdbcTemplate.execute(sql);
//2.添加方式 2(推薦)
String sql2 = "insert into monster values(?,?,?)";
//回傳的 int型別 表示執行后表受影響的記錄數
int affected = jdbcTemplate.update(sql2, 500, "牛魔王", "芭蕉扇");
System.out.println("add ok affected = " + affected);
}
添加成功:

2.2修改資料
//測驗通過JdbcTemplate物件完成修改資料
@Test
public void updateDataByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
String sql = "update monster set skill=? where id=?";
int affected = jdbcTemplate.update(sql, "美人計", 300);
System.out.println("update is ok, affected = " + affected);
}
修改成功:

2.3批量處理
對于某個類,如果有很多API,使用的步驟:
1.先確定API名字 2.根據API提供的引數,組織引數 3.根據API可以推測類似的用法和功能
//批量添加兩個 monster
@Test
public void addBatchDataByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//1.準備引數
String sql = "insert into monster values(?,?,?)";
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(new Object[]{600, "白蛇", "翻江倒海"});
batchArgs.add(new Object[]{700, "青蛇", "竹葉青"});
//2.呼叫
//int[] batchUpdate(String sql, List<Object[]> batchArgs);
//說明:回傳結果為int陣列,每個元素對應上面的sql陳述句對表的影響記錄數
int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
//輸出
for (int anInt : ints) {
System.out.println("anInt=" + anInt);
}
System.out.println("batch add is ok..");
}
批處理結果:

2.4查詢
物體類 Monster.java
package com.li.bean;
/**
* @author 李
* @version 1.0
* Javabean / Entity
*/
public class Monster {
private Integer monsterId;
private String name;
private String skill;
//無參構造器一定要有,spring底層反射創建物件時需要使用
public Monster() {
}
//全參構造器
public Monster(Integer monsterId, String name, String skill) {
this.monsterId = monsterId;
this.name = name;
this.skill = skill;
}
public Integer getMonsterId() {
return monsterId;
}
public void setMonsterId(Integer monsterId) {
this.monsterId = monsterId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Monster{" +
"monsterId=" + monsterId +
", name='" + name + '\'' +
", skill='" + skill + '\'' +
'}';
}
}
2.4.1查詢單行多列
查詢 id=500 的 monster 并封裝到 Monster 物體物件
//查詢 id=100的 monster并封裝到 Monster物體物件
@Test
public void selectDataByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//1.確定API
//<T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
//2.準備引數
//注意:封裝物件時,如果查詢回傳的欄位名和物體物件的屬性名不一致會出現問題,最好使用別名!
String sql = "SELECT id AS monsterId , NAME, skill FROM monster WHERE id=?";
//使用RowMapper介面來對回傳的資料,進行一個封裝(底層是反射->setter)
RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
//3.呼叫
Monster monster = jdbcTemplate.queryForObject(sql, rowMapper, 500);
System.out.println("monster=" + monster);
}
查詢結果:
2.4.2查詢多行多列
查詢 id>=200 的 monster,并封裝到 Monster 物體物件
//查詢 id>=200的 monster并封裝到 Monster物體物件
@Test
public void selectMulDataByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//1.確定API
//public <T> T query(String sql, ResultSetExtractor<T> rse, @Nullable Object... args)
//2.組織引數
String sql = "SELECT id AS monsterId , NAME, skill FROM monster WHERE id>= ?";
BeanPropertyRowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
List<Monster> query = jdbcTemplate.query(sql, rowMapper, 200);
for (Monster monster : query) {
System.out.println("monster=" + monster);
}
}
查詢結果:
2.4.3查詢單行單列
查詢回傳結果只有單行單列的值,比如查詢表中的總記錄數,或者查詢 id=200 的 name 欄位的值
//查詢 id>=200的 monster并封裝到 Monster物體物件
@Test
public void selectScalarByJdbcTemplate() {
//獲取容器
ApplicationContext ioc =
new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
//獲取JdbcTemplate物件
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//1.確定API
// public <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)
//requiredType 表示回傳的單行單列的 值的 資料型別
//2.組織引數
String sql = "SELECT NAME FROM monster WHERE id=?";
String sql2 = "SELECT COUNT(*) FROM monster";
//3.呼叫
String name = jdbcTemplate.queryForObject(sql, String.class, 200);
Integer count = jdbcTemplate.queryForObject(sql2, Integer.class);
System.out.println("id=200 的 name = " + name);
System.out.println("monster表的總記錄數 = " + count);
}
查詢結果:
2.5具名引數
-
在 JDBC用法中,SQL引數是用占位符
?表示,并且受到位置的限制,定位引數的問題在于,一旦引數的位置發生變化,必須改變引數的系結,在Spring JDBC中,系結SQL引數的另一種選擇是使用具名引數 (named parameter),SQL具名引數是按照名稱系結,而不是位置系結,
-
什么是具名引數?
具名引數:SQL 按名稱(以冒號開頭)而不是按位置進行指定,具名引數更易于維護, 也提升了可讀性,具名引數由框架類在運行時用占位符取代,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/542585.html
標籤:其他
上一篇:rust寫一個im聊天服務
下一篇:JVM是如何解決跨代參考問題的?
