JDBC API 属于Java APIJDBC用于如下几种功能:链接到数据库、执行SQL语句html
能够在POM中找到引入的JDBC依赖和mysql依赖: JDBC 依赖:java
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
MySql 驱动依赖:mysql
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
新增配置文件:src/main/resources/application.ymlgit
spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/study-spring-boot?serverTimezone=UTC&useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8 driverClassName: com.mysql.cj.jdbc.Driver
注意:com.mysq.jdbc.Driver
被废弃了,须要使用com.mysql.cj.jdbc.Driver
github
package com.jackson0714.springboot; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; @SpringBootTest class Springboot05DataJdbcApplicationTests { @Autowired DataSource dataSource; //自动配置数据源,使用yml配置 @Test void contextLoads() throws SQLException { System.out.println("数据源:" + dataSource.getClass()); Connection connection = dataSource.getConnection(); System.out.println("数据库链接:" + connection); connection.close(); } }
默认数据源:class com.zaxxer.hikari.HikariDataSourceweb
数据库链接:HikariProxyConnection@1335157064 wrapping com.mysql.cj.jdbc.ConnectionImpl@7ff8a9dcspring
自动配置文件路径:org.springframework.boot.autoconfigure.jdbcsql
DataSourceConfiguration用来自动导入数据源(根据各类判断)shell
/** * Tomcat Pool DataSource configuration. */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true) static class Tomcat { @Bean @ConfigurationProperties(prefix = "spring.datasource.tomcat")
若是导入了org.apache.tomcat.jdbc.pool.DataSource数据源,而且配置的spring.datasource.type配置的是org.apache.tomcat.jdbc.pool.DataSource,或没配置type也使用tomcat数据源数据库
org.apache.tomcat.jdbc.pool、HikariDataSource、org.apache.commons.dbcp2
使用DataSourceBuilder建立数据源,利用反射建立响应type的数据源,而且绑定相关属性
/** * Generic DataSource configuration. */ @Configuration(proxyBeanMethods = false) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type") static class Generic { @Bean DataSource dataSource(DataSourceProperties properties) { //使用DataSourceBuilder建立数据源,利用反射建立响应type的数据源,而且绑定相关属性 return properties.initializeDataSourceBuilder().build(); } }
/** * Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on * {@link InitializingBean#afterPropertiesSet()} and {@literal data-*.sql} SQL scripts on * a {@link DataSourceSchemaCreatedEvent}. * * @author Stephane Nicoll * @see DataSourceAutoConfiguration */ class DataSourceInitializerInvoker implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
createSchema() 建立表 (文件名规则 schema-*.sql) initSchema() 执行数据脚本 (文件名规则 data-*.sql)
getScripts() 来获取须要执行的脚本
private List<Resource> getScripts(String propertyName, List<String> resources, String fallback) { if (resources != null) { return getResources(propertyName, resources, true); } String platform = this.properties.getPlatform(); List<String> fallbackResources = new ArrayList<>(); fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql"); fallbackResources.add("classpath*:" + fallback + ".sql"); return getResources(propertyName, fallbackResources, false); }
fallback
= "schema", platform
="all",会自动执行根目录下:schema-all.sql 或schema.sql 文件
fallback
= "data", platform
="all",会自动执行根目录下:data-all.sql 或data.sql 文件
isEnabled() 方法判断是否开启了自动执行脚本
有三种模式:NEVER,EMBEDDED(默认),Always
疑问:用EMBEDDED模式返回false,开关关闭,不执行脚本,这是为啥呢?
用Always模式则每次启动spring boot重复执行脚本(建立表脚本都是先判断有没有表,有则删除后重建)
private boolean isEnabled() { DataSourceInitializationMode mode = this.properties.getInitializationMode(); if (mode == DataSourceInitializationMode.NEVER) { return false; } if (mode == DataSourceInitializationMode.EMBEDDED && !isEmbedded()) { return false; } return true; }
schema: - classpath:department.sql
建立出的 department
表
JdbcTemplateAutoConfiguration.java 文件 自动注入了JdbcTemplate。(JdbcTemplate用来操做数据库)
@Configuration(proxyBeanMethods = false) @ConditionalOnClass({ DataSource.class, JdbcTemplate.class }) @ConditionalOnSingleCandidate(DataSource.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class) @EnableConfigurationProperties(JdbcProperties.class) @Import({ JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class }) public class JdbcTemplateAutoConfiguration { }
咱们用Swagger的方式来测试
<!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
package com.jackson0714.springboot.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build(); } private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("玩转Spring Boot 接口文档") .description("This is a restful api document of Spring Boot.") .version("1.0") .build(); } }
http://localhost:8081/swagger-ui.html
@ApiOperation(value = "1.新增部门") @ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "部门名称") }) @PostMapping("/create") public int createDepartment(@RequestParam String name) { String sql = String.format("insert into department(departmentName) value('%s')", name); int result = jdbcTemplate.update(sql); return result; }
表记录
@ApiOperation(value = "2.查询全部部门") @GetMapping("/getAllDepartment") public List<Map<String, Object>> getAllDepartment() { List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from department"); return list; }
@ApiOperation(value = "3.根据id查询某个部门") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "须要查询的部门id") }) @GetMapping("/{id}") public Map<String, Object> getDepartmentById(@PathVariable Long id) { String sql = "select * from department where id = " + id; List<Map<String, Object>> list = jdbcTemplate.queryForList(sql); return list.get(0); }
@ApiOperation(value = "根据id更新部门名称") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "须要更新的部门id"), @ApiImplicitParam(name = "name", value = "须要更新的部门名称") }) @PostMapping("/update") public int updateDepartmentById(@RequestParam Long id, @RequestParam String name) { String sql = String.format("update department set departmentName = '%s' where id = %d", name, id); int result = jdbcTemplate.update(sql); return result; }
@ApiOperation(value = "根据id删除部门") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "须要删除的部门id") }) @PostMapping("/delete") public int deleteDepartment(@RequestParam Long id) { String sql = String.format("delete from department where id = %d", id); int result = jdbcTemplate.update(sql); return result; }
java.sql.SQLException:null, message from server: "Host 'Siri' is not allowed to connect to this MySQL server" 解决方案: 执行命令:
use mysql; select host from user; update user set host = '%' where user = 'root'
执行结果:
Query OK, 1 row affected
以下图所示:
Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support. 解决方案: 配置spring.datasource.url 时,增长参数:serverTimezone=UTC
关注公众号:悟空聊架构,回复pmp,领取pmp资料!回复悟空,领取架构师资料! 悟空聊架构
关注我,带你天天进步一点点!