Springboot第六章 数据访问

版权声明:版权为ZZQ所有 https://blog.csdn.net/qq_39148187/article/details/82378967

Spring+jdbc

使用idea 创建springboot项目的时候选中mysql 勾上mysql 和jdbc  然后我们进行演示

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://104.224.142.102:3306/test
    username: root
    password: 1234

yml/properties 中配置上数据库连接配置 

package com.zzq.springboot06jdbc;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBoot06JdbcApplicationTests {

    @Autowired
    DataSource dataSource  ;

	@Test
	public void contextLoads() throws SQLException {
        System.out.println(dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

}

获取连接池类型, 和连接对象connection

class com.zaxxer.hikari.HikariDataSource
2018-09-04 09:56:25.040  INFO 10792 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2018-09-04 09:56:28.653  INFO 10792 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
HikariProxyConnection@1488352537 wrapping com.mysql.jdbc.JDBC4Connection@281ce6bb
2018-09-04 09:56:28.678  INFO 10792 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@38467116: startup date [Tue Sep 04 09:56:15 CST 2018]; root of context hierarchy
2018-09-04 09:56:28.681  INFO 10792 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2018-09-04 09:56:28.686  INFO 10792 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

我们可以看到springboot 使用的是HikaridataSource 这个连接池, 我之前也是没有听说过,是我孤陋寡闻,springboot2.0之前的默认连接池是tomcat 连接池,  springboot2.0 换成了hikaridate 是有原因的 我们看下网上评价

https://blog.csdn.net/qq_31125793/article/details/51241943

我个人觉得使用druid 还是比较好

数据源的配置在 DataSourceProperties中 

自动配置原理在org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration  中

DataSourceConfiguration

数据源的配置 ,根据各种配置创建数据源,默认是使用 HikariDataSource 

springboot 默认支持的数据源有 : 

org.apache.tomcat.jdbc.pool.DataSource dataSource
com.zaxxer.hikari.HikariDataSource
org.apache.commons.dbcp2.BasicDataSource
	/**
	 * Generic DataSource configuration.
	 */
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type")
	static class Generic {

		@Bean
		public DataSource dataSource(DataSourceProperties properties) {
			return properties.initializeDataSourceBuilder().build();
		}

	}

也可以自定义数据源类型,使用build()创建数据源的,用反射创建type 数据源绑定相关属性

springboot 配置自动配置jdbc配置类

 */
	public void initSchema() {
		List<Resource> scripts = getScripts("spring.datasource.data",
				this.properties.getData(), "data");
		if (!scripts.isEmpty()) {
			if (!isEnabled()) {
				logger.debug("Initialization disabled (not running data scripts)");
				return;
			}
			String username = this.properties.getDataUsername();
			String password = this.properties.getDataPassword();
			runScripts(scripts, username, password);
		}
	}

在创建完连接池之后执行了,runscripts 方法这个方式是用来初始化sql 表的,可以吧建表语句写在文件中,然后springboot项目启动的时候自动创建

这个方法三个参数,

	private void runScripts(List<Resource> resources, String username, String password) {

resource 里面就是放的配置的sql文件地址

它里面还有一个方法

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);
	}

他是先从我们properties/yml中找有没有我们配置的,如果有就按照我们的加载,如果没有就

	public boolean createSchema() {
		List<Resource> scripts = getScripts("spring.datasource.schema",
				this.properties.getSchema(), "schema");
		if (!scripts.isEmpty()) {
			if (!isEnabled()) {
				logger.debug("Initialization disabled (not running DDL scripts)");
				return false;
			}
			String username = this.properties.getSchemaUsername();
			String password = this.properties.getSchemaPassword();
			runScripts(scripts, username, password);
		}
		return !scripts.isEmpty();
	}

这里看到fallback   就是schema 字符串 所以他默认会加载根目录下的schema.sql文件

	/**
	 * Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or
	 * data-${platform}.sql).
	 */
	private String platform = "all";

或者是制定platform 参数然后data-${platform}.sql文件或者schema-${platform}.sql 文件

在springboot1.5 中会自动加载,但是springboot2.0 可能不会,我们需要配上一个参数

    initialization-mode: always

这个是干什么? 点开看看

	/**
	 * Initialize the datasource with available DDL and DML scripts.
	 */
	private DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;

	/**

看描述  是初始化可以可用的ddl dml 数据源脚本文件

默认类型是embedded类型 ,点开

/*
 * Copyright 2012-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.jdbc;

/**
 * Supported {@link javax.sql.DataSource} initialization modes.
 *
 * @author Vedran Pavic
 * @author Stephane Nicoll
 * @since 2.0.0
 * @see AbstractDataSourceInitializer
 */
public enum DataSourceInitializationMode {

	/**
	 * Always initialize the datasource.
	 */
	ALWAYS,

	/**
	 * Only initialize an embedded datasource.
	 */
	EMBEDDED,

	/**
	 * Do not initialize the datasource.
	 */
	NEVER

}

枚举类,第一个是初始化所有的数据源, 第二个是,初始化嵌入式的数据源, 第三个是初始化数据源

我们把他调成always 就可以了 

JDBCTemplate 

spring 提供的听哈用的

package com.zzq.springboot06jdbc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * @author ZZQ
 * @date 2018/9/4 11:44
 */
@RestController
public class helloWorldController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/jdbc")
    public Map hello(){
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from department");
        return  maps.get(0);
    }
}

springboot使用druiddatasource 实现监控,防火墙等

1)引入依赖

 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

2)配置properties 

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:my...
    username: root
    password: 1234
    #支持的是list
    schema:
      - classpath:department.sql
      - classpath:employee.sql
    initialization-mode: always
    type: com.alibaba.druid.pool.DruidDataSource

只要type 改变spring 使用的连接池也就发生了变化

这样切换了, 但是druid 有更厉害的功能监控之类的这个需要我们自己定义datasource  不能使用springboot的反射创建的datasource 写一个自己的配置类和配置文件对应

  spring:
    datasource:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://104.224.142.102:3306/test
      username: root
      password: 1234
      #支持的是list
      schema:
        - classpath:department.sql
        - classpath:employee.sql
      initialization-mode: always
      type: com.alibaba.druid.pool.DruidDataSource
    #   数据源其他配置 (一下默认是不起作用的)
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
#   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
package com.zzq.springboot06jdbc.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.ServletContextLiveBeansView;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZZQ
 * @date 2018/9/4 12:42
 */
@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return  new DruidDataSource();
    }

    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();

        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默认就是允许所有访问
        initParams.put("deny","192.168.15.21");

        bean.setInitParameters(initParams);
        return bean;
    }


    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");

        bean.setInitParameters(initParams);

        bean.setUrlPatterns(Arrays.asList("/*"));

        return  bean;
    }

}

这样配置即可

Springboot 整合Mybatis  

注解版

直接引入mybatis-spring- starter 然后然后druid 连接池配置好,编写mapper文件

package com.zzq.springboot06mybatis.mapper;

import com.zzq.springboot06mybatis.entity.Department;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author ZZQ
 * @date 2018/9/4 16:47
 */
@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id );

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert  into department(departmentName) values(#{departmentName})")
    public int insertDept( Department department);


}

这里@Options 这个注解是用来标识自增主键,他的结果会自动的封装进department 中,然后返回 

这里我们的字段和数据库中的字段是对应的, 数据中也是驼峰命名,但是数据库如果是以_隔开, 我们要自己配置命名规则,写配置类 

package com.zzq.springboot06mybatis.config;

import ch.qos.logback.classic.gaffer.ConfigurationContributor;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * @author ZZQ
 * @date 2018/9/4 17:18
 */
@Configuration
public class MybatisConfig {

    /**
    *   @author ZZQ
    *   @date 2018/9/4
    *   @description
     *  开启mybatis 驼峰命名法
    */
    public ConfigurationCustomizer configurationCustomizer(){
        return  new ConfigurationCustomizer() {
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration) {
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }
}

如果很多mapper的话我们可以采用包扫描的方式加入mapper 

@MapperScan(basePackages = {"com.zzq.springboot06mybatis.mapper"})

可以传入多个位置,这里是数组

配置版

使用xml配置,复杂的sql 让java 代码变得臃肿不适合写注解

使用配置

1)创建全局配置文件mybatis-config.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

2)然后再springboot全局配置文件中配置 mapper 接口文件和mapper 映射文件的位置

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

然后其他就和我们正常写的一样了

--------------------------------------------

Mybatis +Springboot  之后如何打印输出打印sql ? 

logging:
  level:
    com.zzq.springboot06mybatis.mapper: DEBUG

这里的com.zzq.springboot06mybatis.mapper  就是接口文件的位置

猜你喜欢

转载自blog.csdn.net/qq_39148187/article/details/82378967
今日推荐