Spring全家桶–数据库相关

  • Post author:
  • Post category:其他

目录

如何配置数据源 

Spring Boot 做了哪些配置 

数据源相关配置属性 

数据库连接池

HikariCP 

Alibaba Druid 

通过 Spring JDBC 访问数据库 

了解 Spring 的抽象 

Spring 的事务抽象 

Spring 的 JDBC 异常抽象 

O/R Mapping 实践 

常⽤的 Bean 注解 

认识 Spring Data JPA 

Hibernate 

Java Persistence API 

Spring Data 

常⽤ JPA 注解 

Project Lombok 

Spring Data JPA 的基本用法 

通过 MyBatis 操作数据库 

NoSQL 实践 

Docker 容器辅助开发

Spring Data MongoDB 的基本⽤法 

Spring Data Redis 的基本⽤法 

Redis 的几种运⾏模式

Spring 的缓存抽象 

Project Reactor

Project Reactor 介绍 

通过 Reactive 的⽅式访问 NoSQL 

通过 Reactive 的⽅式访问数据 RDBMS 

Spring AOP 的基本概念

监控 DAO 层的简单方案 


如何配置数据源 

Spring Boot 做了哪些配置 

DataSourceAutoConfiguration 配置 DataSource  

DataSourceTransactionManagerAutoConfiguration 配置 DataSourceTransactionManager  

JdbcTemplateAutoConfiguration 配置 JdbcTemplate 

 

数据源相关配置属性 

通⽤ 

  • spring.datasource.url=jdbc:mysql://localhost/test 
  • spring.datasource.username=dbuser
  • spring.datasource.password=dbpass 
  • spring.datasource.driver-class-name=com.mysql.jdbc.Driver(可选) 

初始化内嵌数据库 

  • spring.datasource.initialization-mode=embedded|always|never 
  • spring.datasource.schema与spring.datasource.data确定初始化SQL⽂文件 
  • spring.datasource.platform=hsqldb | h2 | oracle | mysql | postgresql(与前者对应) 

配置多数据源的注意事项 

  1. 不同数据源的配置要分开
  2. 关注每次使⽤用的数据源
  • 有多个DataSource时系统如何判断 
  • 对应的设施(事务、ORM等)如何选择DataSource 

Spring Boot中的多数据源配置 

⼿工配置两组 DataSource 及相关内容 

Spring Boot协同工作(二选⼀) 

  • 配置@Primary类型的Bean 
  • 排除Spring Boot的⾃动配置 
  • DataSourceAutoConfiguration 
  • DataSourceTransactionManagerAutoConfiguration 
  • JdbcTemplateAutoConfiguration 

 

数据库连接池

连接池选择时的考量量点 

  • 可靠性 
  • 性能  
  • 功能 
  • 可运维性 
  • 可扩展性  
  • 其他   

 

HikariCP 

HikariCP 为什么快 

1. 字节码级别优化(很多方法通过 JavaAssist 生成)

2. ⼤量小改进 

  • 用 FastStatementList 代替 ArrayList
  • 无锁集合 ConcurrentBag
  • 代理类的优化(⽐如,用 invokestatic 代替了 invokevirtual) 

 

Spring Boot 2.x 中 默认使⽤用 HikariCP

spring.datasource.hikari.*  

Spring Boot 1.x  默认使用 Tomcat 连接池,需要移除 tomcat-jdbc 依赖

  • spring.datasource.type=com.zaxxer.hikari.HikariDataSource 

 

常用 HikariCP 配置参数 

常用配置 

  • spring.datasource.hikari.maximumPoolSize=10 
  • spring.datasource.hikari.minimumIdle=10 
  • spring.datasource.hikari.idleTimeout=600000 
  • spring.datasource.hikari.connectionTimeout=30000 
  • spring.datasource.hikari.maxLifetime=1800000 

其他配置详见 HikariCP 官⽹网  

https://github.com/brettwooldridge/HikariCP 

 

Alibaba Druid 

“Druid连接池是阿⾥巴巴开源的数据库连接池项目。Druid连接池为监控⽽生, 内置强⼤的监控功能,监控特性不影响性能。功能强⼤大,能防SQL注⼊入,内置 Logging能诊断Hack应⽤行为。”                                          –Alibaba Druid 官⽅方介绍 

实⽤的功能

  • 详细的监控(真的是全面) 
  • ExceptionSorter,针对主流数据库的返回码都有支持 
  • SQL 防注⼊
  • 内置加密配置 众多扩展点,⽅便进行定制 

数据源配置 

直接配置 DruidDataSource 

通过 druid-spring-boot-starter 

  • spring.datasource.druid.* 

Filter 配置 

  • spring.datasource.druid.filters=stat,config,wall,log4j (全部使⽤用默认值) 

密码加密 

  • spring.datasource.password=<加密密码> 
  • spring.datasource.druid.filter.config.enabled=true 
  • spring.datasource.druid.connection-properties=config.decrypt=true;config.decrypt.key=<public-key> 

SQL 防注入 

  • spring.datasource.druid.filter.wall.enabled=true 
  • spring.datasource.druid.filter.wall.db-type=h2 
  • spring.datasource.druid.filter.wall.config.delete-allow=false
  • spring.datasource.druid.filter.wall.config.drop-table-allow=false 

Druid Filter 

  • 用于定制连接池操作的各种环节
  • 可以继承 FilterEventAdapter 以便便⽅方便便地实现 Filter 
  • 修改 META-INF/druid-filter.properties 增加 Filter 配置 

 

通过 Spring JDBC 访问数据库 

Spring JDBC 操作类 

spring-jdbc 

  • core,JdbcTemplate 等相关核心接⼝和类 
  • datasource,数据源相关的辅助类 
  • object,将基本的 JDBC 操作封装成对象 
  • support,错误码等其他辅助工具 

 

简单的 JDBC 操作 

JdbcTemplate 

  • query 
  • queryForObject 
  • queryForList 
  • update
  • execute 

 

SQL 批处理 

JdbcTemplate 

batchUpdate 

  • BatchPreparedStatementSetter 

NamedParameterJdbcTemplate 

batchUpdate 

  • SqlParameterSourceUtils.createBatch 

 

了解 Spring 的抽象 

Spring 的事务抽象 

一致的事务模型 

  • JDBC/Hibernate/myBatis 
  • DataSource/JTA 

 

事务抽象的核⼼接口 

PlatformTransactionManager 

• DataSourceTransactionManager 

• HibernateTransactionManager

• JtaTransactionManager 

TransactionDefinition 

• Propagation 

• Isolation

• Timeout 

• Read-only status 

 

事务传播特性 

传播性

描述

PROPAGATION_REQUIRED

0

当前有事务就⽤当前的,没有就⽤新的

PROPAGATION_SUPPORTS

1

事务可有可无,不是必须的

PROPAGATION_MANDATORY

2

当前一定要有事务,不然就抛异常

PROPAGATION_REQUIRES_NEW

3

⽆论是否有事务,都起个新的事务

PROPAGATION_NOT_SUPPORTED

4

不支持事务,按非事务⽅式运行

PROPAGATION_NEVER

5

不支持事务,如果有事务则抛异常

PROPAGATION_NESTED

6

当前有事务就在当前事务里里再起⼀个事务

 

事务隔离特性 

隔离性

脏读

不可重复读

幻读

ISOLATION_READ_UNCOMMITTED

1

ISOLATION_READ_COMMITTED

2

×

ISOLATION_REPEATABLE_READ

3

×

×

ISOLATION_SERIALIZABLE

4

×

×

×

 

编程式事务 

TransactionTemplate 

  • TransactionCallback 
  • TransactionCallbackWithoutResult 

PlatformTransactionManager 可以传⼊TransactionDefinition进行定义 

 

声明式事务 

基于注解的配置⽅方式 

开启事务注解的⽅方式 

  • @EnableTransactionManagement 
  • <tx:annotation-driven/> 

一些配置 

  • proxyTargetClass 
  • mode
  • order 

@Transactional 

  • transactionManager 
  • propagation 
  • isolation
  • timeout 
  • readOnly 
  • 怎么判断回滚 

 

Spring JDBC 异常抽象 

Spring 会将数据操作的异常转换为 DataAccessException ,无论使用何种数据访问⽅方式,都能使⽤一样的异常 

Spring 通过 SQLErrorCodeSQLExceptionTranslator 解析错误码 

ErrorCode 定义 

  • org/springframework/jdbc/support/sql-error-codes.xml 
  • Classpath 下的 sql-error-codes.xml 

错误码解析逻辑可定制

 

O/R Mapping 实践 

常⽤的 Bean 注解 

通过注解定义 Bean 

@Component 

@Repository 

@Service 

@Controller 

  • @RestController 

 

认识 Spring Data JPA 

对象与关系的范式不匹配 

 

Object

RDBMS

粒度

继承

没有

唯⼀性

a == b

a.equals(b)

主键

关联

引⽤用

外键

数据访问

逐级访问

SQL 数量要少

 

Hibernate 

一款开源的对象关系映射(Object / Relational Mapping)框架 

将开发者从 95% 的常⻅数据持久化⼯作中解放出来 

屏蔽了底层数据库的各种细节 

Hibernate 发展历程 

2001年,Gavin King 发布第⼀个版本 

2003年,Hibernate 开发团队加入 JBoss 

2006年,Hibernate 3.2 成为 JPA 实现 

 

Java Persistence API 

JPA 为对象关系映射提供了⼀种基于 POJO 的持久化模型 

  • 简化数据持久化代码的开发工作
  • 为 Java 社区屏蔽不不同持久化 API 的差异 

2006 年,JPA 1.0 作为 JSR 220 的⼀部分正式发布 

 

Spring Data 

在保留底层存储特性的同时,提供相对⼀致的、基于 Spring 的编程模型 

主要模块 

  • Spring Data Commons 
  • Spring Data JDBC 
  • Spring Data JPA 
  • Spring Data Redis ……

 

常⽤ JPA 注解 

实体 

  • @Entity、@MappedSuperclass 
  • @Table(name)

主键 

@Id 

  • @GeneratedValue(strategy, generator)
  • @SequenceGenerator(name, sequenceName)

映射 

  • @Column(name, nullable, length, insertable, updatable) 
  • @JoinTable(name)、@JoinColumn(name) 

关系  

  • @OneToOne、@OneToMany、@ManyToOne、@ManyToMany 
  • @OrderBy 

 

Project Lombok 

Project Lombok 能够⾃动嵌入 IDE 和构建工具,提升开发效率 

常用功能 

  • @Getter / @Setter
  • @ToString
  • @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor
  • @Data
  • @Builder
  • @Slf4j / @CommonsLog / @Log4j2

 

Spring Data JPA 的基本用法 

Repository 

@EnableJpaRepositories 

Repository<T, ID> 接口 

  • CrudRepository<T, ID>
  • PagingAndSortingRepository<T, ID>
  • JpaRepository<T, ID>

定义查询 

根据方法名

  • find…By… / read…By… / query…By… / get…By…
  • count…By…
  • …OrderBy…[Asc / Desc]
  • And / Or / IgnoreCase
  • Top / First / Distinct

分页查询 

  • PagingAndSortingRepository<T, ID>
  • Pageable / Sort
  • Slice<T> / Page<T>

Repository 是怎么从接口变成 Bean  

Repository Bean 是如何创建的 

JpaRepositoriesRegistrar 

  • 激活了 @EnableJpaRepositories
  • 返回了 JpaRepositoryConfigExtension 

RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions 

  • 注册 Repository Bean(类型是 JpaRepositoryFactoryBean ) 

RepositoryConfigurationExtensionSupport.getRepositoryConfigurations 

  • 取得 Repository 配置 

JpaRepositoryFactory.getTargetRepository 

  • 创建了 Repository 

接⼝中的⽅法是如何被解释的

RepositoryFactorySupport.getRepository 添加了Advice 

  • DefaultMethodInvokingMethodInterceptor
  • QueryExecutorMethodInterceptor

AbstractJpaQuery.execute 执行具体的查询 

语法解析在 Part  

 

通过 MyBatis 操作数据库 

认识 MyBatis 

MyBatis(https://github.com/mybatis/mybatis-3) 

  • 一款优秀的持久层框架
  • 支持定制化 SQL、存储过程和高级映射 

 

Spring 中使⽤用 MyBatis 

  • MyBatis Spring Adapter(https://github.com/mybatis/spring)
  • MyBatis Spring-Boot-Starter(https://github.com/mybatis/spring-boot-starter)  

简单配置 

  • mybatis.mapper-locations = classpath*:mapper/**/*.xml 
  • mybatis.type-aliases-package = 类型别名的包名 
  • mybatis.type-handlers-package = TypeHandler扫描包名 
  • mybatis.configuration.map-underscore-to-camel-case = true 

Mapper 的定义与扫描 

@MapperScan 配置扫描位置 

@Mapper 定义接⼝ 映射的定义—— XML 与注解 

 

MyBatis 更好用的那些⼯具 MyBatis Generator 

认识 MyBatis Generator 

MyBatis Generator(http://www.mybatis.org/generator/) 

MyBatis 代码生成器 

根据数据库表生成相关代码 

  • POJO 
  • Mapper 接⼝
  • SQL Map XML 

 

运⾏ MyBatis Generator 

命令⾏

 java -jar mybatis-generator-core-x.x.x.jar -configfile generatorConfig.xml 

Maven Plugin(mybatis-generator-maven-plugin) 

mvn mybatis-generator:generate 

${basedir}/src/main/resources/generatorConfig.xml 

Eclipse Plugin 

Java 程序
Ant Task 

配置 MyBatis Generator 

generatorConfiguration 

context 

  • jdbcConnection
  • javaModelGenerator
  • sqlMapGenerator
  • javaClientGenerator (ANNOTATEDMAPPER / XMLMAPPER / MIXEDMAPPER) 
  • table 

 

⽣成时可以使用的插件 

内置插件都在 org.mybatis.generator.plugins 包中 

  • FluentBuilderMethodsPlugin
  • ToStringPlugin
  • SerializablePlugin
  • RowBoundsPlugin
  • …… 
  •  

使用⽣成的对象 

  • 简单操作,直接使⽤生成的 xxxMapper 的⽅法 
  • 复杂查询,使⽤生成的 xxxExample 对象 

 

MyBatis 更好用的那些⼯具 —MyBatis PageHelper 

认识 MyBatis PageHelper 

MyBatis PageHepler(https://pagehelper.github.io) 

  • 支持多种数据库 
  • 支持多种分⻚方式 
  • SpringBoot 支持(https://github.com/pagehelper/pagehelper-spring-boot ) 
    • pagehelper-spring-boot-starter 

 

NoSQL 实践 

Docker 容器辅助开发

优点:简化了重复搭建开发环境的工作、交付系统更更为流畅、伸缩性更更好。

在本地的基本⽤法:

镜像相关 

• docker pull <image>

• docker search <image>

容器相关 

• docker run

• docker start/stop <容器器名> 

• docker ps <容器器名> 

• docker logs <容器器名> 

docker run 的常⽤用选项 

docker run [OPTIONS] IMAGE [COMMAND] [ARG…] 

选项说明 

  • -d,后台运行容器 
  • -e,设置环境变量量
  • –expose / -p 宿主端口:容器端口 
  • –name,指定容器名称 
  • –link,链接不同容器
  • -v 宿主目录:容器⽬录,挂载磁盘卷 

 

国内 Docker 镜像配置 

官⽅ Docker Hub 

• https://hub.docker.com 

官⽅方镜像 

• 镜像 https://www.docker-cn.com/registry-mirror 

• 下载 https://www.docker-cn.com/get-docker  

阿⾥里里云镜像 

https://dev.aliyun.com 

 

Docker 常⽤命令

通过 Docker 启动 MongoDB 

官⽅指引 

• https://hub.docker.com/_/mongo 

获取镜像 

• docker pull mongo

运行 MongoDB 镜像 

• docker run –name mongo -p 27017:27017 -v ~/docker-

data/mongo:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin

-e MONGO_INITDB_ROOT_PASSWORD=admin -d mongo

 

通过 Docker 启动 MongoDB 

登录到 MongoDB 容器中 

• docker exec -it mongo bash

通过 Shell 连接 MongoDB 

• mongo -u admin -p admin

 

Spring Data MongoDB 的基本⽤法 

Spring 中访问 MongoDB 

Spring MongoDB 的支持 

MongoDB 是一款开源的文档型数据库 

• https://www.mongodb.com 

Spring MongoDB 的支持 

Spring Data MongoDB 

  • MongoTemplate 
  • Repository ⽀持 

 

Spring Data MongoDB 的基本⽤用法 

注解 

  • @Document 
  • @Id 

MongoTemplate 

  • save / remove
  • Criteria / Query / Update

 

初始化 MongoDB 的库及权限 创建库 

  use springTest;

创建⽤用户 

  db.createUser(

    {

      user: “test”,

      pwd: “test”,

      roles: [

         { role: “readWrite”, db: “springTest” }

      ]

} ) 

 

Spring Data MongoDB Repository 

@EnableMongoRepositories 

对应接口 

  • MongoRepository<T, ID>
  • PagingAndSortingRepository<T, ID>
  • CrudRepository<T, ID>

 

Spring Data Redis 的基本⽤法 

Spring 中访问 Redis 

Spring 对 Redis 的⽀持 Redis 是⼀一款开源的内存 KV 存储,⽀支持多种数据结构 

• https://redis.io

Spring Redis 的支持 

• Spring Data Redis 

  • 支持的客户端 Jedis / Lettuce 
  • RedisTemplate
  • Repository ⽀支持 

 

Jedis 客户端的简单使⽤ 

  • Jedis 不是线程安全的
  • 通过 JedisPool 获得 Jedis 实例
  • 直接使⽤用 Jedis 中的⽅方法 

 

Jedis 客户端的简单使用 

通过 Docker 启动 Redis 

官⽅指引 

• https://hub.docker.com/_/redis 

获取镜像 

• docker pull redis

启动 Redis 

• docker run –name redis -d -p 6379:6379 redis

 

Redis 的几种运⾏模式

Redis 的哨兵与集群模式 

Redis 的哨兵模式 Redis Sentinel Redis 的一种⾼可用方案 

• 监控、通知、⾃自动故障转移、服务发现

JedisSentinelPool 

 

Redis 的集群模式 

Redis Cluster 

  • 数据自动分片(分成16384个 Hash Slot ) 
  • 在部分节点失效时有⼀一定可⽤用性

JedisCluster 

• Jedis 只从 Master 读数据,如果想要⾃自动读写分离,可以定制 

 

Spring 的缓存抽象 

为不同的缓存提供一层抽象

Java ⽅法增加缓存,缓存执行结果 

支持ConcurrentMapEhCacheCaffeineJCache(JSR-107) 

接⼝

  • org.springframework.cache.Cache
  • org.springframework.cache.CacheManager

 

基于注解的缓存 

@EnableCaching 

  • @Cacheable
  • @CacheEvict
  • @CachePut
  • @Caching
  • @CacheConfig

 

通过 Spring Boot 配置 Redis 缓存 

Redis Spring 中的其他用法 

 

Redis 建立连接

配置连接⼯厂 

•  LettuceConnectionFactory JedisConnectionFactory 

  • RedisStandaloneConfiguration
  • RedisSentinelConfiguration
  • RedisClusterConfiguration

 

读写分离 

Lettuce 内置支持读写分离 

  • 只读主、只读从 
  • 优先读主、优先读从 

LettuceClientConfiguration

LettucePoolingClientConfiguration

LettuceClientConfigurationBuilderCustomizer

 

RedisTemplate 

RedisTemplate<K, V>

• opsForXxx() 

StringRedisTemplate 

一定注意设置过期时间!!!

 

Redis Repository 

实体注解 

  • @RedisHash
  • @Id
  • @Indexed

 

处理不同类型数据源的 Repository 

如何区分这些 Repository 

  • 根据实体的注解
  • 根据继承的接⼝类型
  • 扫描不同的包

 

Project Reactor

Project Reactor 介绍 

“在计算机中,响应式编程或反应式编程(英语:Reactive Programming)是一种面向数据流和变化传播的编程范式。这意味着可以在编程语⾔中很⽅便地表达静态或动态的数据流, ⽽相关的计算模型会自动将变化的值通过数据流进⾏传播。” 

——维基百科 

 

Project Reactor ⼀些核⼼的概念 

Operators – Publisher / Subscriber 

• Nothing Happens Until You subscribe()

• Flux [ 0..N ] – onNext()、onComplete()、onError() 

• Mono [ 0..1 ] – onNext()、onComplete()、onError() 

Backpressure 

• Subscription 

• onRequest()、onCancel()、onDispose() 

线程调度 Schedulers 

• immediate() / single() / newSingle()

• elastic() / parallel() / newParallel()

错误处理

• onError / onErrorReturn / onErrorResume 

• doOnError / doFinally 

 

通过 Reactive 的⽅式访问 NoSQL 

通过 Reactive 的⽅式访问数据 Redis 

Spring Data Redis 

Lettuce 能够支持 Reactive ⽅式 

Spring Data Redis 中主要的支持 

• ReactiveRedisConnection

• ReactiveRedisConnectionFactory

• ReactiveRedisTemplate

  • opsForXxx() 

 

通过 Reactive 的⽅式访问数据 MongoDB 

Spring Data MongoDB 

MongoDB 官⽅提供了⽀持 Reactive 的驱动 

• mongodb-driver-reactivestreams 

Spring Data MongoDB 中主要的⽀支持 

• ReactiveMongoClientFactoryBean

• ReactiveMongoDatabaseFactory

• ReactiveMongoTemplate

 

通过 Reactive 的⽅式访问数据 RDBMS 

Spring Data R2DBC 

R2DBC (https://spring.io/projects/spring-data-r2dbc) 

• Reactive Relational Database Connectivity 

支持的数据库 

• Postgres(io.r2dbc:r2dbc-postgresql) 

• H2(io.r2dbc:r2dbc-h2)
• Microsoft SQL Server(io.r2dbc:r2dbc-mssql) 

 

Spring Data R2DBC 

  一些主要的类 

• ConnectionFactory

• DatabaseClient

  • execute().sql(SQL)
  • inTransaction(db -> {}) 

• R2dbcExceptionTranslator 

  • SqlErrorCodeR2dbcExceptionTranslator

 

R2DBC Repository 支持 

一些主要的类 

• @EnableR2dbcRepositories 

• ReactiveCrudRepository<T, ID>

  • @Table / @Id 
  • 其中的方法返回都是 Mono 或者 Flux 
  • 自定义查询需要⾃己写 @Query 

 

Spring AOP 的基本概念

通过 AOP 打印数据访问层摘要 

Spring AOP 的⼀些核心概念 

概念

含义

Aspect

切面

Join Point

连接点,Spring AOP里总是代表一次⽅法行行

Advice

通知,在连接点执行的动作

Pointcut

切入点,说明如何匹配连接点

Introduction

引入,为现有类型声明额外的⽅法和属性

Target object

⽬标对象

AOP proxy

AOP 代理对象,可以是 JDK 动态代理,也可以是 CGLIB 代理

Weaving

织入,连接切面与⽬标对象或类型创建代理的过程

常用注解 

  • @EnableAspectJAutoProxy
  • @Aspect
  • @Pointcut
  • @Before
  • @After / @AfterReturning / @AfterThrowing
  • @Around
  • @Order

 

监控 DAO 层的简单方案 

  • 如何打印 SQL 
     

HikariCP 

• P6SQL,https://github.com/p6spy/p6spy 

 

Alibaba Druid 

• 内置 SQL 输出 

• https://github.com/alibaba/druid/wiki/Druid中使用log4j2进⾏日志输出 


版权声明:本文为haponchang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。