# 05.SpringBoot-数据访问
# 1.数据库场景的自动配置分析与整合测试
1.导入JDBC场景和驱动包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2
3
4
5
6
7
8
相关数据源配置:
DataSourceAutoConfiguration: 数据源的自动配置。- 修改数据源相关的配置:
spring.datasource。 - 数据库连接池的配置,是自己容器中没有DataSource才自动配置的。
- 底层配置好的连接池是:
HikariDataSource。
- 修改数据源相关的配置:
DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置。JdbcTemplateAutoConfiguration:JdbcTemplate的自动配置,可以来对数据库进行CRUD。可以修改前缀为
spring.jdbc的配置项来修改JdbcTemplate。@Bean @Primary JdbcTemplate:Spring容器中有这个JdbcTemplate组件,使用@Autowired。
JndiDataSourceAutoConfiguration: JNDI的自动配置。XADataSourceAutoConfiguration: 分布式事务相关的。
2.配置yml文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 1234
driver-class-name: com.mysql.jdbc.Driver
2
3
4
5
6
3.单元测试
@Slf4j
@SpringBootTest
public class WebAdminApplicationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void dataSourceTest() {
Long aLong = jdbcTemplate.queryForObject("select count(*) from admin", Long.class);
log.info("记录总数:{}",aLong);
}
}
2
3
4
5
6
7
8
9
10
11
# 2.整合(Druid)德鲁伊数据源
官方文档 - Druid连接池介绍 (opens new window)
Spring Boot整合第三方技术的两种方式:
自定义
找starter场景
# 1.自定义方式
1.引入数据源依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
</dependency>
2
3
4
5
2.配置数据源
@Configuration
public class myConfig{
@Bean
@ConfigurationProperties("spring.datasource")//复用配置文件的数据源配置
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
}
2
3
4
5
6
7
8
9
10
3.配置Druid的监控页功能
Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。这个StatViewServlet的用途包括:
提供监控信息展示的html页面
提供监控信息的JSON API
Druid内置提供一个StatFilter,用于统计监控信息。
WebStatFilter用于采集web-jdbc关联监控的数据,如SQL监控、URI监控。
Druid提供了WallFilter,它是基于SQL语义分析来实现防御SQL注入攻击的。
@Configuration
public class myConfig{
@Bean
@ConfigurationProperties("spring.datasource")//复用配置文件的数据源配置
public DataSource dataSource() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
//开启监控和防火墙功能
druidDataSource.setFilters("stat,wall");
return druidDataSource;
}
/**
* 配置 druid的监控页功能
* @return
*/
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean<Servlet> servletServletRegistrationBean = new ServletRegistrationBean<>();
servletServletRegistrationBean.setServlet(new StatViewServlet());
servletServletRegistrationBean.addUrlMappings("/druid/*");
return servletServletRegistrationBean;
}
/**
* WebStatFilter 用于采集web-jdbc关联监控的数据。
*/
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
/**
* 配置 Spring 方法监控 - 核心:补充切入点和切面(原代码缺失)
*/
// 注册 Druid Spring 监控拦截器
@Bean
public DruidStatInterceptor druidStatInterceptor() {
return new DruidStatInterceptor();
}
// 配置切入点(监控指定包下的 Spring Bean 方法,根据实际业务包调整)
@Bean
public JdkRegexpMethodPointcut druidStatPointcut() {
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
// 监控业务层所有方法(com.demo.boot 包下的所有类)
pointcut.setPatterns("com.demo.boot.*");
return pointcut;
}
// 注册切面
@Bean
public Advisor druidStatAdvisor() {
return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 2.Starter方式
1.引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.23</version>
</dependency>
2
3
4
5
2.分析自动配置项
扩展配置项
spring.datasource.druid自动配置类
DruidDataSourceAutoConfigureDruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patternsDruidStatViewServletConfiguration.class, 监控页的配置。spring.datasource.druid.stat-view-servlet默认开启。DruidWebStatFilterConfiguration.class,web监控配置。spring.datasource.druid.web-stat-filter默认开启。DruidFilterConfiguration.class所有Druid的filter的配置:
3.配置示例
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_account
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
druid:
aop-patterns: com.atguigu.admin.* #监控SpringBean
filters: stat,wall # 底层开启功能,stat(sql监控),wall(防火墙)
stat-view-servlet: # 配置监控页功能
enabled: true
login-username: admin
login-password: admin
resetEnable: false
web-stat-filter: # 监控web
enabled: true
urlPattern: /*
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
filter:
stat: # 对上面filters里面的stat的详细配置
slow-sql-millis: 1000
logSlowSql: true
enabled: true
wall:
enabled: true
config:
drop-table-allow: false
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 3.整合MyBatis
# 1.配置版
1.引入依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
2
3
4
5
配置模式:
全局配置文件
1)SqlSessionFactory:自动配置好了
2)SqlSession:自动配置了SqlSessionTemplate 组合了SqlSession
3)@Import(AutoConfiguredMapperScannerRegistrar.class)
- Mapper: 只要我们写的操作MyBatis的接口标准了@Mapper就会被自动扫描进来
@EnableConfigurationProperties(MybatisProperties.class) : MyBatis配置项绑定类。
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration{
...
}
@ConfigurationProperties(prefix = "mybatis")
public class MybatisProperties{
...
}
2
3
4
5
6
7
8
9
10
配置文件:
spring:
datasource:
username: root
password: 1234
url: jdbc:mysql://localhost:3306/my
driver-class-name: com.mysql.jdbc.Driver
# 配置mybatis规则
mybatis:
config-location: classpath:mybatis/mybatis-config.xml #全局配置文件位置
mapper-locations: classpath:mybatis/*.xml #sql映射文件位置
2
3
4
5
6
7
8
9
10
11
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>
<!-- 由于Spring Boot自动配置缘故,此处不必配置,只用来做做样。-->
</configuration>
2
3
4
5
6
7
8
配置mybatis.configuration相关的,就是相当于改mybatis全局配置文件中的值。(也就是说配置了mybatis.configuration,就不需配置mybatis全局配置文件了)
# 配置mybatis规则
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
# 可以不写全局配置文件,所有全局配置文件的配置都放在configuration配置项中了。
# config-location: classpath:mybatis/mybatis-config.xml
configuration:
map-underscore-to-camel-case: true
2
3
4
5
6
7
然后可以自己写个例子测试一下
# 2.注解混合版
示例:
@Mapper
public interface UserMapper {
public User getUser(Integer id);
@Select("select * from user where id=#{id}")
public User getUser2(Integer id);
public void saveUser(User user);
@Insert("insert into user(`name`) values(#{name})")
@Options(useGeneratedKeys = true, keyProperty = "id")
public void saveUser2(User user);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lun.boot.mapper.UserMapper">
<select id="getUser" resultType="com.lun.boot.bean.User">
select * from user where id=#{id}
</select>
<insert id="saveUser" useGeneratedKeys="true" keyProperty="id">
insert into user(`name`) values(#{name})
</insert>
</mapper>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
可用@MapperScan("com.lun.boot.mapper") 简化,Mapper接口就可以不用标注@Mapper注解。
@MapperScan("com.lun.boot.mapper")
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
2
3
4
5
6
7
8
9
# 4.整合MyBatisPlus操作数据库
MyBatisPlus官方文档 (opens new window)
# MyBatisPlus是什么
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
2
3
4
5
MybatisPlusAutoConfiguration配置类,MybatisPlusProperties配置项绑定。SqlSessionFactory自动配置好,底层是容器中默认的数据源。容器中也自动配置好了
SqlSessionTemplate。mapperLocations自动配置好的,有默认值classpath*:/mapper/**/*.xml,这表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件放在 mapper下。@Mapper标注的接口也会被自动扫描,建议直接@MapperScan("com.lun.boot.mapper")批量扫描。MyBatisPlus优点之一:只需要我们的Mapper继承MyBatisPlus的
BaseMapper就可以拥有CRUD能力,减轻开发工作。
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lun.hellomybatisplus.model.User;
public interface UserMapper extends BaseMapper<User> {
}
2
3
4
5
6
# 5.整合redis
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--导入jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2
3
4
5
6
7
8
9
10
RedisAutoConfiguration自动配置类,RedisProperties 属性类 --> spring.redis.xxx是对redis的配置。- 连接工厂
LettuceConnectionConfiguration、JedisConnectionConfiguration是准备好的。 - 自动注入了
RedisTemplate<Object, Object>,xxxTemplate。 - 自动注入了
StringRedisTemplate,key,value都是String - 底层只要我们使用
StringRedisTemplate、RedisTemplate就可以操作Redis。
小实验
1.配置redis
spring:
redis:
host: localhost
port: 6379
lettuce:
pool:
max-active: 8
max-idle: 10
min-idle: 1
time-between-eviction-runs: 10s
2
3
4
5
6
7
8
9
10
2.测试连接
@SpringBootTest
public class Boot05WebAdminApplicationTests {
@Autowired
StringRedisTemplate redisTemplate;
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello","world");
String hello = operations.get("hello");
System.out.println(hello);
System.out.println(redisConnectionFactory.getClass());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
3.URL统计拦截器:
@Component
public class RedisUrlCountInterceptor implements HandlerInterceptor {
@Autowired
StringRedisTemplate redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
//默认每次访问当前uri就会计数+1
redisTemplate.opsForValue().increment(uri);
return true;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
4.注册拦截器
@Configuration
public class AdminWebConfig implements WebMvcConfigurer{
@Autowired
RedisUrlCountInterceptor redisUrlCountInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(redisUrlCountInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**",
"/js/**","/aa/**");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Filter、Interceptor 几乎拥有相同的功能?
- Filter是Servlet定义的原生组件,它的好处是脱离Spring应用也能使用。
- Interceptor是Spring定义的接口,可以使用Spring的自动装配等功能。
5.调用Redis内的统计数据
@Slf4j
@Controller
public class IndexController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/main.html")
public String mainPage(HttpSession session,Model model){
log.info("当前方法是:{}","mainPage");
ValueOperations<String, String> opsForValue =
redisTemplate.opsForValue();
String s = opsForValue.get("/main.html");
String s1 = opsForValue.get("/sql");
model.addAttribute("mainCount",s);
model.addAttribute("sqlCount",s1);
return "main";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24