day14-JdbcTemplate-01

来源:https://www.cnblogs.com/liyuelian/archive/2023/01/30/17077343.html
-Advertisement-
Play Games

JdbcTemplate-01 看一個實際需求: 如果希望使用spring框架做項目,Spring框架如何處理對資料庫的操作呢? 方案一:使用之前的JdbcUtils類 方案二:spring提供了一個操作資料庫(表)的功能強大的類JdbcTemplate。我們可以通過ioc容器來配置一個JdbcTe ...


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

  1. 通過Spring可以配置數據源,從而完成對數據表的操作
  2. JdbcTemplate 是 spring 提供的訪問資料庫的技術。可以將 JDBC 的常用操作封裝為模板方法。
image-20230130183802247

2.使用實例

需求說明:使用 Spring 的方式來完成 JdbcTemplate 配置和使用

一、搭建環境:

  1. 引入JdbcTemplate 需要的jar包(Spring5)

    image-20230130182521048
  2. 創建資料庫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,'蜘蛛怪','吐絲');
image-20230130184434097

二、配置DataSource

  1. 創建配置文件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
  1. 創建容器配置文件src/JdbcTemplate_ioc.xml
<!--引入外部的屬性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置數據源對象-DataSource-->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
    <!--給數據源對象配置屬性值-->
    <property name="user" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.pwd}"/>
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
</bean>
  1. 測試連接
@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();
}

成功連接:

image-20230130194736188
  1. 配置 JdbcTemplate_ioc.xml,將數據源分配給 JdbcTemplate bean對象
<!--配置JdbcTemplate對象-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" 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);
}

添加成功:

image-20230130200640803 image-20230130201116969

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);
}

修改成功:

image-20230130201656523 image-20230130201723618

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..");
}

批處理結果:

image-20230130203736793 image-20230130203812283

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);
}

查詢結果:

image-20230130210708174

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);
    }
}

查詢結果:

image-20230130211933967

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);
}

查詢結果:

image-20230130213520356

2.5具名參數

  • 在 JDBC用法中,SQL參數是用占位符 ? 表示,並且受到位置的限制。

    定位參數的問題在於,一旦參數的位置發生變化,必須改變參數的綁定,在Spring JDBC中,綁定SQL參數的另一種選擇是使用具名參數 (named parameter),SQL具名參數是按照名稱綁定,而不是位置綁定。

  • 什麼是具名參數?

    具名參數:SQL 按名稱(以冒號開頭)而不是按位置進行指定。具名參數更易於維護, 也提升了可讀性。具名參數由框架類在運行時用占位符取代。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 後端應用分層是什麼,例如:你用Spring MVC開發web程式、項目用三層架構分包,這些都用了分層思想。 MVC模式包含了三部分: 視圖(view):負責界面顯示、處理用戶交互。如:前端應用 控制器(controller):協調視圖層與模型層之間的相互工作。控制器接收視圖層發來的請求,決定用那些模 ...
  • 設計原則 23種設計模式滿足並實現了設計原則中的一個或者多個,從而達到了代碼復用、增加可維護性的目的。 開閉原則(Open+Closed+Principle,OCP) 里氏代換原則(Liskov+Substitution+Principle,LSP) 依賴倒轉原則(Dependency+Invers ...
  • CQRS只是一種非常簡單的模式(pattern),CQRS本身並不是一種架構風格,和最終一致性/消息/讀寫分離/事件溯源/DDD等沒有必然的聯繫,它最大優勢是給我們帶來更多的架構屬性選擇 ...
  • 什麼是RabbitMQ? RabbitMQ是一款開源的,Erlang編寫的,基於AMQP協議的消息中間件 為什麼使用MQ?MQ的優點 非同步處理 - 相比於傳統的串列、並行方式,提高了系統的吞吐量。 應用解耦 - 系統間通過消息通信,不用關心其他系統的處理。 流量削鋒 - 可以通過消息隊列長度控制請求 ...
  • 洛谷oj題單【入門1】順序結構-入門難度(Java) 來源:https://www.luogu.com.cn/training/100#problems B2002 Hello,World! public class Main { public static void main(String[] a ...
  • 簡介 Quarkus是類似於Spring Boot的框架,可以方便大家進行Java開發。利用GraalVM的魔力,能更好的適應雲原生的場景,極快的啟動速度。 創建項目 在IDEA就直接有創建Quarkus項目的初始化工具,直接根據自己需要填好即可,非常方便: 選擇自己需要的一些組件和依賴,我這裡只選 ...
  • 創建項目 1.先創建空項目Empty project 2.再創建模板Module 3.設置項目結構 4.創建Java class 5.創建包 一、註釋 註釋顏色設置 Java中的註釋有三種: 1.單行註釋 //(雙斜杠開頭) 2.多行註釋 /* 註釋*/ 3.文檔註釋 /** * */ 二、標識符和 ...
  • 本文已收錄至Github,推薦閱讀 👉 Java隨想錄 微信公眾號:Java隨想錄 CSDN: 碼農BookSea 不知道自己的無知,乃是雙倍的無知。——柏拉圖 跨代引用問題 跨代引用是指新生代中存在對老年代對象的引用,或者老年代中存在對新生代的引用。 假如要現在進行一次只局限於新生代區域內的收集 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...