Spring数据访问1 - 数据源配置及数据库连接池的概念
无论你要选择哪种数据访问方式,首先你都需要配置好数据源引用。
Spring中配置数据源的几种方式
- 通过在JDBC驱动程序定义的数据源;
- 通过JNDI查找的数据源;
- 连接池的数据源;
对于即将发布到生产环境中的应用程序, 建议使用从连接池获取连接的数据源。 可能的话, 倾向于通过应用服务器的JNDI来获取数据源。
使用JNDI数据源
Spring应用程序经常部署在Java EE应用服务器中,例如Tomcat、JBoss。这些服务器器允许你通过配置获取数据源,这样做的好处是数据源可以在应用之外进行管理。另外,在应用服务器中数据源通常都是以连接池的方式组织,从而具备更好的性能,并且还支持系统管理员对其进行热切换。
对于Tomcat需要在tomcat/conf/context.xml中配置好连接信息,其中name指的是JNDI的名称
<Resource auth="Container"
driverClassName="oracle.jdbc.driver.OracleDriver"
name="jdbc/dev"
password="dev"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@127.0.0.1:1521/orcl"
username="dev"/>
对于Sping应用来说需要手动配置数据源Bean
@Bean
public JndiObjectFactoryBean dataSource() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/dev");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return jndiObjectFactoryBean;
}
Spring Boot中帮我们自动配置好了,只需要在application.properties中声明指定jndiName就可以了。
spring.datasource.jndi-name=java:comp/env/jdbc/dev
// 或者是
spring.datasource.jndi-name=jdbc/dev
因为Spring boot自带web容器,因此JNDI方式只适用于将war发布到独立的web容器启动的方式。
使用连接池的数据源
啥是连接池?
数据库连接池是web容器(比如Tomcat)提供的一个数据库连接管理的容器,连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。
为什么要用它?
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。 一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并将这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库连接对象),由应用程序动态地对池中的连接进行申请、使用和释放。对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。 连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
在Spring Boot中怎么用?
配置连接池参数
- 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
- 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
- 最大空闲时间: 超出这个时间,该连接将被销毁
- 获取连接超时时间: 超出时间程序将会返回连接超时异常
- 超时重试连接次数: 超时后重新连接的次数
Spring Boot2.0默认使用HikariCP连接池管理数据源

HikariCP的特点是快,字节码级别优化(很多⽅法通过 JavaAssist ⽣成),⼤量⼩改进
常用HkariCP配置
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
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
更多配置去官网https://github.com/brettwooldridge/HikariCP
这样就搞定了,Spring Boot帮我们把数据源创建、事务管理、JdbcTemplate创建都搞定了。
Alibaba Druid 连接池(https://github.com/alibaba/druid)
Druid连接池是阿⾥巴巴开源的数据库连接池项⽬。 Druid连接池为监控而生,内置强⼤的监控功能,监控特性不影响性能。功能强⼤,能防SQL注⼊,内置Logging能诊断Hack应⽤⾏为。
实用的功能
• 详细的监控(真的是全⾯)
 
• ExceptionSorter,针对主流数据库的返回码都有⽀持
 
• SQL 防注⼊
 
• 内置加密配置
 
• 众多扩展点,⽅便进⾏定制
Spring Boot中通过druid-spring-boot-starter来引入druid, spring.datasource.druid.* 来配置相关参数,如下

Durid通过Filter来扩展和定制连接池操作的细节
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  // 是否允许执行delete
• spring.datasource.druid.filter.wall.config.drop-table-allow=false // 是否允许执行drop table
实现Filter
• 可以继承 FilterEventAdapter 以便⽅便地实现 Filter
• 修改 META-INF/druid-filter.properties 增加 Filter 配置
在数据库连接建立前后打印日志的例子:

多数据源配置
在Sring boot中配置多数据源需要写多套配置,例如创建两个数据源
foo.datasource.url=jdbc:h2:mem:foo
foo.datasource.username=sa
foo.datasource.password= bar.datasource.url=jdbc:h2:mem:bar
bar.datasource.username=sa
bar.datasource.password=
分别用Java Config 为不同的配置创建数据源Bean。
首先让Spring boot取消自动配置
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        JdbcTemplateAutoConfiguration.class})
然后手动配置DataSource和TransactionManager,@Primary注解指明当有两个类实现同一接口的时候该采用哪个实现类进行@Autowried,另外可以在实现类上用@Qualifier("className")指定名称,后面@Autowried的时候也用@Qualifier指定注入哪个类。
@Configuration
@Slf4j
public class DataSourceConfig { @Bean
@ConfigurationProperties("foo.datasource")
public DataSourceProperties fooDataSourceProperties() {
return new DataSourceProperties();
} @Bean
@Primary
public DataSource fooDataSource() {
DataSourceProperties dataSourceProperties = fooDataSourceProperties();
log.info("foo datasource: {}", dataSourceProperties.getUrl());
return dataSourceProperties.initializeDataSourceBuilder().build();
} @Bean
JdbcTemplate fooJdbcTemplate(@Qualifier("fooDataSource")DataSource dataSource) {
return new JdbcTemplate(dataSource);
} @Bean
@Resource
public PlatformTransactionManager fooTxManager(DataSource fooDataSource) {
return new DataSourceTransactionManager(fooDataSource);
} @Bean
@ConfigurationProperties("bar.datasource")
public DataSourceProperties barDataSourceProperties() {
return new DataSourceProperties();
} @Bean
public DataSource barDataSource() {
DataSourceProperties dataSourceProperties = barDataSourceProperties();
log.info("bar datasource: {}", dataSourceProperties.getUrl());
return dataSourceProperties.initializeDataSourceBuilder().build();
} @Primary
@Bean
JdbcTemplate barJdbcTemplate(@Qualifier("barDataSource")DataSource dataSource) {
return new JdbcTemplate(dataSource);
} @Bean
@Resource
public PlatformTransactionManager barTxManager(DataSource barDataSource) {
return new DataSourceTransactionManager(barDataSource);
}
}
到此我们可以使用DataSource了
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        JdbcTemplateAutoConfiguration.class})
@Slf4j
public class MultiDataSourceApplication implements CommandLineRunner {
    @Autowired
    private DataSource dataSource;
    @Autowired
    @Qualifier("barDataSource")
    private DataSource barDataSource;
    @Autowired
    @Qualifier("fooJdbcTemplate")
    private JdbcTemplate fooJdbcTemplate;
    @Autowired
    @Qualifier("barJdbcTemplate")
    private JdbcTemplate barJdbcTemplate;
    public static void main(String[] args) {
        SpringApplication.run(MultiDataSourceApplication.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        showConnection();
    }
    private void showConnection() throws SQLException {
        log.info("fooDataSource数据源: " + dataSource.toString());
        log.info("fooJdbcTemplate: " + fooJdbcTemplate.toString());
        log.info("barDataSource数据源: " + barDataSource.toString());
        log.info("barJdbcTemplate: " + barJdbcTemplate.toString());
    }
}
对于即将发布到生产环境中的应用程序, 建议使用从连接池获取连接的数据源。 如果可能的话, 我倾向于通过应用服务器的JNDI来获取数据源。
Spring数据访问1 - 数据源配置及数据库连接池的概念的更多相关文章
- Spring数据访问之JdbcTemplate
		Spring数据访问之JdbcTemplate 使用JdbcTemplate的基本操作步骤 1.引jar包 
- Spring Boot2.x 动态数据源配置
		原文链接: Spring Boot2.x 动态数据源配置 基于 Spring Boot 2.x.Spring Data JPA.druid.mysql 的动态数据源配置Demo,适合用于数据库的读写分 ... 
- MyBatis源码解析之数据源(含数据库连接池简析)
		一.概述: 常见的数据源组件都实现了javax.sql.DataSource接口: MyBatis不但要能集成第三方的数据源组件,自身也提供了数据源的实现: 一般情况下,数据源的初始化过程参数较多,比 ... 
- Web jsp开发学习——数据库的另一种连接方式(配置静态数据库连接池)
		1.导包 2.找到sever里的sever.xml,配置静态数据库连接池 <Context docBase="bookstore" path="/booksto ... 
- Spring Boot数据访问之数据源自动配置
		Spring Boot提供自动配置的数据访问,首先体验下,Spring Boot使用2.5.5版本: 1)导入坐标: 2.5.25版本支持8.0.26mysql数据库驱动.spring-boot-st ... 
- Spring数据访问和事务
		1.模型 2.解耦 3.实现 3.1 核心接口 3.2 代码分析 3.2.1 事务管理 3.2.2 数据访问 4.使用 4.1 编程模式 4.2 配置模式 4.2.1 声明式配置方式 4.2.2 注解 ... 
- spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)
		一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ... 
- 三、Spring——数据访问
		1.Spring 对 DAO的支持 Spring支持目前大多数常用的数据持久化技术,Spring定义了一套面向DAO层的异常体系,并未各种支持的持久化技术提供了异常转换器.这样,我们在设计DAO接口时 ... 
- 复习Spring第三课--数据源配置的多种方式
		spring数据源配置可以说分为:spring容器自带连接池.项目中创建连接池.服务器创建连接池三种 一.spring容器自带连接池 Spring本身也提供了一个简单的数据源实现类DriverMa ... 
随机推荐
- 微信小程序 navigateTo 传对象参数
			当微信小程序navigateTo传入参数是个object时,请使用JSON.strtingify将object转化为字符串,代码如下: wx.navigateTo({ url: '../sendChe ... 
- JVM Safepoint 安全点
			一.什么是安全点: 在可达性分析算法中查找存活的对象,首先要找到哪些是GC Roots: 有两种查找GC Roots的方法: 一种是遍历方法区和栈区来查找(保守式GC): 一种是通过OopMap的数据 ... 
- android之View坐标系(view获取自身坐标的方法和点击事件中坐标的获取)
			在做一个view背景特效的时候被坐标的各个获取方法搞晕了,几篇抄来抄去的博客也没弄很清楚. 现在把整个总结一下. 其实只要把下面这张图看明白就没问题了. 涉及到的方法一共有下面几个: view获取自身 ... 
- html5--6-47 阶段练习2-渐变按钮
			html5--6-47 阶段练习2-渐变按钮 实例 @charset="UTF-8"; .but1{ padding: 10px 20px; font-size:16px; tex ... 
- 后台while收发过程
			fuse_loop_mt.c 中fuse_do_work函数使用while循环在后台不断运行,每一个while循环中,主要有两个操作. 1. fuse_session_receive_buf(mt-& ... 
- Bootstrap-CL:按钮下拉菜单
			ylbtech-Bootstrap-CL:按钮下拉菜单 1.返回顶部 1. Bootstrap 按钮下拉菜单 本章将讲解如何使用 Bootstrap class 向按钮添加下拉菜单.如需向按钮添加下拉 ... 
- vue项目中的路径别名
			每次写引入组件的路径,如果路径嵌套比较深,那么会比较麻烦,我们可以在webpack.base.conf.js,中设置路径的别名,默认webpack设置src的别名为@ 建议配置src下一级目录的别名, ... 
- zz MBR,EBR
			http://hi.baidu.com/net5x/item/12d5243d86416bd76d15e993 
- In-App Purchase Programming Guide----(二) ---- Designing Your App’s Products
			Designing Your App’s Products A product is something you want to sell in your app’s store. You creat ... 
- k8s-容器资源需求、资源限制及HeapSter-二十二
			一.容器资源需求.资源限制 资源需求.资源限制:指的是cpu.内存等资源: 资源需求.资源限制的两个关键字: request:需求,最低保障,在调度时,这个节点必须要满足request需求的资源大小: ... 
