一文学会Spring JDBC 使用

Spring JDBC教程:从入门到实践 在Spring Boot中,JdbcTemplate通常通过自动配置创建,但你也可以自定义它以满足特定的需求。 阅读详情

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>

编写配置类:

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

  • 创建配置文件: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 加强版 ORM 框架 spring-data-jdbc 入门与实践 前言 Spring 为了支持以统一的方式访问不同类型的数据库,提供了一个 Spring Data 框架,这个框架根据不同的数据库访问技术划分了不同的模块。上篇 《Spring 加强版 ORM 框架 Spring Data 入门》 介绍了不同模块遵循的通用规范,这篇我们来介绍下基于 JDBC 技术实现的 spring-data-jdbc 模块。 一、入门 基本的概念这里就不多说了,如果你在本篇遇到不明白的地方可以移步上一篇文章查看相关内容。 Spring Boot 内置了对 spring-data-jdbc 阅读详情

相关推荐

Python实战:5分钟搞定N-CMAPSS航空发动机数据集解析(附完整代码)

本文提供了一份针对N-CMAPSS航空发动机数据集的快速解析实战指南。通过Python的h5py库,详细演示了如何读取HDF5文件结构、理解数据分类(如传感器、健康参数、场景描述符)并加载为Pandas DataFrame。文章还澄清了数据集中常见的变量数量疑惑,并给出了从数据加载到构建剩余使用寿命预测模型预处理流水线的完整代码,帮助工程师和研究人员高效入门航空发动机预测性维护分析。

weixin_29057065的博客 422

Spring JDBC

Spring JDBC模块负责数据库资源管理和错误处理。 针对数据库操作,Spring框架提供了JdbcTemplate类,该类是Spring JDBC的核心类。 一、Spring JDBC的配置 Spring JDBC主要由4个包组成: Spring JDBC所需要的jar包: Spring对数据库的操作都封装在了这几个包中,想要使用JDBC就需要对其进行配置,在Spring容器中,对JDBC的配置是在applicationContext.xml文件中进行的。 <?xml ..

m0_51457307的博客 7073

西门子1200,与V90和步科MD60第三方伺服PN通讯

需要注意的是回零方式的选择,因为V90是绝对值编码器,这里回零模式选择模式7,系统自动根据编码器反馈以及组态的机械参数,计算出轴的位置,并且掉电保持。在线访问中,找到对应的网卡,以及下面扫描到的设备,可以在线修改ip地址和profinet名称,注意一定要和组态中的完全一致。以上硬件组态上完成,主要是gsd文件导入后,添加硬件,建立连接,修改ip和profinet名称,添加报文。1- 博图V18内,设备组态,网络视图中,拖入V90以及MD60伺服,并与PLC创建连接。向厂家索要GSD文件,PN的描述文件。

weixin_37596954的博客 2465

Spring之JDBC

Spring JDBC是Spring所提供的持久层技术,负责数据库资源和错误处理,降低JDBC API的使用难度,以一种更简洁,更直接的方式使用JDBC API,大大简化了开发人员对数据库的操作。

m0_58024723的博客 1832

S32K144 SDK实战:FTM输入捕获模块的配置与应用

本文详细介绍了S32K144 SDK中FTM输入捕获模块的配置与应用实践。从基础认知到开发环境搭建,再到引脚配置和中断处理技巧,全面解析了如何利用FTM模块实现高精度信号测量。特别适用于电机控制、工业测速等场景,帮助开发者快速掌握S32K144的FTM输入捕获功能。

weixin_42566424的博客 217

论文工具——写论文好用的绘图工具(甘特图+流程图+网络模型图+泳道图)

* 在写HiFi-GAN论文的代码阅读过程中,我发现仅仅通过文字来描述网络结构,不够详细,所以想绘制出网络结构图,更加具象化的描述出网络结构。想去花了,才发现之前都是通过在线绘图网站画的,费时费力,所以想找一些专门的网站化出比较规范并且高质量的图。一方面是为了方便讲解,提高论文的质量,另外一方面也是为了以后写论文打下良好的基础。 * 这篇文章会根据我以前的画图经验展开,以前是使用绘图软件,手动绘图。后来,看到了其他的方法,但是需要写一些代码,或者需要安装特定的软件,投入成本太大,就没有学。所以,本文分享的工

Blackoutdragon的博客 1万+

Spring系列四之JDBC

Spring JDBCSpring JDBC之数据库环境MySQL及辅助jar包的下载MySQL解压缩版的安装登录MySQLEclipse连接MySQL Spring JDBC之数据库环境 下面开始学习Sping中数据库的相关内容 MySQL及辅助jar包的下载 在学习Spring JDBC中,我们采用的数据库是MySQL,版本是社区版+解压缩版,因为社区版是免费的,解压缩版相对msi安装版更锻炼...

gengermao的博客 3239

Qemu开发ARM篇-3、qemu运行uboot演示

在上一篇文章中,我们搭建了交叉编译工具链,并成功进行了uboot的交叉编译,在该篇中,我们将演示如何利用qemu运行上一篇中交叉编译的uboot程序。

sinat_33909696的博客 1212

被缠上了,小王问我怎么在 Spring Boot 中使用 JDBC 连接 MySQL

上次帮小王入了 Spring Boot 的门后,他觉得我这个人和蔼可亲、平易近人,于是隔天小王又微信我说:“二哥,快教教我,怎么在 Spring Boot 项目中使用 JDBC 连接 MySQL 啊?” 收到问题的时候,我有点头大,难道以后就要被小王缠上了? 没等我发牢骚,小王就紧接着说:“二哥,你先别生气,上次你帮了我的忙后,我在心里感激了你一晚上,想着第一次遇到这么亲切的大佬,一定要抱紧大腿。。。。。” 马屁拍到这份上,我的气自然也就消了。随后,我花了五分钟的时间帮他解决了苦恼,没成想,他又...

keocce的博客 200

Serial RapidIO Gen2 IP 说明(三)

前言 继续接着上篇文章,介绍Serial RapidIO Gen2 IP 的具体端口信息。 一、端口描述 1、缓冲设计接口 2、物理层接口 参考说明 【1】Serial RapidIO Gen2 v4.1https://china.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/srio_gen2/v4_1/pg007_srio_gen2.pdf ...

记录所学,分享知识,结识挚友 1322

RockChip Android14 修改LCD背光最大值

在调试LCD屏时时长会出现硬件不匹配,导致电流过大,屏幕发热严重。在不调整硬件的情况下,我们可以通过修改软件,降低LCD背光最大值来实现适配。我们都知道LCD屏背光是靠pwm来控制,一般来说最大值可以设置为255,针对上述问题,我们可以通过软件来降低该值,比如200,100等等。

qq_34968572的博客 631

JSP中国古典文学学习系统40080--程序+源码+数据库+调试部署+开发环境

中国古典文学源远流长、博大精深,是中华民族的文化瑰宝。然而,在数字化时代,传统学习方式面临资源分散、互动性不足等问题。开发中国古典文学学习系统,能整合丰富的学习资源,提供多样化的学习方式,激发学习者兴趣,促进古典文学的传承与弘扬,具有重要的文化价值与教育意义。

Kittyxia001的博客 874

Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay)

植被是陆地生态系统中最重要的组分之一,也是对气候变化最敏感的组分,其在全球变化过程中起着重要作用,能够指示自然环境中的大气、水、土壤等成分的变化,其年际和季节性变化可以作为地球气候变化的重要指标。此外,由于生态工程保护建设和植被自然生长等因素,中国陆地生态系统发挥了重要的碳汇作用。因此,定量评估植被时空动态变化是制定生态系统可持续发展目标和衡量生态系统固碳潜力的重要前提,卫星遥感数据衍生的生态参量产品为研究长时间序列全球及区域植被时空变化提供了重要数据源。SG滤波能够对物候信息进行平滑,并提取其中的物候信息

amyniez的博客,欢迎交流讨论 4248

Spring MVC系列之JDBC Demo(SpringBoot)(七)

前言清风文学网 www.198200.com 前面我们了解了Spring MVC的基本使用,其实和.NET或.NET Core MVC无异,只是语法不同而已罢了,本节我们将和和数据库打交道,从最基础的JDBC讲解起,文中若有错误之处,还望指正。 JDBC Demo 我们需要下载三个包:JDBC驱动包(mysql-connector-java)、spring boot启用jdbc(spri...

终极冥帝 262

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JDBC时间类型映射全解析:从Date到LocalDateTime的演进

本文深入探讨JDBC时间类型映射的最佳实践,从历史演进到现代解决方案。早期使用java.util.Date存在设计缺陷,JDBC引入java.sql包的三剑客(Date、Time、Timestamp)作为过渡。Java 8的java.time包彻底解决了时间处理问题,JDBC 4.2原生支持这些新类型,推荐使用setObject/getObject方法实现类型安全和精度保持。文章提供了数据库与Java类型的详细映射表,并针对时区敏感场景给出解决方案。最后通过实体类设计和数据访问层实现示例,展示了实际应用中的

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 1190

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SpringBoot构建琼瑶文学数字化平台的技术实践

SpringBoot作为现代Java开发的主流框架,以其高效的开发模式和丰富的生态系统著称,特别适合构建垂直领域的数字化平台。其核心原理是通过自动配置和起步依赖简化项目搭建,配合嵌入式容器实现快速部署。在文学数字化领域,SpringBoot能够有效支持文本分析、情感计算等高阶需求,结合Elasticsearch等中间件可大幅提升全文检索性能。本文以琼瑶文学平台为例,展示了如何利用定制化情感分析算法和时代背景标注系统处理特色文学内容,其中Redis缓存和MySQL读写分离的架构设计有效应对了突发流量场景。这类

weixin_34152820的博客 465

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

springboot基于Spring Boot框架的文学名著分享系统的设计与实现

我是一名资深的高级程序员,在编程的世界里已深耕多年。对 Java 语言有着深入的理解和熟练的运用,无论是复杂的业务逻辑处理还是高效的性能优化,都能轻松驾驭。Spring Boot 框架是我手中的强大武器,凭借对其核心原理的透彻掌握,我能够快速构建出稳定、可靠且可扩展的后端应用。从项目的初始化到功能的逐步完善,我能精准地运用自动配置、起步依赖等特性,大大提高开发效率。

weixin_63671835的博客 694

StudyTonight Spring 中文教程(一)

Spring 是一个基于 Java 的应用框架,由 Pivotal 软件公司设计和开发。在本教程中,我们将讨论Spring 5,它是传统 Spring 框架的最新和更改进的版本。Spring 是一个用于创建企业应用的应用框架。由于其庞大的库和工具,我们可以轻松创建基于网络的应用。Spring 为创建 Java 企业应用提供了一个简单友好的环境。它是功能齐全的,并提供了其他各种子项目,如Spring MVC等,有助于相应地构建应用。

龙哥盟 1321

java毕业设计-基于springboot+vue的文学名著分享系统设计和实现,基于springboot的线上文学名著图书分享系统设计和实现(源码+LW+部署文档+远程调试+代码讲解等)

基于springboot+vue的文学名著分享系统设计和实现,基于springboot的线上文学名著图书分享系统设计和实现

项目帮 2089

【历代文学】Druid连接池实战:搞懂6个参数,就能用好它

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。Druid是一个开源项目,源码托管在github上,源代码仓库地址是:阿里巴巴的Druid是一个JDBC组件,它包含三部分:DruidDriver代理、DruidDataSource数据库连接池和SQLParser。Druid是阿里巴巴的开源项目,该项目主要是为了监控数据库连接池的性能指标,提供可视化的操作界面。Druid连接池的优点:可以监控数据库池的状态,包括池的状态及每个活动连接的详细状态。

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 3155

mybatis事物如何避免脏读_一文学懂MyBatis框架设计

多年以前猿小二刚刚进入程序猿的大军中,每天都在快乐的coding,那个时候经常要更数据打交道,所以编写很多JDBC的代码,动不动就得写JDBC六部曲。注册驱动获取Connection连接执行预编译执行SQL封装结果集释放资源越写越熟练,甚至有种自己写代码的功力有点超神的错觉;经过了一段时间的重复,猿小二意识到自己每天都在写重复的代码。而且,每次如果要更改sql语句或者配置...

weixin_39849762的博客 150

Java毕设项目推荐-基于Spring Boot+vue的文学名著分享系统的设计与实现【附源码+文档,调试定制服务】

Java毕设项目推荐-基于Spring Boot+vue的文学名著分享系统的设计与实现【附源码+文档,调试定制服务】

我的个人博客:https://bishe666.top 991

一文学会SpringBoot集成mybatis

spring boot连接Mysql 集成mybatis 了解什么是spring boot SpringBoot是Spring社区发布的一个开源项目,在帮助开发者快速并且更简单的构建项目 它使用习惯优于配置的理念让你的项目快速运行起来 使用Spring Boot很容易创建一个独立运行(运行jar,内置Servlet容器,Tomcat、jetty) 准生产级别的基于Spring框架的项目,使用S...

Cbuc丶的博客 479
上一篇: 读时加写锁,写时加读锁,Eureka可真的会玩
下一篇: spring的自动装配
java小姜在线冲
博客等级 码龄4年 53粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值