JDBC、连接池、Mybatis原理(笔记)

原生JDBC几大类:
DriverManager--Connection--Statement--ResultSet

//注册driver
Class.forName(driver);
//新建连接
Connection connection = DriverManager.getConnection(url,username,password);
Statement statement = connection.createStatement();
//执行sql
ResultSet resultSet = statement.executeQuery("select * from test where id = 1 ");
//查询结果
while(resultSet.next()){
                String name = resultSet.getString("name");
                System.out.println(" name : " + name);
            }
//关闭资源...

Statement和PreparedStatement:
前者:动态拼接,编译时需直接传入参数
后者:可以使用占位符,执行时再传入参数,防止sql注入。支持预编译,但是空间范围有限(适用于批量操作)

PreparedStatement preparedStatement = connection.prepareStatement("insert into test (name,age) values (?,?)");
preparedStatement.setString(1,"xx");
preparedStatement.setInt(1,18);
//如果是查询返回true,更新或者插入返回false
boolean rel = preparedStatement.execute();
//关闭资源...

连接池原理:

连接复用:传统jdbc连接,生成Connection,使用完手动关闭。连接池的作用就是使连接得到复用,getConnection()获取连接,releaseConnection()释放连接,维护连接池中一定数量的连接。

连接池(ConnectionPool)和资源管理:

  • 不同的应用都访问同一个数据源,会导致数据库资源耗尽。所以连接池的第一个任务是限制,限制每个服务可以拥有的最大资源,确定连接池的大小。
  • 在连接池的范围内,最大限度的使用资源。许多数据库中Connection并不是最小单位,控制Statement资源比Connection更重要,创建一个Connection会在物理网络上建立一个用于通讯的连接,一个连接可以申请几百个Statement。传统jdbc中每个Statement单独占用一个Connection,造成资源浪费。ConnectionPool可以解决这个问题,让几十个几百个Statement使用同一个Connection。一个Connection对应多个Statement,一个Statement对应一个ResultSet,同一个Statement创建的ResultSet,后创建的覆盖前面的。
  • 连接池逻辑:连接池接收到需要连接请求,查看池中是否有空闲连接,如果没有,查看是否到达最高连接值,如果没有创建一个新的连接给请求端。如果超出最大等待时间,抛异常。

常用连接池:
HikariCP 和 Druid

Druid使用(偏向监控):

  • 连接池
  • StatFiter插件,监控sql的执行性能,打印日志
  • jdbc层的插件拓展
  • 数据库密码加密

数据连接池常用的配置参数:

#数据库配置
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = 123
spring.datasource.initialSize = 5 //初始化连接数量
spring.datasource.minIdle = 5 //最小连接池数量
spring.datasource.maxActive = 20 //最大连接池数量
spring.datasource.maxWait = 60000 //等待超时时间
spring.datasource.testWhileIdle=true //申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
spring.datasource.timeBetweenEvictionRunMillis=60000 //上述的空闲时间
spring.datasource.minEvictableIdleTimeMillis=10000 //
spring.datasource.validationQuery=SELECT '1' //检测连接的sql
spring.datasource.testOnBorrow=true //申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
spring.datasource.testOnReturn=false //归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
spring.datasource.poolPreparedStatements=true //是否缓存preparedStatement,也就是PSCache
spring.datasource.maxPoolPreparedStatementPerConnectionSize=10 //缓存大小
spring.datasource.filters=stat //常用的插件有:监控统计用的filter:stat;日志用的filter:log4j;防御sql注入的filter:wall

DataSource和监控页面拦截配置:

@Configuration
public class DruidConfig {

    //DataSource配置
    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource druid(){
        return new DruidDataSource();
    }

    //sql监控界面
    @Bean
    public ServletRegistrationBean druidServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean<>();
        bean.setServlet(new StatViewServlet());//配置拦截器
        bean.addUrlMappings("/druid/*");//只拦截管理页面的请求
        HashMap initParam = new HashMap<>();
        initParam.put("loginUsername","admin"); //登录druid管理界面的用户名
        initParam.put("loginPassword","123");//登录druid管理界面的密码
        initParam.put("resetEnable","true");//是否允许druid重置统计信息
        initParam.put("allow","");//ip白名单,没有设置表示允许所有访问
        bean.setInitParameters(initParam);
        return bean;
    }

    //exclusions掉一些不需要拦截的资源
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        bean.addUrlPatterns("/*");
        bean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return bean;
    }

}

HikariCP的使用(偏向性能):

//数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = 123

//Spring Boot 2.0 默认使用HikariDataSource作为数据库连接池
//spring.datasource.type = com.zaxxer.hikari.HikariDataSource

spring.datasource.hikari.connection-timeout=20000 //连接超时时间
spring.datasource.hikari.minimum-idle=5 //最小空闲连接数
spring.datasource.hikari.maximum-pool-size=12 //最大连接数
spring.datasource.hikari.idle-timeout=300000 //允许连接在连接池中空闲的最长时间
spring.datasource.hikari.max-lifetime=1200000 //池中连接关闭后的最长生命周期
spring.datasource.hikari.auto-commit=true //从池返回的连接的默认自动提交行为

Mybatis几大类:
SqlSessionFactoryBuilder--SqlSessionFactory--SqlSession

实现的过程:

//通过xml配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = factory.openSession();
//sqlSession.selectList(...)
sqlSession.close();

//通过代码
@Bean(name = "dataSource")
@ConfigurationProperties("spring.datasource")
@Primary
public DataSource druid(){
    return new DruidDataSource();
}

@Bean
public SqlSessionFactory getSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
    return bean.getObject();
}

//设置事务管理的做法 DataSourceTransactionManager
@Bean(name = "transactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("dataSource") DataSource dataSource){
    return new DataSourceTransactionManager(dataSource);
}

//设置Mybatis为了接入Spring提供的Bean SqlSessionTemplate
@Bean
public SqlSessionTemplate getSqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory){
    return new SqlSessionTemplate(sqlSessionFactory);
}

2020/03/16


你可能感兴趣的:(数据库,mybatis)