(1)导入JDBC场景
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jdbcartifactId>
dependency>
<properties>
<java.version>1.8</java.version>
<mysql.version>5.1.49</mysql.version>
</properties>
(2)分析自动配置
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration
DataSourceTransactionManagerAutoConfiguration:事务管理器的自动配置
JdbcTemplateAutoConfiguration:JdbcTemplate的自动配置,可以来对数据库进行增删改查
JndiDataSourceAutoConfiguration: jndi 的自动配置
XADataSourceAutoConfiguration: 分布式事务相关的
(3)修改配置项 【就是我们需要对我们操作的数据库进行配置】
spring:
datasource:
url: jdbc:mysql://localhost:3306/smbms
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
(4)我们测试是否可以成功操作数据库
package com.atguigu.admin;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootTest
@Slf4j
class Boot05WebAdminApplicationTests {
@Autowired
JdbcTemplate jdbcTemplate;
@Test
void contextLoads() {
//查询表中的数据
// jdbcTemplate.queryForObject("select * from smbms_user");
// jdbcTemplate.queryForList("select * from smbms_user");
Long aLong = jdbcTemplate.queryForObject("select count(*) from smbms_user", Long.class);
log.info("记录总数: {}", aLong);
}
}
创建数据源
引入德鲁伊连接池的依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
下面这张图我想说明:如果我们在容器中没有自定义数据源,那么系统会给我们创建HikariDataSource数据源
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="20" />
<property name="initialSize" value="1" />
<property name="maxWait" value="60000" />
<property name="minIdle" value="1" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="20" />
在SpringBoot中,我们只需要通过 @ConfigurationProperties 指向我们的配置文件,就可以实现属性自动绑定
@Configuration
public class MyDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource")
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
}
StatViewServlet
StatViewServlet 的用途包括:
提供监控信息展示的html页面
提供监控信息的JSON API
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*
配置Druid的监控页功能
/**
* 配置druid的监控页功能
* @return
*/
@Bean
public ServletRegistrationBean statViewServlet() {
StatViewServlet statViewServlet = new StatViewServlet();
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
// 监控页账号密码
registrationBean.addInitParameter("loginUsername", "admin");
registrationBean.addInitParameter("loginPassword"," 123456");
return registrationBean;
}
StatFilter
用于统计监控信息:如果SQL监控、URI监控
需要给数据源中配置如下属性;可以允许多个filter,多个用,分割;如:
<property name="filters" value="stat,slf4j" />
慢SQL记录配置:
<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<property name="slowSqlMillis" value="10000" />
<property name="logSlowSql" value="true" />
</bean>
使用 slowSqlMillis 定义慢SQL的时长
引入 德鲁伊数据源的starter
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.17version>
dependency>
我们查看场景中的配置,分析一下SpringBoot为我们完成了哪些自动配置
@Configuration
@ConditionalOnClass({DruidDataSource.class})
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class, DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
DruidSpringAopConfiguration.class
DruidStatViewServletConfiguration.class
DruidWebStatFilterConfiguration.class
DruidFilterConfiguration.class
private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";
private static final String FILTER_WALL_CONFIG_PREFIX = "spring.datasource.druid.filter.wall.config";
接下来我们要演示具体是如何进行配置以及使用的
下面这个文件是我在项目的 application.yml 中进行配置的
spring:
datasource:
url: jdbc:mysql://localhost:3306/smbms
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
druid:
filters: stat,wall # 指定开启哪些功能[此处分别为 sql监控、防火墙]
stat-view-servlet: # 监控页功能
enabled: true
login-password: admin # 监控登录密码
login-username: admin # 监控登录账号
reset-enable: false
web-stat-filter: # web监控和uri监控
enabled: true
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' # 不指定默认就是这个
url-pattern: /*
aop-patterns: com.atguigu.admin.* # 监控这个包下的所有组件
filter: # 对于上面拦截器/过滤器的详细配置
stat:
slow-sql-millis: 1000 # 指定超过1s的查询都是慢查询
log-slow-sql: true # 是否开启慢查询日志记录功能
enabled: true
wall:
enabled: true
config:
delete-allow: false # 禁止删表操作
jdbc:
template:
query-timeout: 3
如果我们想来到druid的监控页
localhost:8080/druid/login.html
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
SpringBoot 底层为我们做了什么?
通过 @EnableConfigurationProperties注解实现与配置文件的绑定
@EnableConfigurationProperties(MybatisProperties.class) : MyBatis配置项绑定类。
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration{}
@ConfigurationProperties(prefix = "mybatis")
public class MybatisProperties
先看下一目录结构,了解都创建了哪些文件
# 配置mybatis的规则
mybatis:
# config-location: classpath:mybatis/mybatis-config.xml # 指定mybatis全局文件的位置
mapper-locations: classpath:mybatis/mapper/*.xml # 指定mybatis的sql映射文件位置
configuration:
map-underscore-to-camel-case: true # 通过配置文件的方式开启驼峰映射
接下来附上我们的各个文件
//AccountMapper 接口
package com.atguigu.admin.mapper;
import com.atguigu.admin.bean.Account;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Bonbons
* @version 1.0
*/
@Mapper
public interface AccountMapper {
public Account getAcct(Long id);
}
//AccountService类
package com.atguigu.admin.service;
import com.atguigu.admin.bean.Account;
import com.atguigu.admin.mapper.AccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Bonbons
* @version 1.0
*/
@Service
public class AccountService {
//注入操作数据库的对象
@Autowired
AccountMapper accountMapper;
public Account getAcctById(Long id){
return accountMapper.getAcct(id);
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.admin.mapper.AccountMapper">
<select id="getAcct" resultType="com.atguigu.admin.bean.Account">
select * from account_tbl where id = #{id}
select>
mapper>
<!--此处的目的是开启驼峰映射,以后大多就不设置mybatis的核心配置文件了-->
<?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"/>
</settings>
</configuration>
// City类
package com.atguigu.admin.bean;
import lombok.Data;
/**
* @author Bonbons
* @version 1.0
*/
@Data
public class City {
private Long id;
private String name;
private String state;
private String country;
}
// CityMapper接口
package com.atguigu.admin.mapper;
import com.atguigu.admin.bean.City;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @author Bonbons
* @version 1.0
*/
@Mapper
public interface CityMapper {
//不去编写sql映射文件了,而是直接在我们接口方法的上方通过注解来指定
@Select("select * from city where id = #{id}")
public City getById(Long id);
}
// CityService类
package com.atguigu.admin.service;
import com.atguigu.admin.bean.City;
import com.atguigu.admin.mapper.CityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Bonbons
* @version 1.0
*/
@Service
public class CityService {
//注入我们的mapper
@Autowired
CityMapper cityMapper;
public City getById(Long id){
return cityMapper.getById(id);
}
}
//控制器方法
//纯注解的方式
@Autowired
CityService cityService;
@GetMapping("/city")
@ResponseBody
public City getCityById(@RequestParam("id") Long id){
return cityService.getById(id);
}
什么情况下会混合 配置文件 + 注解的形式呢?
可以参考下面的这几部分代码:
// CityMapper接口
package com.atguigu.admin.mapper;
import com.atguigu.admin.bean.City;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @author Bonbons
* @version 1.0
*/
@Mapper
public interface CityMapper {
//不去编写sql映射文件了,而是直接在我们接口方法的上方通过注解来指定
@Select("select * from city where id = #{id}")
public City getById(Long id);
//这个不采用注解的方式,与配置文件结合使用完成插入功能
public void insert(City city);
}
// CityService类
package com.atguigu.admin.service;
import com.atguigu.admin.bean.City;
import com.atguigu.admin.mapper.CityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Bonbons
* @version 1.0
*/
@Service
public class CityService {
//注入我们的mapper
@Autowired
CityMapper cityMapper;
public City getById(Long id){
return cityMapper.getById(id);
}
public void saveCity(City city){
cityMapper.insert(city);
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.admin.mapper.AccountMapper">
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into city(`name`, `state`, `country`) values(#{name}, #{state}, #{country})
insert>
mapper>
//IndexController控制器
//纯注解的方式 >> 查询
@Autowired
CityService cityService;
@GetMapping("/city")
@ResponseBody
public City getCityById(@RequestParam("id") Long id){
return cityService.getById(id);
}
//注解+配置文件 >> 添加
@ResponseBody
@PostMapping("/city")
public City saveCity(City city){
cityService.saveCity(city);
return city;
}
//普通Java对象类
package com.atguigu.admin.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Bonbons
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
private Long id;
private String name;
private String state;
private String country;
}
我们也可以将第二种配置方式转为注解方式【内含配置项的注解用法】
@Insert("insert into city(`name`, `state`, `country`) values(#{name}, #{state}, #{country})")
@Options(useGeneratedKeys = true, keyProperty = "id")
public void insert(City city);
整体流程说明:
准备数据库表【我使用的是mysql的navicat】
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
引入mybatisPlus的starter
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.1version>
dependency>
package com.atguigu.admin.mapper;
import com.atguigu.admin.bean.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Bonbons
* @version 1.0
* 让我们的接口直接继承MyBatisPlus提供的BaseMapper
* 泛型为我们要操作的数据类型
*/
public interface UserMapper extends BaseMapper<User> {
}
package com.atguigu.admin.bean;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Bonbons
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
/**
* 正常所有的属性都应该与数据库表中的字段对应上
* 但是上面的userName和 password 我们暂时用不到,所以就通过注解暂时让他俩不在表中
*/
@TableField(exist = false)
private String userName;
@TableField(exist = false)
private String password;
//MyBatisPlus整合用的User对象为下面四个字段
private Long id;
private String name;
private Integer age;
private String email;
}
@Autowired
UserMapper userMapper;
@Test
void testUserMapper(){
User user = userMapper.selectById(1L);
log.info("用户信息: {}", user);
}
spring:
datasource:
url: jdbc:mysql://localhost:3306/smbms
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
druid:
filters: stat,wall # 指定开启哪些功能[此处分别为 sql监控、防火墙]
stat-view-servlet: # 监控页功能
enabled: true
login-password: admin # 监控登录密码
login-username: admin # 监控登录账号
reset-enable: false
web-stat-filter: # web监控和uri监控
enabled: true
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
url-pattern: /*
aop-patterns: com.atguigu.admin.* # 监控这个包下的所有组件
filter: # 对于上面拦截器/过滤器的详细配置
stat:
slow-sql-millis: 1000 # 指定超过1s的查询都是慢查询
log-slow-sql: true # 是否开启慢查询日志记录功能
enabled: true
wall:
enabled: true
config:
delete-allow: false # 禁止删表操作
jdbc:
template:
query-timeout: 3
# 配置mybatis的规则
mybatis:
# config-location: classpath:mybatis/mybatis-config.xml # 指定mybatis全局文件的位置
mapper-locations: classpath:mybatis/mapper/*.xml # 指定mybatis的sql映射文件位置
configuration:
map-underscore-to-camel-case: true # 通过配置文件的方式开启驼峰映射
接下来我们对 mybatis-plus 场景的自动配置进行分析
补充的其他知识点:
@Bean标记一个方法,如果参数是一个对象,这个参数就会从容器中自动确定这个组件
Ctrl + F12 查看类中有哪些方法 【IDEA快捷键】
只需要我们的Mapper继承 BaseMapper 就可以拥有crud能力 【当然我们如果有特殊的需求,也可以使用sql映射文件自定义】
零散知识点:
BaseMapper
默认对应数据库中的 user 表UserService
/**
* 继承顶级 Service
*/
public interface UserService extends IService<User> {
}
UserServiceImpl
package com.atguigu.admin.service.impl;
import com.atguigu.admin.bean.User;
import com.atguigu.admin.mapper.UserMapper;
import com.atguigu.admin.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author Bonbons
* @version 1.0
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
Controller
@GetMapping("/dynamic_table")
public String dynamic_table(Model model) {
// 从数据库中查出user表中的用户进行展示
List<User> list = userService.list();
model.addAttribute("users", list);
return "table/dynamic_table";
}
修改前端页面
<tr>
<th>#th>
<th>idth>
<th>nameth>
<th>agesth>
<th>emailth>
<th>操作th>
tr>
thead>
<tbody>
<tr class="gradeX" th:each="user,stat:${users}">
<td th:text="${stat.count}">Tridenttd>
<td th:text="${user.id}">idtd>
<td th:text="${user.name}">Internet
Explorer 4.0
td>
<td th:text="${user.age}">td>
<td class="center hidden-phone">[[${user.email}]]td>
<td class="center hidden-phone">Xtd>
tr>
效果演示
演示分页功能的使用:
@Configuration
public class MyBatisConfig {
/**
* MybatisPlusInterceptor
* @return
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// MyBatis-plus3.4版本以后的分页拦截器
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
paginationInnerInterceptor.setOverflow(true);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
paginationInnerInterceptor.setMaxLimit(500L);
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
在Controller中增加分页功能
@GetMapping("/dynamic_table")
public String dynamic_table(@RequestParam(value = "pn", defaultValue = "1") Integer pn, Model model) {
// 从数据库中查出user表中的用户进行展示
List<User> list = userService.list();
//model.addAttribute("users", list);
// 分页查询数据
Page<User> userPage = new Page<>(pn, 2);
// 分页查询的结果
Page<User> page = userService.page(userPage, null);
model.addAttribute("page", page);
return "table/dynamic_table";
}
修改前端页面,演示分页效果
<div class="row-fluid">
<div class="span6">
<div class="dataTables_info" id="dynamic-table_info">
当前第 [[${page.current}]] 页
总计 [[${page.pages}]] 页
共 [[${page.total}]] 条记录
div>
div>
<div class="span6">
<div class="dataTables_paginate paging_bootstrap pagination">
<ul>
<li class="prev disabled"><a href="#">← 前一页a>li>
<li th:class="${num == page.current?'active':''}"
th:each="num:${#numbers.sequence(1,page.pages)}">
<a th:href="@{/dynamic_table(pn=${num})}">[[${num}]]a>
li>
<li class="next disabled"><a href="#">下一页 → a>li>
ul>
div>
div>
div>
实现删除功能
增加删除的按钮:
<td>
<a
th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}"
class="btn btn-danger btn-sm"
type="button">
删除
a>
td>
设置控制器方法:
@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable("id") Long id,
@RequestParam(value = "pn", defaultValue = "1") Integer pn,
RedirectAttributes ra) {
userService.removeById(id);
ra.addAttribute("pn", pn);
return "redirect:/dynamic_table";
}
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
RedisTemplate
、StringRedisTemplate
【区别就是kv的类型不同,后者专门用于String】spring:
redis:
host: r-bp1nc7reqesxisgxpipd.redis.rds.aliyuncs.com
port: 6379
password: lfy:Lfy123456
@Autowired
StringRedisTemplate redisTemplate;
@Test
void testRedis() {
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello", "world");
String hello = operations.get("hello");
System.out.println(hello);
}
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
spring:
redis:
host: r-bp1nc7reqesxisgxpipd.redis.rds.aliyuncs.com
port: 6379
password: lfy:Lfy123456
client-type: jedis
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Test
void testRedis(){
// org.springframework.data.redis.connection.jedis.JedisConnectionFactory
System.out.println(redisConnectionFactory.getClass());
}
@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;
}
}
@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/**");
}
}
@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"); // 获取main.html页面访问的次数
String s1 = opsForValue.get("/sql"); // 获取sql请求访问的次数
model.addAttribute("mainCount", s);
model.addAttribute("sqlCount", s1);
return "main";
}
}
<div class="col-md-6 col-xs-12 col-sm-6">
<div class="panel purple">
<div class="symbol">
<i class="fa fa-gavel">i>
div>
<div class="state-value">
<div class="value" th:text="${mainCount}">230div>
<div class="title">/main.htmldiv>
div>
div>
div>
<div class="col-md-6 col-xs-12 col-sm-6">
<div class="panel red">
<div class="symbol">
<i class="fa fa-tags">i>
div>
<div class="state-value">
<div class="value" th:text="${sqlCount}">3490div>
<div class="title">/sqldiv>
div>
div>
div>