目录
如何配置数据源
Spring Boot 做了哪些配置
数据源相关配置属性
数据库连接池
HikariCP
Alibaba Druid
通过 Spring JDBC 访问数据库
了解 Spring 的抽象
Spring 的事务抽象
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(与前者对应)
配置多数据源的注意事项
不同数据源的配置要分开
关注每次使⽤用的数据源
有多个DataSource时系统如何判断
对应的设施(事务、ORM等)如何选择DataSource
Spring Boot中的多数据源配置
⼿工配置两组 DataSource 及相关内容
与Spring Boot协同工作(二选⼀)
配置@Primary类型的Bean
排除Spring Boot的⾃动配置
DataSourceAutoConfiguration
DataSourceTransactionManagerAutoConfiguration
JdbcTemplateAutoConfiguration
连接池选择时的考量量点
可靠性
性能
功能
可运维性
可扩展性
其他
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
“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=
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
core,JdbcTemplate 等相关核心接⼝和类
datasource,数据源相关的辅助类
object,将基本的 JDBC 操作封装成对象
support,错误码等其他辅助工具
简单的 JDBC 操作
JdbcTemplate
query
queryForObject
queryForList
update
execute
SQL 批处理
JdbcTemplate
batchUpdate
BatchPreparedStatementSetter
NamedParameterJdbcTemplate
batchUpdate
SqlParameterSourceUtils.createBatch
一致的事务模型
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
一些配置
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
CrudRepository
PagingAndSortingRepository
JpaRepository
定义查询
根据方法名
find...By... / read...By... / query...By... / get...By...
count...By...
...OrderBy...[Asc / Desc]
And / Or / IgnoreCase
Top / First / Distinct
分页查询
PagingAndSortingRepository
Pageable / Sort
Slice
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
• docker search
容器相关
• 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
PagingAndSortingRepository
CrudRepository
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 ⽅法增加缓存,缓存执行结果
• 支持ConcurrentMap、EhCache、Caffeine、JCache(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
• 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
@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进⾏日志输出
————————————————
版权声明:本文为CSDN博主「hp15」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/haponchang/article/details/93873924