我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文带你学会Spring JDBC的使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文带你学会Spring JDBC的使用

1、JDBC

JDBC 就是 数据库开发 操作的 代名词,因为只要是现代商业项目的开发那么一定是离不开 数据库 的,不管你搞的是什么,只要是想使用动态的开发结构,那么一定就是 JDBC ,那么下面首先来回顾一下传统JDBC的使用。

JDBC有四种连接: 像JDBC-ODBC的连接已经确定不再使用了、主要采用的是 JDBC网络连接模式

在JDBC的开发之中,一定要 配置相应数据库的驱动程序 后才可以使用,所以这就属于标准的做法,同时还有一点必须明确,不管未来出现了什么样的 Java数据库开发框架,那么核心的本质只有一点: JDBC,可是JDBC 标准里面所定义的 操作结构 是属于 较为底层 的操作形式,所以使用起来 非常的繁琐,因为几乎所有的数据库的项目都需要加载驱动、创建数据库连接、数据库的操作对象、关闭数据库,只有中间的数据库的CRUD操作是有区别的,那么就需要考虑对JDBC进行封装了,那么这个时候就有了ORM组件(全称ORMapping、对象关联映射,采用对象的形式实现JDBC的开发操作)。

​ 从历史的发展上来讲,ORMapping组件出现较多:JDO、Entity Bean、Hibernate、IBatis、SpringJDBC、MyBatis、JPA标准,当然随着技术的发展与淘汰,基本上现在阶段剩下的ORM组件,常用的就是MyBatis(国内互联网公司)、JPA(国外机构),而SpringJDBC是属于JDBC的轻度包装组件(其他的组件都属于重度包装),所以使用SpringJDBC可以 简化JDBC 传统开发里面繁琐的操作步骤。

添加依赖

<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>
		<!--数据库依赖-->	
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    
    	<!--测试-->
        <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 日志配置文件 (当启动程序,没有任何报错,但是没有信息打印时,需要配置日志)

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
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


#文件输出的相关设置
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

#日志输出级别
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,配置数据源,是关键性的一步。

2.1、配置数据源

2.1.1、注册数据源对像

创建数据源的配置类:(基于配置类的方式)

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() {
        // 驱动数据源
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        // 加载驱动程序
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/yootk"); 
        dataSource.setUsername("root"); 
        dataSource.setPassword("317311");
        return dataSource;
    }
}

创建数据源的配置类:(基于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">

    <!--数据源的配置-->
    <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、测试

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 {
	// 日志工厂对象
    private static final Logger LOGGER = LoggerFactory.getLogger(TestDataSource.class);
    @Autowired
    private DataSource dataSource;
    @Test
    public void testConnection() throws Exception{
        LOGGER.info("【数据库连接对象】:{}",dataSource);
    }
}

// 执行结果 输入数据源对象,说明连接成功
// [INFO ] 2022-09-14 12:18:59,307(386) --> [main] look.word.test.TestDataSource.testConnection(TestDataSource.java:29): 【数据库连接对象】:org.springframework.jdbc.datasource.DriverManagerDataSource@535779e4

但是基于这种连接操作的性能是非常一般的,请追随源代码,一探究竟。

然后找到我们的AbstractDriverBasedDataSource.getConnection()方法,进入getConnectionFromDriver()方法。

找到getConnectionFromDriver(),他是一个抽象方法,然后找到其子类,DriverManagerDataSource

然后又会发现,我们回到了DriverManagerDataSource,然后我们在进入getConnectionFromDriverManager方法。

最终获取连接的方式,

2.1.3、默认连接方式的缺点

​ 这种连接的管理方式,是在每一次 获取连接 的时候 才进行 数据库连接的操作了,那么现在的问题就来了,这样的管理方式好吗 ?首先在数据库连接的处理之中,一定会建立若干个Socket 连接,那么会有耗时,而在数据库关闭的时候也会存在有同样的耗时处理,这样在“次次次高并发”的处理下很难得到有效的控制。所以在实际项目中最佳数据库连接的管理,一定是基于数据库连接池方式实现的。所以此时可以考虑在 Spring 内部去实现一个连接池的维护。早期的数据库连接池组件提供有一个 C3P0组件,但是现在已经停止维护了。

2.2、HikariCP

​ 在实际的项目应用开发过程之中,为了解决JDBC连接与关闭的延时以及性能问题,提供了数据库连接池的解决方案,并且针对于该方案提供了成型的HikariCP服务组件。HikariCP (Hikari来自日文,是“光”的含义)是由日本程序员开源的一个数据库连接池组件,该组件拥有如下特点:

  • 宇节码更加的精简,这样可以在缓存中添加更多的程序代码;
  • 实现了一个无锁集合,减少了并发访问造成的资源竞争问题;
  • 使用了自定义数组类型(FastList)代替了ArrayList,提高了get()与remove()的操作性能;
  • 针对CPU的时间片算法进行了优化,尽可能在一个时间片内完成所有处理操作。

​ 在Spring之中默认推荐的数据库连接池组件就是HikariCP,不建议再使用其他的数据库连接池组件,当然国内也有优秀的CP组件,那么就是阿里推出的Druid(在性能上可能低于HikariCP,但是提供有完整的管理界面),如果要想使用这个组件,可以采用如下的步骤进行配置。

2.2.1、使用

添加依赖:

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

编写配置类:

这次我们再用配置文件的方式,方便扩展

创建配置文件:class="lazy" data-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】配置数据库连接超时时间 单位【毫秒】
yootk.database.connectionTimeOut=3000
# 【Hikaricp】一个连接最小维持的时间 单位【毫秒】
yootk.database.idleTimeOut=3000
# 【Hikaricp】一个连接最长存活的时间 单位【毫秒】
yootk.database.maxLifetime=6000
# 【Hikaricp】最大保存的数据库连接实例
yootk.database.maximumPoolSize=60
# 【Hikaricp】最小保存的数据库连接实例 (在没有任何用户访问时,最少维持的连接数量)
yootk.database.minimumIdle=20
# 【Hikaricp】是否为只读
yootk.database.readOnly=false

创建配置对象

@Configuration
//读取指定位置的资源文件
@PropertySource("classpath:config/database.properties") 
public class HikariCpDataSourceConfig {
    
    @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连接池数据源
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setPassword(password);
        // 超时时间
        dataSource.setConnectionTimeout(connectionTimeOut);
        // 空闲超时
        dataSource.setIdleTimeout(idleTimeOut);
        // 连接的最长时间
        dataSource.setMaxLifetime(maxLifetime);
        // 连接池最大数量
        dataSource.setMaximumPoolSize(maximumPoolSize);
        // 当没有连接时 最小保留的连接数量
        dataSource.setMinimumIdle(minimumIdle);
        // 是否只读数据库
        dataSource.setReadOnly(readOnly);
        return dataSource;
    }
}

测试类:

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("【数据库连接对象】:{}", dataSource.getConnection());
    }
}

​ 如果出错,可以看看日志输入信息。

这样我们就实现了,使用HikariCP获取连接对象了,接下来就会使用HikariCP对具体的数据库进行操作。

2.3、JdbcTempLate

JdbcTempLate的使用很简单,只需要为其指定数据源即可。

我们采用配置类的方式,为其配置数据源

2.3.1、增

添加配置类:

@Configuration
public class JdbcTempLateConfig {
    @Bean // 方法形参 会自动从容器中注入对象
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return jdbcTemplate;
    }
}

编写测试类:

@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入门','李老师',99.90)";
        LOGGER.info("【插入执行结果】:{}", jdbcTemplate.update(sql));
    }
}

执行结果:

这个时候就是用JdbcTemplate轻松地实现了数据的插入操作。

但是,可以发现,我们上面的操作,还是存在问题的,比如没有对sql 进行预处理,会出现 Sql 注入的风险。

2.3.2、改

测试类

@Test
    public void testUpdate() {
        String sql = "update yootk.book set title = ? where bid = ?";
        LOGGER.info("【插入执行结果】:{}", jdbcTemplate.update(sql, "Python入门", 2));
    }

2.3.3、删

测试类

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

2.3.4、增 (返回id)

在MySQL数据库里面,有一种功能,可以通过一个next()处理函数获取当前所生成的ID号(主要针对于自动增长列),实际上这个功能主要的目的是为了解决增加数据时的ID返回处理问题了,因为很多的时候需要在数据增加成功之后对指定的ID进行控制,所以才提供了专属的处理函数,Oracle之中直接使用序列即可,但是MySQL的实现就需要专属的处理函数了。.在程序的开发之中,如果要想获取到增长后的ID数据,在SpringJDBC里面提供有了一个KeyHolder接口,在这个接口里面定义了获取主键内容的处理方法。

​ 在平常开发中,我们经常会遇到,插入这个数据后,会需要这个数据的id,然后对其进行一系类操作。

​ 如果要想获取到增长后的ID数据,在SpringJDBC里面提供有了一个KeyHolder接口,在这个接口里面定义了获取主键内容的处理方法。

测试类

@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); // 对sql进行预处理
                ps.setString(1, "Springboot实战");
                ps.setString(2, "老李");
                ps.setDouble(3, 99.00);
                return ps;
            }
        }, keyHolder);
        LOGGER.info("【插入执行影响行数】:{},当前插入数据的ID:{}", count, keyHolder.getKey());
    }
// 执行结果
// look.word.test.TestJdbcTempLate.testInsertReturnId(TestJdbcTempLate.java:61): 【插入执行影响行数】:1,当前插入数据的ID:4

如果在 PreparedStatement ps = con.prepareStatement(sql);中,没有指定需要返回KEY,则会出现异常。

2.3.5、批处理

测试类:

这种方式是基于集合的。

@Test
    public void testInsertBatch() {
        List<String> titles = List.of("Springboot开发实战", "SSM开发案例", "Netty开发实战", "Redis开发实战");
        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() {  // 执行批量插入
             //@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(); //总长度
            }
        });
    }

基于对象

@Test
    public void testInsertBatch2() {
        List<Object[]> params = List.of(
                new Object[]{"Spring开发实战", "11", 89.0},
                new Object[]{"Spring开发实战1", "11", 89.0},
                new Object[]{"Spring开发实战2", "11", 89.0},
                new Object[]{"Spring开发实战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、查

​ 在数据库操作过程中,除了数据更新操作之外,最为繁琐的就是数据库的查询功能了。由于JdbcTemplate设计的定位属于ORMapping组件,所以就需要在查询完成之后,可以自动的将查询结果转为VO类型的实例,而为了解决该问题,在SpringJDBC中提供了一个RowMapper接口,这个接口可以实现ResultSet向指定对象实例的转换。该接口提供有一个mapRow()处理方法,可以接收查询结果每行数据的结果集,用户可以将指定列取出,并保存在自标VO实例之中

查询单个

Book 对象 根据数据库创建

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

测试类:

// 查询单个
    @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 是对预处理数据的回填 多个需按照顺序编写
        System.out.println("【queryForObject 查询结果】book = " + book);
    }

查询多个

// 查询所有
    @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);
    }

分页查询

// 分页
    @Test
    public void testQuerySpAll() {
        int current = 2; // 页数
        int size = 5;// 每页数量
        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);
    }

统计行数

// 查询行数
    @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("【数据库记录总行数】{}", count);
    }

以上就是一文带你学会Spring JDBC的使用的详细内容,更多关于Spring JDBC的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文带你学会Spring JDBC的使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一文带你学会使用PHP接口

PHP中的Interface是一种非常重要的特性,它允许开发人员定义一组规范或者约束,以确保类之间的互操作性和兼容性。在本文中,我们将详细介绍PHP中的Interface的概念、定义、实现、使用、使用场景以及其它相关的一些知识点,需要的朋友可以参考下
2023-05-18

一篇文章带你学会Spring MVC表单标签

SpringMVC表单标签是网页的可配置和可重复使用的构建块,下面这篇文章主要给大家介绍了如何通过一篇文章学会Spring MVC表单标签的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-03-24

一文带你学会规则引擎Drools的应用

Drools 就是一个开源的业务规则引擎,可以很容易地与 spring boot 应用程序集成,这篇文章就来和大家详细聊聊Drools的具体应用,需要的可以参考一下
2023-03-11

一文带你学会Java网络编程

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。这篇文章将带大家深入了解一下Java的网络编程,需要的可以了解一下
2022-11-13

一文带你快速学会C#中WinForm框架的使用详解

WinForm是一门非常经济实惠的技术,就是说,可以在短时间内学会,并迅速借此进行项目开发。本文就来和大家聊聊WinForm框架的使用方法,希望对大家有所帮助
2023-02-26

一文教你学会Go中singleflight的使用

Singleflight是一个Go包,可防止并发请求重复执行相同的耗时操作。它通过缓存结果来实现串行执行和性能提升。使用方法:创建Singleflight对象并指定执行的DoFunc执行DoFunc来获取结果获取结果和错误优势:避免重复操作,提高性能简化并发控制缓存结果用例:数据库查询、远程资源加载、复杂计算等。Singleflight还提供了配置选项,如缓存大小、过期时间和缓存未命中时的等待时间。
一文教你学会Go中singleflight的使用
2024-04-02

一分钟带你快速学会Selenium工具的使用

学会Selenium工具的使用可以帮助我们自动化网页测试,提高测试效率。下面是快速学习Selenium工具使用的步骤:1.下载Selenium WebDriver:首先,从Selenium官方网站下载Selenium WebDriver。根
2023-09-20

一文带你学会C语言中的qsort函数

qsort函数是C语言的库函数,能实现对各种元素类型的比较,使用的基本思想是快速排序法,头文件是<stdlib.h>,本文不讲解具体实现原理,只对使用方法进行说明,希望对大家有所帮助
2022-12-21

如何使用JDBC操作数据库?一文带你吃透JDBC规范

文章目录 1. 前言2. JDBC 概述2.1 概念2.2 优点 3. JDBC 快速入门4. JDBC API详解4.1 DriverManager4.1.1 注册驱动4.1.2 获取连接 4.2 Connection4
2023-08-17

一篇文章带你学会JavaScript计时事件

JS可以实现很多java代码不易完成的功能,下面这篇文章主要给大家介绍了关于如何通过一篇文章带你学会JavaScript计时事件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2022-11-16

一文带你学会Mysql表批量添加字段

目录1 mysql表批量添加字段1.1 添加单个字段1.2 批量添加多个字段 如果需要批量添加多个字段,可以使用逗号隔开多个字段的添加语句,如下所示:2 mysql 为多个表添加字段2.1 方法一:手动逐个添加2.2 方法二:使用脚本批量添
2023-05-05

一文带你学会Python Flask框架设置响应头

本篇博客我们将带大家全面了解Python中Flask框架关于请求的相关设置的相关知识,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下
2023-01-28

一文教你学会Redis的事务

Redis 作为内存的存储中间件,已经是面试的面试题必问之一了。今天小编就来和大家一起来聊聊Redis的事务吧,希望对大家有所帮助
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录