Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part A JDBC)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part A JDBC)

一、Spring Boot Data Access

Spring Boot默认使用Spring Data对SQL和NoSQL进行统一的访问处理,并添加了自动大量的自动配置,引入XxxTemplate如JdbcTemplate、RedisTemplate以及XxxRepository如JpaRepository、CrudRepository等来简化对数据访问层的操作,只需要进行简单的配置即可实现。

Spring Data的模块划分,查看官网

1a89113ae254430cb65538b49f49aa44_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.

It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services.

Spring Data的使命是为数据访问提供熟悉且一致的基于Spring的编程模型,同时仍保留底层数据存储的特殊特性。使数据访问技术,关系数据库和非关系数据库,map-reduce框架和基于云的数据服务变得简单易用。

Spring Boot 中关于 Spring Data的starters

cd564a0897ad412fb545988562bd23ab_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

二、Integrate Spring Data JDBC

Spring Boot 默认数据源

创建项目spring-boot-data,引入JDBC依赖和MySQL依赖

68a81f3247164c7aac19d0f9adc7c81b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

在application.yml配置文件中增加数据库连接配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost.com:3306/test
复制代码

在test包下的DataApplicationTests类中增加测试方法testGetConnection(),测试获取数据源

@SpringBootTest
public class DataApplicationTests {
    @Autowired
    private DataSource dataSource;
    @Test
    public void testGetConnection() throws SQLException {
        System.out.println("数据源类型为:" + dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println("获取到到数据库连接为:" + connection);
        connection.close();
    }
}
复制代码

执行测试

b860457b80b34e11b5fa200db9a008fb_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

成功获取到HikarPool数据源。

自动配置原理

数据源相关的配置都在DataSourceProperties类中。数据源的自动配置类是 org.springframework.boot.autoconfigure.jdbc DataSourceAutoConfiguration

Spring Boot默认支持的数据源有

  • com.zaxxer.hikari.HikariDataSource
  • org.apache.tomcat.jdbc.pool.DataSource
  • org.apache.commons.dbcp2.BasicDataSource
  • oracle.ucp.jdbc.PoolDataSource

911f4cf2246948db9d3e5c2c7ad336bb_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

DataSourceConfiguration类可以根据配置创建以上数据源,配置spring.datasource.type指定数据源,默认的数据源为HikariDataSource,如果配置的数据源不是以上这些数据源,则会通过Generic静态类的dataSource方法往容器中注入自定义的数据源。

8ff6bee8ed9c4a2d9d075fa25e1161a3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

源码中initializeDataSourceBuilder方法返回一个DataSourceBuilder

e59f886e8f1c4896a31a7b0bbc61851b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

而DataSourceBuilder的builder方法通过反射创建出数据源,并将自定义数据源的properties属性和数据源进行绑定

e2def288331c4338a9ade5384705bf21_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

DataSourceInitializer初始化数据

Spring Boot支持在应用启动时初始化数据。

首先创建一个自定义的DataSourceInitializerConfig类,该类是一个配置类需要标注@Configuration标签,需要通过该配置类往容器中导入一个绑定了数据源和SQL脚本的DataSourceInitializer初始化类。

@Configuration
public class LilithDataSourceInitializerConfig {
    @Value("classpath:porsche.sql")
    private Resource script;
    @Bean
    public DataSourceInitializer dataSourceInitializer(final DataSource dataSource){
        final DataSourceInitializer initializer = new DataSourceInitializer();
        initializer.setDataSource(dataSource);
        initializer.setDatabasePopulator(databasePopulator());
        return initializer;
    }
    private DatabasePopulator databasePopulator(){
        final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScripts(script);
        //populator.setSeparator("$$");
        return populator;
    }
}
复制代码

在resource目录下放置porsche.sql

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for porsche
-- ----------------------------
DROP TABLE IF EXISTS `porsche`;
CREATE TABLE `porsche` (
  `por_id` int(11) NOT NULL AUTO_INCREMENT,
  `por_name` char(100) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci DEFAULT NULL,
  `por_price` double DEFAULT NULL,
  `por_stock` int(11) DEFAULT NULL,
  PRIMARY KEY (`por_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=gb2312;
-- ----------------------------
-- Records of porsche
-- ----------------------------
BEGIN;
INSERT INTO `porsche` VALUES (2, 'Cayenne', 910000, 30);
INSERT INTO `porsche` VALUES (3, 'Macan', 550000, 40);
INSERT INTO `porsche` VALUES (4, 'Taycay 2022', 880000, 50);
INSERT INTO `porsche` VALUES (5, 'Porsche 911', 1270000, 40);
INSERT INTO `porsche` VALUES (6, 'Porsche 718', 540000, 70);
INSERT INTO `porsche` VALUES (7, '918 Spyder', 13380000, 10);
INSERT INTO `porsche` VALUES (8, 'Cayman', 720000, 30);
INSERT INTO `porsche` VALUES (9, 'Boxster', 670000, 110);
INSERT INTO `porsche` VALUES (10, 'Carrera GT', 6450000, 20);
INSERT INTO `porsche` VALUES (11, 'Taycan Tubo S', 880000, 140);
INSERT INTO `porsche` VALUES (12, 'Taycan 2023', 880000, 120);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
复制代码

启动主程序,通过查看数据库可以确定程序启动时自动执行了指定的SQL脚本,需要注意的是每次程序启动都会重新初始化数据库,如果不想这样只需要将@Configuration注解注释即可。

测试初始化数据

Spring Boot数据源自动配置了JdbcTemplate,可以使用JdbcTemplate访问数据库

b4c269a7859346469ecee6429e2bac69_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

@Data
public class Porsche {
    private Integer porId;
    private String porName;
    private Double porPrice;
    private Integer porStock;
}
复制代码

增加PorscheMapper类,新增selectAll方法

@Component
public class PorscheMapper {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public List<Map<String, Object>> selectAll(){
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("SELECT * FROM porsche");
        return maps;
    }
}
复制代码

在test包下增加PorscheMapperTest测试类

@SpringBootTest
public class PorscheMapperTest {
    @Autowired
    private PorscheMapper porscheMapper;
    @Test
    public void selectAll() {
        List<Map<String, Object>> maps = porscheMapper.selectAll();
        for (Map<String, Object> map : maps) {
            System.out.println(map);
        }
    }
}
复制代码

执行测试

c933bf5d4acc4d25917e702b5dc5d576_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

可以成功查出所有的数据

三、第三方数据源

Druid数据源配置

druid拥有成套的解决方案,如监控等,如何配置使用Druid数据源?

首先在pom文件中添加druid Staters

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>
复制代码

执行testGetConnection

a1fec1db018645cabea9b1f4285bc6e1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

debug查看设置的属性有没有生效

696627f8a0df4d87a770e12d73ee70b1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

druid 配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/test
    druid:
      # 初始化大小,最小,最大
      initial-size: 5
      max-active: 100
      min-idle: 1
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存时间
      min-evictable-idle-time-millis: 300000
      # 用来检测连接是否有效的sql 必须是一个查询语句 注意没有此语句以下三个属性不会生效
      validation-query: SELECT 1 FROM DUAL
      # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
      test-on-return: false
      # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
      test-on-borrow: true
      # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
      test-while-idle: true
      # 配置监控统计拦截的 Filter,去掉后监控界面 SQL 无法统计,wall 用于防火墙
      filters: stat,wall
      # 通过 connection-properties 属性打开 mergeSql 功能;慢 SQL 记录
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 配置 DruidStatFilter
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
      # 配置 DruidStatViewServlet
      stat-view-servlet:
        url-pattern: /druid/*
        # IP 白名单,没有配置或者为空,则允许所有访问
        #allow: 127.0.0.1
        # IP 黑名单,若白名单也存在,则优先使用
        #deny: 192.168.31.253
        # 禁用 HTML 中 Reset All 按钮
        reset-enable: true
        # 登录用户名/密码
        login-username: root
        login-password: 123
        # 注意 此处必须开启,否则无法访问druid监控面板
        enabled: true
      use-global-data-source-stat: true
复制代码

Druid自动配置原理

com.alibaba.druid.spring.boot.autoconfigure包中包含了Druid的自动配置类DruidDataSourceAutoConfigure

59a629c1ab5d4dd9904767c645282968_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

该自动配置类启用了DataSourceProperties和DruidStatProperties配置类中的配置

image.png

durid所有配置都是以spring.datasource或者spring.datasource.druid开头,这两个配置类中包含了druid在properties配置文件或者yml配置文件中的配置项

Druid 监控

输入地址 http://localhost:8080/druid/index.html 会显示登录界面,输入设置的用户名密码即可进入监控界面

image.png

新建controller包,增加PorscheController

@RestController
public class PorscheController {
    @Autowired
    private PorscheMapper porscheMapper;
    @GetMapping("/porsche")
    public Map<String,Object> query(){
        List<Map<String, Object>> maps = porscheMapper.selectAll();
        return maps.get(0);
    }
}
复制代码

浏览器输入 http://localhost:8080/porsche,页面显示出查询到的信息

image.png

查看Druid的SQL监控界面

image.png

plus:执行test包下的测试类执行的SQL不会被druid监控


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
6天前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
98 3
|
28天前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
561 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
存储 JSON Java
279 0
|
1月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
|
6月前
|
前端开发 Java Maven
Spring 和 Spring Boot 之间的比较
本文对比了标准Spring框架与Spring Boot的区别,重点分析两者在模块使用(如MVC、Security)上的差异。Spring提供全面的Java开发基础设施支持,包含依赖注入和多种开箱即用的模块;而Spring Boot作为Spring的扩展,通过自动配置、嵌入式服务器等功能简化开发流程。文章还探讨了两者的Maven依赖、Mvc配置、模板引擎配置、启动方式及打包部署等方面的异同,展示了Spring Boot如何通过减少样板代码和配置提升开发效率。总结指出,Spring Boot是Spring的增强版,使应用开发、测试与部署更加便捷高效。
801 12
|
7月前
|
Java 数据库连接
【YashanDB知识库】Springboot启动找不到崖山jdbc驱动的问题处理
本文来自YashanDB官网,主要解决SpringBoot应用启动时出现“找不到崖山JDBC驱动”的问题,尽管lib目录下已有yashandb-jdbc-1.6.9.jar文件。错误信息显示`java.lang.ClassNotFoundException: com.yashandb.jdbc.Driver`。解决方案为:通过`which java`等命令定位Java安装路径,将驱动jar包复制到JRE的`lib/ext`目录下,最后重启应用即可。
|
7月前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
349 0
|
7月前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
267 0
|
7月前
|
消息中间件 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——发布/订阅消息的生产和消费
本文详细讲解了Spring Boot中ActiveMQ的发布/订阅消息机制,包括消息生产和消费的具体实现方式。生产端通过`sendMessage`方法发送订阅消息,消费端则需配置`application.yml`或自定义工厂以支持topic消息监听。为解决点对点与发布/订阅消息兼容问题,可通过设置`containerFactory`实现两者共存。最后,文章还提供了测试方法及总结,帮助读者掌握ActiveMQ在异步消息处理中的应用。
313 0