• SpringBoot系列之JDBC数据访问


    SpringBoot系列之JDBC数据访问

    SpringBoot jdbc是比较常用的内容,本博客通过实验并简单跟源码的方式进行介绍,希望可以帮助学习者更好地理解

    环境准备:

    • IDEA
    • Maven

    先新建一个项目:

    New->Project or Module->Spring Initializer
    在这里插入图片描述
    选择JDBC和mysql驱动,为了方便测试web等等也可以选上
    在这里插入图片描述

    项目创建成功之后,会自动配上如下的配置:

    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-jdbc</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    

    新建一个application.yml配置文件:

    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://127.0.0.1:3306/springboot
        driver-class-name: com.mysql.jdbc.Driver
    

    新建一个junit测试类进行测试:

    package com.example.springboot.jdbc;
    
    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 SppringbootJdbcApplicationTests {
    
    	@Autowired
    	DataSource dataSource;
    
    	@Test
    	public void contextLoads() throws SQLException {
    		System.out.println(dataSource.getClass());
    		Connection connection = dataSource.getConnection();
    		System.out.println(connection);
    		connection.close();
    	}
    
    }
    
    

    启动调试,发现控制台抛出异常信息:

    Caused by: com.mysql.cj.exceptions.UnableToConnectException: CLIENT_PLUGIN_AUTH is required
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85)
    at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:205)
    at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1340)
    at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
    ... 90 more

    原因是我的mysql服务器是5.+版本,而最新版2.2.1默认配置的mysql驱动版本是8.+的,8.+的驱动类是com.mysql.cj.jdbc.Driver,而非com.mysql.jdbc.Driver,所以解决方法还是手动加一下mysql驱动版本

    <dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<version>5.1.27</version>
    			<scope>runtime</scope>
    		</dependency>
    

    ok,现在正常测试,测试通过:

    class com.zaxxer.hikari.HikariDataSource
    2019-12-14 15:47:25.241 INFO 6772 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
    2019-12-14 15:47:27.403 INFO 6772 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
    HikariProxyConnection@23906266 wrapping com.mysql.jdbc.JDBC4Connection@717ed

    可以看出2.2.1版本的Springboot默认数据源类是com.zaxxer.hikari.HikariDataSource,而1.+版本很多都是以org.apache.tomcat.jdbc.pool.DataSource为默认数据源类的,具体哪个版本开始改变的不清楚

    既然Springboot默认使用hikari数据源,那就可以加上hikari的一些自定义配置

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf8&useSSL=true
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
        initialization-mode: always
        type: com.zaxxer.hikari.HikariDataSource
    
        hikari:
          jdbc-url: jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf8&useSSL=true
          minimum-idle: 5
          maximum-pool-size: 15
          auto-commit: true
          idle-timeout: 30000
          pool-name: DatebookHikariCP
          max-lifetime: 1800000
          connection-timeout: 30000
          connection-test-query: select 1
    

    经过调试,属性配置是有起效的
    在这里插入图片描述
    ok,掌握简单应用之后,还是要跟一下源码,依照经验,找到对应的自动配置类DataSourceAutoConfiguration.java

    不需要全部看懂源码,只要找到关键的信息即可,如图在这个自动配置类路其实就可以看出Springboot2.2.1支持的数据源种类有如下:
    在这里插入图片描述
    点一下DataSourceConfiguration类,里面都是各种DataSource的配置,用了很多@Conditional注解,条件符合才会起效
    在这里插入图片描述
    然后为什么说2.2.1版本默认是Hikari作为Datasource的?可以看一下项目的依赖图,可以看出默认引入了Hikari的jar
    在这里插入图片描述
    而且条件都符合,所以HikariDataSource就会进行自动配置
    在这里插入图片描述
    源码里用import引入了一个DataSourceInitializationConfiguration类,看其命名,应该是个初始化配置类
    在这里插入图片描述
    挑重点,如图,很明显要用了Spring框架很重要的后置处理器,还有一个DataSourceInitializerInvoker类
    在这里插入图片描述
    DataSourceInitializerInvoker类是做什么的?看其源码应该是一个初始化操作的监听器类,主要操作由DataSourceInitializer执行
    在这里插入图片描述
    DataSourceInitializer源码,里面有很多操作都是进行schema脚本的操作,只要非isEnabled就可以执行
    在这里插入图片描述
    只要两个条件符合就执行,DataSourceInitializationMode属性,看起来是通过配置文件获取的
    在这里插入图片描述
    getScripts,获取对应的脚本
    在这里插入图片描述
    读取schema脚本,所以可以看出只要将一些sql文件放在resources即可,默认文件命名为schema.sql,schema‐all.sql;
    在这里插入图片描述
    再通过资料,确认了这个类确实是执行一些初始化schema脚本的,根据application提示,发现有个属性,将其改为always即可
    在这里插入图片描述

    改为embedded是不能执行的,虽然源码里代码是这样的
    在这里插入图片描述
    还有这个关键代码,从配置spring.datasource.schema获取信息,

    List<Resource> scripts = getScripts("spring.datasource.schema", this.properties.getSchema(), "schema");
    

    在这里插入图片描述

    private List<Resource> getResources(String propertyName, List<String> locations, boolean validate) {
    		List<Resource> resources = new ArrayList<>();
    		for (String location : locations) {
    			for (Resource resource : doGetResources(location)) {
    				if (resource.exists()) {
    					resources.add(resource);
    				}
    				else if (validate) {
    					throw new InvalidConfigurationPropertyValueException(propertyName, resource,
    							"The specified resource does not exist.");
    				}
    			}
    		}
    		return resources;
    	}
    
    

    location就是一个字符类型的位置信息,所以可以使用如下配置,显然就可以自定义schema脚本,不需要固定为schema.sql或者schema-all.sql
    在这里插入图片描述

    代码例子下载:github下载链接

  • 相关阅读:
    【转】全文检索引擎Sphinx配置文件详细介绍
    【转】构建不依赖于cookie的手机端用户登录机制
    Sphinx在window下的初步安装和配置
    Zend Framework 在.htaccess中修改RewriteRule实现url重写
    做后台的程序猿的一点心得
    [Leetcode 75] 96 Unique Binary Search Trees
    [Leetcode 74] 92 Restore IP Addresses
    [Leetcode 73] 92 Reverse Linked List II
    [Leetcode 72] 91 Decode Ways
    [Leetcode 71] 86 Partition List
  • 原文地址:https://www.cnblogs.com/mzq123/p/12041372.html
Copyright © 2020-2023  润新知