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資料!回覆悟空,領取架構師資料! 悟空聊架構
關注我,帶你天天進步一點點!