欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你學(xué)會(huì)Spring?JDBC的使用

 更新時(shí)間:2022年09月15日 15:00:05   作者:look-word  
JDBC?就是?數(shù)據(jù)庫(kù)開(kāi)發(fā)?操作的?代名詞,因?yàn)橹灰乾F(xiàn)代商業(yè)項(xiàng)目的開(kāi)發(fā)那么一定是離不開(kāi)?數(shù)據(jù)庫(kù)?的,不管你搞的是什么,只要是想使用動(dòng)態(tài)的開(kāi)發(fā)結(jié)構(gòu),那么一定就是?JDBC?,那么下面來(lái)教教大家傳統(tǒng)JDBC的使用

1、JDBC

JDBC 就是 數(shù)據(jù)庫(kù)開(kāi)發(fā) 操作的 代名詞,因?yàn)橹灰乾F(xiàn)代商業(yè)項(xiàng)目的開(kāi)發(fā)那么一定是離不開(kāi) 數(shù)據(jù)庫(kù) 的,不管你搞的是什么,只要是想使用動(dòng)態(tài)的開(kāi)發(fā)結(jié)構(gòu),那么一定就是 JDBC ,那么下面首先來(lái)回顧一下傳統(tǒng)JDBC的使用。

JDBC有四種連接: 像JDBC-ODBC的連接已經(jīng)確定不再使用了、主要采用的是 JDBC網(wǎng)絡(luò)連接模式

在JDBC的開(kāi)發(fā)之中,一定要 配置相應(yīng)數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序 后才可以使用,所以這就屬于標(biāo)準(zhǔn)的做法,同時(shí)還有一點(diǎn)必須明確,不管未來(lái)出現(xiàn)了什么樣的 Java數(shù)據(jù)庫(kù)開(kāi)發(fā)框架,那么核心的本質(zhì)只有一點(diǎn): JDBC,可是JDBC 標(biāo)準(zhǔn)里面所定義的 操作結(jié)構(gòu) 是屬于 較為底層 的操作形式,所以使用起來(lái) 非常的繁瑣,因?yàn)閹缀跛械臄?shù)據(jù)庫(kù)的項(xiàng)目都需要加載驅(qū)動(dòng)、創(chuàng)建數(shù)據(jù)庫(kù)連接、數(shù)據(jù)庫(kù)的操作對(duì)象、關(guān)閉數(shù)據(jù)庫(kù),只有中間的數(shù)據(jù)庫(kù)的CRUD操作是有區(qū)別的,那么就需要考慮對(duì)JDBC進(jìn)行封裝了,那么這個(gè)時(shí)候就有了ORM組件(全稱(chēng)ORMapping、對(duì)象關(guān)聯(lián)映射,采用對(duì)象的形式實(shí)現(xiàn)JDBC的開(kāi)發(fā)操作)。

? 從歷史的發(fā)展上來(lái)講,ORMapping組件出現(xiàn)較多:JDO、Entity Bean、Hibernate、IBatis、SpringJDBC、MyBatis、JPA標(biāo)準(zhǔn),當(dāng)然隨著技術(shù)的發(fā)展與淘汰,基本上現(xiàn)在階段剩下的ORM組件,常用的就是MyBatis(國(guó)內(nèi)互聯(lián)網(wǎng)公司)、JPA(國(guó)外機(jī)構(gòu)),而SpringJDBC是屬于JDBC的輕度包裝組件(其他的組件都屬于重度包裝),所以使用SpringJDBC可以 簡(jiǎn)化JDBC 傳統(tǒng)開(kāi)發(fā)里面繁瑣的操作步驟。

添加依賴

<properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.3.21</spring.version>
        <mysql.version>8.0.30</mysql.version>
</properties>

<dependencies>
    	<!--核心依賴-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
		<!--spring-jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
		<!--數(shù)據(jù)庫(kù)依賴-->	
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    
    	<!--測(cè)試-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
        </dependency>

    	<!--日志依賴-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
     	<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
		<!--日志依賴-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>

log4j.properties 日志配置文件 (當(dāng)啟動(dòng)程序,沒(méi)有任何報(bào)錯(cuò),但是沒(méi)有信息打印時(shí),需要配置日志)

#將等級(jí)為DEBUG的日志信息輸出到console和file這兩個(gè)目的地,console和file的定義在下面的代碼
log4j.rootLogger=DEBUG,console,file

#控制臺(tái)輸出的相關(guān)設(shè)置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n


#文件輸出的相關(guān)設(shè)置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logFile.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志輸出級(jí)別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

2、使用

要想使用JDBC,配置數(shù)據(jù)源,是關(guān)鍵性的一步。

2.1、配置數(shù)據(jù)源

2.1.1、注冊(cè)數(shù)據(jù)源對(duì)像

創(chuàng)建數(shù)據(jù)源的配置類(lèi):(基于配置類(lèi)的方式)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
    @Bean
    public DataSource dataSource() {
        // 驅(qū)動(dòng)數(shù)據(jù)源
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        // 加載驅(qū)動(dòng)程序
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/yootk"); 
        dataSource.setUsername("root"); 
        dataSource.setPassword("317311");
        return dataSource;
    }
}

創(chuàng)建數(shù)據(jù)源的配置類(lèi):(基于xml的方式)

<?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:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--數(shù)據(jù)源的配置-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/yootk"/>
        <property name="username" value="root"/>
        <property name="password" value="317311"/>
    </bean>
</beans>

2.1.2、測(cè)試

import look.word.jdbc.config.DataSourceConfig;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.sql.DataSource;

@ContextConfiguration(classes = DataSourceConfig.class) //	兩者二選一即可
//@ContextConfiguration(locations ={"classpath:data-source.xml"})  
@ExtendWith(SpringExtension.class)
public class TestDataSource {
	// 日志工廠對(duì)象
    private static final Logger LOGGER = LoggerFactory.getLogger(TestDataSource.class);
    @Autowired
    private DataSource dataSource;
    @Test
    public void testConnection() throws Exception{
        LOGGER.info("【數(shù)據(jù)庫(kù)連接對(duì)象】:{}",dataSource);
    }
}

// 執(zhí)行結(jié)果 輸入數(shù)據(jù)源對(duì)象,說(shuō)明連接成功
// [INFO ] 2022-09-14 12:18:59,307(386) --> [main] look.word.test.TestDataSource.testConnection(TestDataSource.java:29): 【數(shù)據(jù)庫(kù)連接對(duì)象】:org.springframework.jdbc.datasource.DriverManagerDataSource@535779e4

但是基于這種連接操作的性能是非常一般的,請(qǐng)追隨源代碼,一探究竟。

然后找到我們的AbstractDriverBasedDataSource.getConnection()方法,進(jìn)入getConnectionFromDriver()方法。

找到getConnectionFromDriver(),他是一個(gè)抽象方法,然后找到其子類(lèi),DriverManagerDataSource

然后又會(huì)發(fā)現(xiàn),我們回到了DriverManagerDataSource,然后我們?cè)谶M(jìn)入getConnectionFromDriverManager方法。

最終獲取連接的方式,

2.1.3、默認(rèn)連接方式的缺點(diǎn)

? 這種連接的管理方式,是在每一次 獲取連接 的時(shí)候 才進(jìn)行 數(shù)據(jù)庫(kù)連接的操作了,那么現(xiàn)在的問(wèn)題就來(lái)了,這樣的管理方式好嗎 ?首先在數(shù)據(jù)庫(kù)連接的處理之中,一定會(huì)建立若干個(gè)Socket 連接,那么會(huì)有耗時(shí),而在數(shù)據(jù)庫(kù)關(guān)閉的時(shí)候也會(huì)存在有同樣的耗時(shí)處理,這樣在“次次次高并發(fā)”的處理下很難得到有效的控制。所以在實(shí)際項(xiàng)目中最佳數(shù)據(jù)庫(kù)連接的管理,一定是基于數(shù)據(jù)庫(kù)連接池方式實(shí)現(xiàn)的。所以此時(shí)可以考慮在 Spring 內(nèi)部去實(shí)現(xiàn)一個(gè)連接池的維護(hù)。早期的數(shù)據(jù)庫(kù)連接池組件提供有一個(gè) C3P0組件,但是現(xiàn)在已經(jīng)停止維護(hù)了。

2.2、HikariCP

? 在實(shí)際的項(xiàng)目應(yīng)用開(kāi)發(fā)過(guò)程之中,為了解決JDBC連接與關(guān)閉的延時(shí)以及性能問(wèn)題,提供了數(shù)據(jù)庫(kù)連接池的解決方案,并且針對(duì)于該方案提供了成型的HikariCP服務(wù)組件。HikariCP (Hikari來(lái)自日文,是“光”的含義)是由日本程序員開(kāi)源的一個(gè)數(shù)據(jù)庫(kù)連接池組件,該組件擁有如下特點(diǎn):

  • 宇節(jié)碼更加的精簡(jiǎn),這樣可以在緩存中添加更多的程序代碼;
  • 實(shí)現(xiàn)了一個(gè)無(wú)鎖集合,減少了并發(fā)訪問(wèn)造成的資源競(jìng)爭(zhēng)問(wèn)題;
  • 使用了自定義數(shù)組類(lèi)型(FastList)代替了ArrayList,提高了get()與remove()的操作性能;
  • 針對(duì)CPU的時(shí)間片算法進(jìn)行了優(yōu)化,盡可能在一個(gè)時(shí)間片內(nèi)完成所有處理操作。

? 在Spring之中默認(rèn)推薦的數(shù)據(jù)庫(kù)連接池組件就是HikariCP,不建議再使用其他的數(shù)據(jù)庫(kù)連接池組件,當(dāng)然國(guó)內(nèi)也有優(yōu)秀的CP組件,那么就是阿里推出的Druid(在性能上可能低于HikariCP,但是提供有完整的管理界面),如果要想使用這個(gè)組件,可以采用如下的步驟進(jìn)行配置。

2.2.1、使用

添加依賴:

<dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>5.0.1</version>
            </dependency>

編寫(xiě)配置類(lèi):

這次我們?cè)儆门渲梦募姆绞?,方便擴(kuò)展

創(chuàng)建配置文件:src/main/profiles/dev/config/database.properties

yootk.database.driverClassName=com.mysql.cj.jdbc.Driver
yootk.database.jdbcUrl=jdbc:mysql://localhost:3306/yootk
yootk.database.username=root
yootk.database.password=317311
# 【Hikaricp】配置數(shù)據(jù)庫(kù)連接超時(shí)時(shí)間 單位【毫秒】
yootk.database.connectionTimeOut=3000
# 【Hikaricp】一個(gè)連接最小維持的時(shí)間 單位【毫秒】
yootk.database.idleTimeOut=3000
# 【Hikaricp】一個(gè)連接最長(zhǎng)存活的時(shí)間 單位【毫秒】
yootk.database.maxLifetime=6000
# 【Hikaricp】最大保存的數(shù)據(jù)庫(kù)連接實(shí)例
yootk.database.maximumPoolSize=60
# 【Hikaricp】最小保存的數(shù)據(jù)庫(kù)連接實(shí)例 (在沒(méi)有任何用戶訪問(wèn)時(shí),最少維持的連接數(shù)量)
yootk.database.minimumIdle=20
# 【Hikaricp】是否為只讀
yootk.database.readOnly=false

創(chuàng)建配置對(duì)象

@Configuration
//讀取指定位置的資源文件
@PropertySource("classpath:config/database.properties") 
public class HikariCpDataSourceConfig {
    /**
     * 綁定資源文件中的配置數(shù)據(jù)項(xiàng)
     */
    @Value("${yootk.database.driverClassName}")
    private String driverClassName;
    @Value("${yootk.database.jdbcUrl}")
    private String jdbcUrl;
    @Value("${yootk.database.username}")
    private String username;
    @Value("${yootk.database.password}")
    private String password;
    @Value("${yootk.database.connectionTimeOut}")
    private Long connectionTimeOut;
    @Value("${yootk.database.idleTimeOut}")
    private Long idleTimeOut;
    @Value("${yootk.database.maxLifetime}")
    private Long maxLifetime;
    @Value("${yootk.database.maximumPoolSize}")
    private Integer maximumPoolSize;
    @Value("${yootk.database.minimumIdle}")
    private Integer minimumIdle;
    @Value("${yootk.database.readOnly}")
    private boolean readOnly;

    @Bean("dataSource")
    public DataSource dataSource() {
        // Hikari連接池?cái)?shù)據(jù)源
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setPassword(password);
        // 超時(shí)時(shí)間
        dataSource.setConnectionTimeout(connectionTimeOut);
        // 空閑超時(shí)
        dataSource.setIdleTimeout(idleTimeOut);
        // 連接的最長(zhǎng)時(shí)間
        dataSource.setMaxLifetime(maxLifetime);
        // 連接池最大數(shù)量
        dataSource.setMaximumPoolSize(maximumPoolSize);
        // 當(dāng)沒(méi)有連接時(shí) 最小保留的連接數(shù)量
        dataSource.setMinimumIdle(minimumIdle);
        // 是否只讀數(shù)據(jù)庫(kù)
        dataSource.setReadOnly(readOnly);
        return dataSource;
    }
}

測(cè)試類(lèi):

import look.word.jdbc.config.HikariCpDataSourceConfig;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import javax.sql.DataSource;
@ContextConfiguration(classes = HikariCpDataSourceConfig.class)
@ExtendWith(SpringExtension.class)
public class TestDataSource {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestDataSource.class);

    @Autowired
    private DataSource dataSource;

    @Test
    public void testConnection() throws Exception {
        LOGGER.info("【數(shù)據(jù)庫(kù)連接對(duì)象】:{}", dataSource.getConnection());
    }
}

? 如果出錯(cuò),可以看看日志輸入信息。

這樣我們就實(shí)現(xiàn)了,使用HikariCP獲取連接對(duì)象了,接下來(lái)就會(huì)使用HikariCP對(duì)具體的數(shù)據(jù)庫(kù)進(jìn)行操作。

2.3、JdbcTempLate

JdbcTempLate的使用很簡(jiǎn)單,只需要為其指定數(shù)據(jù)源即可。

我們采用配置類(lèi)的方式,為其配置數(shù)據(jù)源

2.3.1、增

添加配置類(lèi):

@Configuration
public class JdbcTempLateConfig {
    @Bean // 方法形參 會(huì)自動(dòng)從容器中注入對(duì)象
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return jdbcTemplate;
    }
}

編寫(xiě)測(cè)試類(lèi):

@ContextConfiguration(classes = {HikariCpDataSourceConfig.class, JdbcTempLateConfig.class})
@ExtendWith(SpringExtension.class)
public class TestJdbcTempLate {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestJdbcTempLate.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void testConnection() throws Exception {
        String sql = "insert into book(title,author,price) values('java入門(mén)','李老師',99.90)";
        LOGGER.info("【插入執(zhí)行結(jié)果】:{}", jdbcTemplate.update(sql));
    }
}

執(zhí)行結(jié)果:

這個(gè)時(shí)候就是用JdbcTemplate輕松地實(shí)現(xiàn)了數(shù)據(jù)的插入操作。

但是,可以發(fā)現(xiàn),我們上面的操作,還是存在問(wèn)題的,比如沒(méi)有對(duì)sql 進(jìn)行預(yù)處理,會(huì)出現(xiàn) Sql 注入的風(fēng)險(xiǎn)。

2.3.2、改

測(cè)試類(lèi)

@Test
    public void testUpdate() {
        String sql = "update yootk.book set title = ? where bid = ?";
        LOGGER.info("【插入執(zhí)行結(jié)果】:{}", jdbcTemplate.update(sql, "Python入門(mén)", 2));
    }

2.3.3、刪

測(cè)試類(lèi)

@Test
    public void testDelete() {
        String sql = "delete from yootk.book  where bid = ?";
        LOGGER.info("【插入執(zhí)行結(jié)果】:{}", jdbcTemplate.update(sql, 2));
    }

2.3.4、增 (返回id)

在MySQL數(shù)據(jù)庫(kù)里面,有一種功能,可以通過(guò)一個(gè)next()處理函數(shù)獲取當(dāng)前所生成的ID號(hào)(主要針對(duì)于自動(dòng)增長(zhǎng)列),實(shí)際上這個(gè)功能主要的目的是為了解決增加數(shù)據(jù)時(shí)的ID返回處理問(wèn)題了,因?yàn)楹芏嗟臅r(shí)候需要在數(shù)據(jù)增加成功之后對(duì)指定的ID進(jìn)行控制,所以才提供了專(zhuān)屬的處理函數(shù),Oracle之中直接使用序列即可,但是MySQL的實(shí)現(xiàn)就需要專(zhuān)屬的處理函數(shù)了。.在程序的開(kāi)發(fā)之中,如果要想獲取到增長(zhǎng)后的ID數(shù)據(jù),在SpringJDBC里面提供有了一個(gè)KeyHolder接口,在這個(gè)接口里面定義了獲取主鍵內(nèi)容的處理方法。

? 在平常開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到,插入這個(gè)數(shù)據(jù)后,會(huì)需要這個(gè)數(shù)據(jù)的id,然后對(duì)其進(jìn)行一系類(lèi)操作。

? 如果要想獲取到增長(zhǎng)后的ID數(shù)據(jù),在SpringJDBC里面提供有了一個(gè)KeyHolder接口,在這個(gè)接口里面定義了獲取主鍵內(nèi)容的處理方法。

測(cè)試類(lèi)

@Test
    public void testInsertReturnId() {
        String sql = "insert into yootk.book(title,author,price) values(?,?,?)";
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); // 獲取KEY的處理信息
        int count = jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); // 對(duì)sql進(jìn)行預(yù)處理
                ps.setString(1, "Springboot實(shí)戰(zhàn)");
                ps.setString(2, "老李");
                ps.setDouble(3, 99.00);
                return ps;
            }
        }, keyHolder);
        LOGGER.info("【插入執(zhí)行影響行數(shù)】:{},當(dāng)前插入數(shù)據(jù)的ID:{}", count, keyHolder.getKey());
    }
// 執(zhí)行結(jié)果
// look.word.test.TestJdbcTempLate.testInsertReturnId(TestJdbcTempLate.java:61): 【插入執(zhí)行影響行數(shù)】:1,當(dāng)前插入數(shù)據(jù)的ID:4

如果在 PreparedStatement ps = con.prepareStatement(sql);中,沒(méi)有指定需要返回KEY,則會(huì)出現(xiàn)異常。

2.3.5、批處理

測(cè)試類(lèi):

這種方式是基于集合的。

@Test
    public void testInsertBatch() {
        List<String> titles = List.of("Springboot開(kāi)發(fā)實(shí)戰(zhàn)", "SSM開(kāi)發(fā)案例", "Netty開(kāi)發(fā)實(shí)戰(zhàn)", "Redis開(kāi)發(fā)實(shí)戰(zhàn)");
        List<Double> prices = List.of(90.1, 98.9, 78.9, 98.9);
        String sql = "insert into yootk.book(title,author,price) values(?,?,?)";
        this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {  // 執(zhí)行批量插入
             //@param i  集合索引
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setString(1, titles.get(i));
                ps.setString(2, "老李老師");
                ps.setDouble(3, prices.get(i));
            }
            @Override
            public int getBatchSize() {
                return titles.size(); //總長(zhǎng)度
            }
        });
    }

基于對(duì)象

@Test
    public void testInsertBatch2() {
        List<Object[]> params = List.of(
                new Object[]{"Spring開(kāi)發(fā)實(shí)戰(zhàn)", "11", 89.0},
                new Object[]{"Spring開(kāi)發(fā)實(shí)戰(zhàn)1", "11", 89.0},
                new Object[]{"Spring開(kāi)發(fā)實(shí)戰(zhàn)2", "11", 89.0},
                new Object[]{"Spring開(kāi)發(fā)實(shí)戰(zhàn)3", "11", 89.0}
        );
        String sql = "insert into yootk.book(title,author,price) values(?,?,?)";
        int[] result = jdbcTemplate.batchUpdate(sql, params);//批量插入
        System.out.println("result = " + result);
    }

2.3.4、查

? 在數(shù)據(jù)庫(kù)操作過(guò)程中,除了數(shù)據(jù)更新操作之外,最為繁瑣的就是數(shù)據(jù)庫(kù)的查詢功能了。由于JdbcTemplate設(shè)計(jì)的定位屬于ORMapping組件,所以就需要在查詢完成之后,可以自動(dòng)的將查詢結(jié)果轉(zhuǎn)為VO類(lèi)型的實(shí)例,而為了解決該問(wèn)題,在SpringJDBC中提供了一個(gè)RowMapper接口,這個(gè)接口可以實(shí)現(xiàn)ResultSet向指定對(duì)象實(shí)例的轉(zhuǎn)換。該接口提供有一個(gè)mapRow()處理方法,可以接收查詢結(jié)果每行數(shù)據(jù)的結(jié)果集,用戶可以將指定列取出,并保存在自標(biāo)VO實(shí)例之中

查詢單個(gè)

Book 對(duì)象 根據(jù)數(shù)據(jù)庫(kù)創(chuàng)建

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer bid;
    private String title;
    private String author;
    private Double price;
}

測(cè)試類(lèi):

// 查詢單個(gè)
    @Test
    public void testQuery() {
        String sql = "select  bid, title, author, price from yootk.book  where bid = ?";
        Book book = jdbcTemplate.queryForObject(sql, new RowMapper<Book>() {
            @Override
            public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
                Book book = new Book();
                book.setBid(rs.getInt(1));
                book.setTitle(rs.getString(2));
                book.setAuthor(rs.getString(3));
                book.setPrice(rs.getDouble(4));
                return book;
            }
        }, 3); // 這里的3 是對(duì)預(yù)處理數(shù)據(jù)的回填 多個(gè)需按照順序編寫(xiě)
        System.out.println("【queryForObject 查詢結(jié)果】book = " + book);
    }

查詢多個(gè)

// 查詢所有
    @Test
    public void testQueryAll() {
        String sql = "select  bid, title, author, price from yootk.book ";
        List<Book> list = jdbcTemplate.query(sql, new RowMapper<Book>() {
            @Override
            public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
                Book book = new Book();
                book.setBid(rs.getInt(1));
                book.setTitle(rs.getString(2));
                book.setAuthor(rs.getString(3));
                book.setPrice(rs.getDouble(4));
                return book;
            }
        });
        list.stream().forEach(System.out::println);
    }

分頁(yè)查詢

// 分頁(yè)
    @Test
    public void testQuerySpAll() {
        int current = 2; // 頁(yè)數(shù)
        int size = 5;// 每頁(yè)數(shù)量
        String sql = "select  bid, title, author, price from yootk.book limit ? ,?  ";
        List<Book> list = jdbcTemplate.query(sql, new RowMapper<Book>() {
            @Override
            public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
                Book book = new Book();
                book.setBid(rs.getInt(1));
                book.setTitle(rs.getString(2));
                book.setAuthor(rs.getString(3));
                book.setPrice(rs.getDouble(4));
                return book;
            }
        }, (current - 1) * size, size);
        list.stream().forEach(System.out::println);
    }

統(tǒng)計(jì)行數(shù)

// 查詢行數(shù)
    @Test
    public void testQueryCount() {
        String sql = "select  count(*) from yootk.book where title like ?";
        long count = jdbcTemplate.queryForObject(sql, new RowMapper<Long>() {
            @Override
            public Long mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getLong(1);
            }
        }, "%Spring%");
        LOGGER.info("【數(shù)據(jù)庫(kù)記錄總行數(shù)】{}", count);
    }

以上就是一文帶你學(xué)會(huì)Spring JDBC的使用的詳細(xì)內(nèi)容,更多關(guān)于Spring JDBC的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java?http請(qǐng)求獲取圖片并返回文件流給前端的方法步驟

    java?http請(qǐng)求獲取圖片并返回文件流給前端的方法步驟

    作為一名Java后端開(kāi)發(fā)者,掌握如何從后端返回文件流至前端是基本技能之一,這篇文章主要介紹了java?http請(qǐng)求獲取圖片并返回文件流給前端的方法步驟,需要的朋友可以參考下
    2024-09-09
  • Java System類(lèi)用法實(shí)戰(zhàn)案例

    Java System類(lèi)用法實(shí)戰(zhàn)案例

    這篇文章主要介紹了Java System類(lèi)用法,結(jié)合具體實(shí)例形式分析了java使用System類(lèi)獲取系統(tǒng)環(huán)境變量信息相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • 手把手教你如何搭建SpringBoot+Vue前后端分離

    手把手教你如何搭建SpringBoot+Vue前后端分離

    這篇文章主要介紹了手把手教你如何搭建SpringBoot+Vue前后端分離,前后端分離是目前開(kāi)發(fā)中常用的開(kāi)發(fā)模式,達(dá)成充分解耦,需要的朋友可以參考下
    2023-03-03
  • java springmvc亂碼解決歸納整理詳解

    java springmvc亂碼解決歸納整理詳解

    本篇文章介紹了java 中spring mvc 解決亂碼的問(wèn)題方法實(shí)例,需要的朋友可以參考下
    2017-04-04
  • Spring?Boot實(shí)現(xiàn)分布式任務(wù)調(diào)度的步驟

    Spring?Boot實(shí)現(xiàn)分布式任務(wù)調(diào)度的步驟

    Spring?Boot提供了一些工具和框架,可以幫助我們輕松地實(shí)現(xiàn)分布式任務(wù)調(diào)度,在本文中我們將介紹如何使用Spring?Boot、Spring?Cloud、Quartz和Redis來(lái)實(shí)現(xiàn)分布式任務(wù)調(diào)度,感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • 安裝多個(gè)版本JDK后使用時(shí)的切換方法總結(jié)

    安裝多個(gè)版本JDK后使用時(shí)的切換方法總結(jié)

    我們平時(shí)在window上做開(kāi)發(fā)的時(shí)候,可能需要同時(shí)開(kāi)發(fā)兩個(gè)甚至多個(gè)項(xiàng)目,有時(shí)不同的項(xiàng)目對(duì)JDK的版本要求有區(qū)別,下面這篇文章主要給大家介紹了安裝多個(gè)版本JDK后使用的切換方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-01-01
  • 分享15款Java程序員必備的開(kāi)發(fā)工具

    分享15款Java程序員必備的開(kāi)發(fā)工具

    這篇文章主要介紹了分享15款Java程序員必備的開(kāi)發(fā)工具,需要的朋友可以參考下
    2015-02-02
  • Java基礎(chǔ)之讓你徹底搞懂代理模式

    Java基礎(chǔ)之讓你徹底搞懂代理模式

    這篇文章主要介紹了Java基礎(chǔ)之讓你徹底搞懂代理模式,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)

    Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)

    下面小編就為大家?guī)?lái)一篇Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java文件拒絕訪問(wèn)問(wèn)題及解決

    Java文件拒絕訪問(wèn)問(wèn)題及解決

    這篇文章主要介紹了Java文件拒絕訪問(wèn)問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論