目录
整合JDBC
pom.xml
<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>
spring:
datasource:
username: root
password: root #使用 MySQL连接驱动是8.0以上,需要在Url后面加上时区, GMT%2B8代表中国时区,不然报时区错误
url: jdbc:mysql://127.0.0.1:3306/test_db?serverTimezone=GMT%2B8 # 注意: 新版本驱动包,要使用以下类作为驱动类
driver-class-name: com.mysql.cj.jdbc.Driver
测试:
package com.haogenmin.democ;
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;
/**
* @author :HaoGenmin
* @Title :Test
* @date :Created in 2020/6/22 16:27
* @description:
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
DataSource datasource;
@org.junit.Test
public void test() throws SQLException {
System.out.println("datasource: " + datasource.getClass());
Connection connection = datasource.getConnection();
System.out.println(connection);
connection.close();
}
}
结果:
datasource: class com.zaxxer.hikari.HikariDataSource
2020-06-22 16:32:43.041 INFO 2800 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-06-22 16:32:43.235 INFO 2800 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
HikariProxyConnection@1842463725 wrapping com.mysql.cj.jdbc.ConnectionImpl@22a6e998
可知SpringBoot的默认数据源是HikariDataSource,这是一个性能和稳定性比C3P0更好的数据源。
JDBC自动配置原理
我们看一下配置文件类:
里面包含数据源配置的各种属性及注释。
再看DataSourceBuilder类。里面有以下两个方法。可以看到我们在不配置数据源的时候调用findType方法。
那findType方法什么作用呢?
可以看到它遍历 DATA_SOURCE_TYPE_NAMES 取到正确的值就返回。看一下DATA_SOURCE_TYPE_NAMES。
第一个就是hikari,因此默认数据源就是hikari了。
配置Druid连接池和监控管理
连接池的性能上面无疑是hikari更强的,但是阿里Druid数据源带有配套的监控系统,你可以实时的查看你数据库的负载,在访问峰值的时候如果数据库丢失的请求过多就要考虑读写分离或者分布式了。
1、导入依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.14</version>
</dependency>
2、Druid的全局配置
# SPRING
spring:
# 数据源配置 =================================================================================
datasource:
username: root
password: 123456
#使用 MySQL连接驱动是8.0以上,需要在Url后面加上时区, GMT%2B8代表中国时区,不然报时区错误
url: jdbc:mysql://localhost:3306/springcloud_db01?serverTimezone=GMT%2B8
# 注意: 新版本驱动包,要使用以下类作为驱动类
driver-class-name: com.mysql.cj.jdbc.Driver
# 指定 Druid 数据源
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置, DataSourceProperties中没有相关属性,默认无法绑定 initialSize: 8
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,slf4j
maxPoolPreparedStatementPerConnectionSize: 25
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis:
configuration:
map-underscore-to-camel-case: true
3、配置类。
package com.haogenmin.democ.datasourceconfig;
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 javax.servlet.Filter;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author :HaoGenmin
* @Title :DataSourceConfig
* @date :Created in 2020/6/23 9:32
* @description:
*/
@Configuration
public class DataSourceConfig {
//绑定数据源配置
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid() {
return new DruidDataSource();
}
/**
* 配置Druid监控
* 1. 配置一个管理后台的Servlet
* 2. 配置一个监控的filter
*/
@Bean // 1. 配置一个管理后台的Servlet
public ServletRegistrationBean statViewServlet() {
//StatViewServlet是 配置管理后台的servlet
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//配置初始化参数
Map<String, String> initParam = new HashMap<>();
//访问的用户名密码
initParam.put(StatViewServlet.PARAM_NAME_USERNAME, "admin");
initParam.put(StatViewServlet.PARAM_NAME_PASSWORD, "123456");
//允许访问的ip,默认所有ip访问
initParam.put(StatViewServlet.PARAM_NAME_ALLOW, "127.0.0.1");
//禁止访问的ip
initParam.put(StatViewServlet.PARAM_NAME_DENY, "192.168.10.1");
bean.setInitParameters(initParam);
return bean;
}
//2. 配置一个监控的filter
@Bean
public FilterRegistrationBean filter() {
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
//配置初始化参数
Map<String, String> initParam = new HashMap<>();
initParam.put(WebStatFilter.PARAM_NAME_EXCLUSIONS, "*.js,*.css,/druid/*"); //拦截所有请求
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
4、测试
我们随便访问一下数据库,可以看到数据源的工作详情
此外,这几个功能也是很好用
Mybatis注解
springboot默认就是支持Mybatis注解开发的,很明显注解开发mapper更便捷。
使用方法:
1、写mapper,只需要写对应的注解就可以了,例如:
@Select("select * from product where pid = #{pid}")
Product findProductById(Integer pid);
@Update("update provider set providerName=#{providerName} where pid=#{pid}" )
int updateProvider(Provider provider);
@Delete("delete from provider where pid=#{pid}")
int deleteProviderByPid(Integer pid);
//useGeneratedKeys是否使用自增主键,keyProperty指定实体类中的哪一个属性封装主键值 @Options(useGeneratedKeys = true, keyProperty = "pid")
@Insert("insert into provider(providerName) values(#{providerName})")
int addProvider(Provider provider);
2、对于mapper接口要标注解或者用@MapperScan("mapper所在的包")扫描,二者取其一,例如:
这里@Component可以不写,有的会报红,但是不影响,强迫症还是加上组件注解。
或者
@MapperScan注解写在应用这里可以,写在配置类上也可以,只要起作用的地方都可以。
3、最后注意开启驼峰命名
这样:
或者这样:
@org.springframework.context.annotation.Configuration
public class MyBatisConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return new ConfigurationCustomizer(){
@Override
public void customize(Configuration configuration) {
//开启驼峰命名方式
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
}