对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入各种xxxTemplate,xxxRepository
来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。这里SpringBoot版本使用1.5.10。
【1】SpringBoot配置数据源
① 创建项目,引入需要的模块
pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
② 配置MySQL并测试
类似于以前项目的config.properties,这将mysql的属性配置在yml文件中。数据源的所有配置对应类如下:
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties
implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {
private ClassLoader classLoader;
private Environment environment;
/**
* Name of the datasource.
*/
private String name = "testdb";
/**
* Generate a random datasource name.
*/
private boolean generateUniqueName;
/**
* Fully qualified name of the connection pool implementation to use. By default, it
* is auto-detected from the classpath.
*/
private Class<? extends DataSource> type;
/**
* Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
*/
private String driverClassName;
/**
* JDBC url of the database.
*/
private String url;
/**
* Login user of the database.
*/
private String username;
/**
* Login password of the database.
*/
private String password;
/**
* JNDI location of the datasource. Class, url, username & password are ignored when
* set.
*/
private String jndiName;
/**
* Populate the database using 'data.sql'.
*/
private boolean initialize = true;
/**
* Platform to use in the DDL or DML scripts (e.g. schema-${platform}.sql or
* data-${platform}.sql).
*/
private String platform = "all";
/**
* Schema (DDL) script resource references.
*/
private List<String> schema;
/**
* User of the database to execute DDL scripts (if different).
*/
private String schemaUsername;
/**
* Password of the database to execute DDL scripts (if different).
*/
private String schemaPassword;
/**
* Data (DML) script resource references.
*/
private List<String> data;
/**
* User of the database to execute DML scripts.
*/
private String dataUsername;
/**
* Password of the database to execute DML scripts.
*/
private String dataPassword;
/**
* Do not stop if an error occurs while initializing the database.
*/
private boolean continueOnError = false;
/**
* Statement separator in SQL initialization scripts.
*/
private String separator = ";";
/**
* SQL scripts encoding.
*/
private Charset sqlScriptEncoding;
private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE;
private Xa xa = new Xa();
private String uniqueName;
//...
}
application.yml文件如下:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
在测试类中获取默认数据源,并拿到链接:
@RunWith(SpringRunner.class)
@SpringBootTest
public class DatasourceApplicationTests {
@Autowired
DataSource dataSource;
@Test
public void contextLoads() throws Exception {
System.out.println(dataSource.getClass()+"***********");
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
测试结果如下:
class org.apache.tomcat.jdbc.pool.DataSource***********
ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@2bfbffb2]]
即,数据源默认使用的是org.apache.tomcat.jdbc.pool.DataSource
(这个与SpringBoot版本有关,这里是1.5.10)。
【2】使用JdbcTemplate访问数据库
① 默认注入
SpringBoot默认配置了JdbcTemplate
和NamedParameterJdbcTemplate
,源码如下:
@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class JdbcTemplateAutoConfiguration {
private final DataSource dataSource;
public JdbcTemplateAutoConfiguration(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
@Primary
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(this.dataSource);
}
@Bean
@Primary
@ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(this.dataSource);
}
}
可以看到在上面JdbcTemplateAutoConfiguration
中默认注入了namedParameterJdbcTemplate
和jdbcTemplate
两个实例。
② 编写controller进行测试
@Controller
public class HelloController {
@Autowired
JdbcTemplate jdbcTemplate;
@ResponseBody
@GetMapping("/hello")
private Map<String,Object> getBook(){
String sql = "select * from book";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
return list.get(0);
}
}
浏览器访问结果如下:
这里返回结果为Map,浏览器得到的为JSON。这是因为,首先方法上使用了注解@Responsebody
,其次WebMVCAutoConfiguration
默认注册了一系列的HttpMessageConverter
,该类主要用来做请求响应的转换。
而@Responsebody
注解被RequestResponseBodyMethodProcessor
处理器进行解析。
【3】SpringBoot加载项目路径下的SQL
SpringBoot另一个特性是可以加载项目路径下的SQL脚本,比如建表语句,insert语句等等。
默认Schema脚本名字:
classpath*:schema.sql;
classpath*:schema-all.sql;
默认Data脚本名字:
classpath*:data.sql;
classpath*:data-all.sql;
如果想使用自定义脚本名字,在yml文件中配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
schema:
- classpath:department.sql
如下图所示:
【4】默认数据源配置实例
这里默认数据源指的是org.apache.tomcat.jdbc.pool.DataSource
。
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
#最大连接数
tomcat.max-active: 20
#最大空闲数
tomcat.max-idle: 8
#最小空闲数
tomcat.min-idle: 8
#初始化连接数
tomcat.initial-size: 10
无需使用额外配置或者pom文件,即可正常使用默认org.apache.tomcat.jdbc.pool.DataSource
。
【5】SpringBoot2.X中使用HikariDataSource
在SpringBoot2.X版本中,默认使用数据源是HikariDataSource
(可以称之为"光"),如下所示在DataSourceBuilder配置。
private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
"com.zaxxer.hikari.HikariDataSource",
"org.apache.tomcat.jdbc.pool.DataSource",
"org.apache.commons.dbcp2.BasicDataSource" };
这里同样贴一份配置实例
# 驱动,根据需要更改 如com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
# Hikari 数据源配置
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
#最小空闲
spring.datasource.hikari.minimum-idle=5
#连接池最大连接数,默认是10
spring.datasource.hikari.maximum-pool-size=15
# 此属性控制从池返回的连接的默认自动提交行为,默认值:true
spring.datasource.hikari.auto-commit=true
# 空闲连接存活最大时间,默认600000(10分钟)
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
spring.datasource.hikari.max-lifetime=1800000
# 数据库连接超时时间,默认30秒,即30000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
配置项 | 默认值 | 说明 |
---|---|---|
autoCommit | true | 此属性控制从池返回的连接的默认自动提交行为,默认值:true |
connectionTimeout | 30000 | 客户端创建连接等待超时时间,如果30秒内没有获取连接则抛异常,不再继续等待 |
idleTimeout | 600000 | 空闲连接存活最大时间,默认600000(10分钟) |
maxLifetime | 1800000 | 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟 |
minimumIdle | 10 | 连接池中最小空闲连接数 |
maximumPoolSize | 10 | 连接池中最大连接数 |
readOnly | false | 从池中获取的连接是否是只读模式 |
validationTimeout | 5000 | 测试连接是否空闲的间隔 |
leadDetectionThreshold | 0 | 连接被占用的超时时间,默认为0即不强制回。可以设置60000即超过1分钟客户端没有释放连接则强制回收该连接,防止连接泄漏 |
initializationFailTimeout | 1 | 如果池无法成功初始化连接,则此属性控制池是否将 fail fast |
isolateInternalQueries | false | 是否在其自己的事务中隔离内部池查询,例如连接活动测试 |
registerMbeans | false | 是否注册JMX管理Bean(MBeans) |
dataSource | null | 这个属性允许你直接设置数据源的实例被池包装,而不是让HikariCP通过反射来构造它 |
schema | driver default | 该属性为支持模式概念的数据库设置默认模式 |
threadFactory | null | 此属性允许您设置将用于创建池使用的所有线程的java.util.concurrent.ThreadFactory的实例 |
scheduledExecutor | null | 此属性允许您设置将用于各种内部计划任务的java.util.concurrent.ScheduledExecutorService实例 |
poolName | HikariPool-1 | 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置 |