原生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