目录
如何配置数据源
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 层的简单方案
DataSourceAutoConfiguration 配置 DataSource
DataSourceTransactionManagerAutoConfiguration 配置 DataSourceTransactionManager
JdbcTemplateAutoConfiguration 配置 JdbcTemplate
通⽤
初始化内嵌数据库
配置多数据源的注意事项
Spring Boot中的多数据源配置
⼿工配置两组 DataSource 及相关内容
与Spring Boot协同工作(二选⼀)
连接池选择时的考量量点
HikariCP 为什么快
1. 字节码级别优化(很多方法通过 JavaAssist 生成)
2. ⼤量小改进
在 Spring Boot 2.x 中 默认使⽤用 HikariCP
spring.datasource.hikari.*
Spring Boot 1.x 默认使用 Tomcat 连接池,需要移除 tomcat-jdbc 依赖
常用 HikariCP 配置参数
常用配置
其他配置详见 HikariCP 官⽹网
https://github.com/brettwooldridge/HikariCP
“Druid连接池是阿⾥巴巴开源的数据库连接池项目。Druid连接池为监控⽽生, 内置强⼤的监控功能,监控特性不影响性能。功能强⼤大,能防SQL注⼊入,内置 Logging能诊断Hack应⽤行为。” –Alibaba Druid 官⽅方介绍
实⽤的功能
数据源配置
直接配置 DruidDataSource
通过 druid-spring-boot-starter
Filter 配置
密码加密
SQL 防注入
Druid Filter
Spring 的 JDBC 操作类
spring-jdbc
简单的 JDBC 操作
JdbcTemplate
SQL 批处理
JdbcTemplate
batchUpdate
NamedParameterJdbcTemplate
batchUpdate
一致的事务模型
事务抽象的核⼼接口
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
PlatformTransactionManager 可以传⼊TransactionDefinition进行定义
声明式事务
基于注解的配置⽅方式
开启事务注解的⽅方式
一些配置
@Transactional
Spring 会将数据操作的异常转换为 DataAccessException ,无论使用何种数据访问⽅方式,都能使⽤一样的异常
Spring 通过 SQLErrorCodeSQLExceptionTranslator 解析错误码
ErrorCode 定义
错误码解析逻辑可定制
通过注解定义 Bean
@Component
@Repository
@Service
@Controller
对象与关系的范式不匹配
|
Object |
RDBMS |
粒度 |
类 |
表 |
继承 |
有 |
没有 |
唯⼀性 |
a == b a.equals(b) |
主键 |
关联 |
引⽤用 |
外键 |
数据访问 |
逐级访问 |
SQL 数量要少 |
一款开源的对象关系映射(Object / Relational Mapping)框架
将开发者从 95% 的常⻅数据持久化⼯作中解放出来
屏蔽了底层数据库的各种细节
Hibernate 发展历程
2001年,Gavin King 发布第⼀个版本
2003年,Hibernate 开发团队加入 JBoss
2006年,Hibernate 3.2 成为 JPA 实现
JPA 为对象关系映射提供了⼀种基于 POJO 的持久化模型
2006 年,JPA 1.0 作为 JSR 220 的⼀部分正式发布
在保留底层存储特性的同时,提供相对⼀致的、基于 Spring 的编程模型
主要模块
实体
主键
@Id
映射
关系
Project Lombok 能够⾃动嵌入 IDE 和构建工具,提升开发效率
常用功能
@EnableJpaRepositories
Repository
根据方法名
Repository Bean 是如何创建的
JpaRepositoriesRegistrar
RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions
RepositoryConfigurationExtensionSupport.getRepositoryConfigurations
JpaRepositoryFactory.getTargetRepository
接⼝中的⽅法是如何被解释的
RepositoryFactorySupport.getRepository 添加了Advice
AbstractJpaQuery.execute 执行具体的查询
语法解析在 Part 中
MyBatis(https://github.com/mybatis/mybatis-3)
简单配置
Mapper 的定义与扫描
@MapperScan 配置扫描位置
@Mapper 定义接⼝ 映射的定义—— XML 与注解
认识 MyBatis Generator
MyBatis Generator(http://www.mybatis.org/generator/)
MyBatis 代码生成器
根据数据库表生成相关代码
运⾏ 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
⽣成时可以使用的插件
内置插件都在 org.mybatis.generator.plugins 包中
使用⽣成的对象
认识 MyBatis PageHelper
MyBatis PageHepler(https://pagehelper.github.io)
优点:简化了重复搭建开发环境的工作、交付系统更更为流畅、伸缩性更更好。
在本地的基本⽤法:
镜像相关
• docker pull
• docker search
容器相关
• docker run
• docker start/stop <容器器名>
• docker ps <容器器名>
• docker logs <容器器名>
docker run 的常⽤用选项
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
选项说明
国内 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 中访问 MongoDB
Spring 对 MongoDB 的支持
MongoDB 是一款开源的文档型数据库
• https://www.mongodb.com
Spring 对 MongoDB 的支持
Spring Data MongoDB
Spring Data MongoDB 的基本⽤用法
注解
MongoTemplate
初始化 MongoDB 的库及权限 创建库
use springTest;
创建⽤用户
db.createUser(
{
user: "test",
pwd: "test",
roles: [
{ role: "readWrite", db: "springTest" }
]
} )
Spring Data MongoDB 的 Repository
@EnableMongoRepositories
对应接口
在 Spring 中访问 Redis
Spring 对 Redis 的⽀持 Redis 是⼀一款开源的内存 KV 存储,⽀支持多种数据结构
• https://redis.io
Spring 对 Redis 的支持
• Spring Data Redis
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 Sentinel 是 Redis 的一种⾼可用方案
• 监控、通知、⾃自动故障转移、服务发现
JedisSentinelPool
Redis 的集群模式
Redis Cluster
JedisCluster
• Jedis 只从 Master 读数据,如果想要⾃自动读写分离,可以定制
为不同的缓存提供一层抽象
• 为 Java ⽅法增加缓存,缓存执行结果
• 支持ConcurrentMap、EhCache、Caffeine、JCache(JSR-107)
• 接⼝
基于注解的缓存
@EnableCaching
通过 Spring Boot 配置 Redis 缓存
Redis 在 Spring 中的其他用法
与 Redis 建立连接
配置连接⼯厂
• LettuceConnectionFactory 与 JedisConnectionFactory
读写分离
Lettuce 内置支持读写分离
LettuceClientConfiguration
LettucePoolingClientConfiguration
LettuceClientConfigurationBuilderCustomizer
RedisTemplate
RedisTemplate
• opsForXxx()
StringRedisTemplate
一定注意设置过期时间!!!
Redis Repository
实体注解
处理不同类型数据源的 Repository
如何区分这些 Repository
“在计算机中,响应式编程或反应式编程(英语: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 的⽅式访问数据 Redis
Spring Data Redis
Lettuce 能够支持 Reactive ⽅式
Spring Data Redis 中主要的支持
• ReactiveRedisConnection
• ReactiveRedisConnectionFactory
• ReactiveRedisTemplate
通过 Reactive 的⽅式访问数据 MongoDB
Spring Data MongoDB
MongoDB 官⽅提供了⽀持 Reactive 的驱动
• mongodb-driver-reactivestreams
Spring Data MongoDB 中主要的⽀支持
• ReactiveMongoClientFactoryBean
• ReactiveMongoDatabaseFactory
• ReactiveMongoTemplate
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
• R2dbcExceptionTranslator
R2DBC Repository 支持
一些主要的类
• @EnableR2dbcRepositories
• ReactiveCrudRepository
通过 AOP 打印数据访问层摘要
Spring AOP 的⼀些核心概念
概念 |
含义 |
Aspect |
切面 |
Join Point |
连接点,Spring AOP里总是代表一次⽅法行行 |
Advice |
通知,在连接点执行的动作 |
Pointcut |
切入点,说明如何匹配连接点 |
Introduction |
引入,为现有类型声明额外的⽅法和属性 |
Target object |
⽬标对象 |
AOP proxy |
AOP 代理对象,可以是 JDK 动态代理,也可以是 CGLIB 代理 |
Weaving |
织入,连接切面与⽬标对象或类型创建代理的过程 |
常用注解
HikariCP
• P6SQL,https://github.com/p6spy/p6spy
Alibaba Druid
• 内置 SQL 输出
• https://github.com/alibaba/druid/wiki/Druid中使用log4j2进⾏日志输出