持久层自动配置

SpingBoot持久层开发原理

1. JDBC

SpringBoot关于数据库的配置都存在于org.springframework.boot.autoconfigure.jdbc

  • 关于数据库的相关配置存放于DataSourceProperties
@ConfigurationProperties(
    prefix = "spring.datasource"
)
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
    private String name;
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private List<String> schema;
    private String schemaUsername;
    private String schemaPassword;
    private List<String> data;
    private String dataUsername;
    private String dataPassword;
  • 在实际使用的时候可以通过spring.datasource修改内部的属性
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.1.113:3308/jdbc
    driver-class-name: com.mysql.jdbc.Driver
  • SpringBoot通过DataSourceConfiguration创建数据源,默认使用Hikari连接池。可以通过spring.datasource.type指定使用的数据源类型
    • 支持以下这四种数据源

image-20200223213912454

通过spring.datasource.dbcp2
    spring.datasource.hikari
    spring.datasource.tomcat
    	来修改springboot提供的数据源的配置

2. 数据源自动配置原理

  • 自动配置通过DataSourceAutoConfigration来完成对数据源的自动配置

image-20200223215736915

  • 通过内部类PooledDataSourceConfiguration类来实现自动配置
    • 导入了各个数据源。Hikari.classTomcat.class……
    • 每一个数据源刚好对应于DataSourceConfiguration类中的数据源对象
@Configuration(
        proxyBeanMethods = false
    )
    @Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})
    @ConditionalOnMissingBean({DataSource.class, XADataSource.class})
    @Import({Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class})
    protected static class PooledDataSourceConfiguration {
        protected PooledDataSourceConfiguration() {
        }
    }
 static class Hikari {
        Hikari() {
        }

        @Bean
        @ConfigurationProperties(
            prefix = "spring.datasource.hikari"
        )
        HikariDataSource dataSource(DataSourceProperties properties) {
            HikariDataSource dataSource = (HikariDataSource)DataSourceConfiguration.createDataSource(properties, HikariDataSource.class);
            if (StringUtils.hasText(properties.getName())) {
                dataSource.setPoolName(properties.getName());
            }

            return dataSource;
        }
    }

3. 创建表

  • SpringBoot支持直接运行建表语句和插入数据的SQL。通过DataSourceInitializer类的完成
    • 通过runSchemaScripts()运行建表语句
    • 通过runDataScripts()运行插入数据的SQL语句
  • 默认可以通过在资源文件下添加SQL语句在服务器启动之时,运行建表语句和插入数据的语句
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.1.113:3308/jdbc
    driver-class-name: com.mysql.cj.jdbc.Driver
    initialization-mode: always //springBoot2.0以上需要添加
    schema:
        - classpath:employee.sql
        - classpath:department.sql
  • SpringBoot默认配置了JdbcTemplate
 class JdbcTemplateConfiguration {	
	@Bean
    @Primary
    JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        Template template = properties.getTemplate();
        jdbcTemplate.setFetchSize(template.getFetchSize());
        jdbcTemplate.setMaxRows(template.getMaxRows());
        if (template.getQueryTimeout() != null) {
            jdbcTemplate.setQueryTimeout((int)template.getQueryTimeout().getSeconds());
        }

        return jdbcTemplate;
    }

4. 整合Druid

		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
  • 通过spring.datasource.typedruid。并且配置druid连接源的参数
spring:
	datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        #  数据源其他配置
        initialSize: 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,slf4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  • Druid常用配置
配置缺省值说明
name配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this)
initialSize0初始化建立物理连接的个数,发生在init方法或者getConnection
maxActive8最大连接池的数量
maxIdle8已经废弃
maxWait连接最大等待时间
poolPreparedStatementsfalse是否缓存prepaerdStatement,也就是PSCache。游标使用
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
validationQuery用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
maxOpenPreparedStatements-1要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
timeBetweenEvictionRunsMillis有两个含义: 1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
4.1 SpringBoot中使用Druid

SpringBoot默认不支持Druid所以需要将数据源添加到容器中

  • 将DruidDataSource数据源添加到容器中,并且导入yml中的相关配置
//导入配置文件中的druid数据库的相关配置
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }
4.2 SpringBoot使用Druid提供的数据库监控系统
  • 创建访问该系统的Servlet。Druid提供了StatViewServlet作为该系统的Servlet。通过Springboot提供的自定义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");//不允许谁访问
        bean.setInitParameters(initParams);
        return bean ;
    }
  • 添加一个过滤器作为监控器
@Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        filterRegistrationBean.setInitParameters(initParams);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        return filterRegistrationBean ;
    }
4.3 测试
  • 访问一个JDBC请求

  • 访问Druid管理后台,里面显示了执行的SQL语句

5. 整合Mybatis

		<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
5.1 基于注解
  • 通过@Mapper注解声明属于mybatis
@Mapper
@Repository("departmentMapper")
public interface IDepartmentMapper {

    @Select("select * from department")
    List<Department> findAll();

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

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

    @Delete("delete from department where id = #{id}")
    int deleteDepart(Integer id);

    @Update("update department set departmentName = #{departmentName} where id = #{id}")
    int updateDepart(Department department);

}
  • 自定义MyBatis的配置规则;通过ConfigurationCustomizer来修改
@Configuration
public class MyBatisConfigurer {

    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return configuration->configuration.setMapUnderscoreToCamelCase(true);//设置驼峰命名
    }
}
  • @MapperScan指定需要扫描哪几个包,添加以后将相当于给包中的类添加了@Mapper
public @interface MapperScan {
    String[] value() default {};

    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
  • 在运行的时候可会出现这样的警告。出现的原因是由于JDK版本太高了,需要1.8或者以下

5.2 基于配置文件
  • 在资源文件下书写主配置文件
<?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"/>
        开启自动驼峰命名规则(camel case)映射
    </settings>
</configuration>
  • 书写接口映射文件
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bywlstudio.springboot02.mapper.IDepartmentMapperXml">
    <select id="findAll" resultType="com.bywlstudio.springboot02.bean.Department">
        select * from department ;
    </select>
    <insert id="insertDepart" parameterType="com.bywlstudio.springboot02.bean.Department" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into department(departmentName) values(#{departmentName})
    </insert>
</mapper>
  • yml配置文件中配置
mybatis:
  config-location: classpath:mapper/mapper.xml # 配置主配置文件
  mapper-locations: classpath:mapper/deparment/DepartmentMapperXml.xml # 配置映射文件
  • 项目结构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值