56、原生组件注入-原生注解与Spring方式注入 官方文档 - Servlets, Filters, and listeners
使用原生的注解 1 2 3 4 5 6 7 8 @WebServlet(urlPatterns = "/my") public class MyServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("66666" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Slf4j @WebFilter(urlPatterns={"/css/*","/images/*"}) public class MyFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { log.info("MyFilter初始化完成" ); } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info("MyFilter工作" ); chain.doFilter(request,response); } @Override public void destroy () { log.info("MyFilter销毁" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Slf4j @WebListener public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized (ServletContextEvent sce) { log.info("MySwervletContextListener监听到项目初始化完成" ); } @Override public void contextDestroyed (ServletContextEvent sce) { log.info("MySwervletContextListener监听到项目销毁" ); } }
最后还要在主启动类添加注解@ServletComponentScan
1 2 3 4 5 6 7 8 @ServletComponentScan(basePackages = "com.lun") @SpringBootApplication(exclude = RedisAutoConfiguration.class) public class Boot05WebAdminApplication { public static void main (String[] args) { SpringApplication.run(Boot05WebAdminApplication.class, args); } }
Spring方式注入 ServletRegistrationBean
, FilterRegistrationBean
, and ServletListenerRegistrationBean
1 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 @Configuration(proxyBeanMethods = true) public class MyRegistConfig { @Bean public ServletRegistrationBean myServlet () { MyServlet myServlet = new MyServlet (); return new ServletRegistrationBean (myServlet,"/my" ,"/my02" ); } @Bean public FilterRegistrationBean myFilter () { MyFilter myFilter = new MyFilter (); FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean (myFilter); filterRegistrationBean.setUrlPatterns(Arrays.asList("/my" ,"/css/*" )); return filterRegistrationBean; } @Bean public ServletListenerRegistrationBean myListener () { MySwervletContextListener mySwervletContextListener = new MySwervletContextListener (); return new ServletListenerRegistrationBean (mySwervletContextListener); } }
57、原生组件注入-【源码分析】DispatcherServlet注入原理 org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
配置类
1 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 62 63 64 65 66 67 68 69 70 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(DispatcherServlet.class) @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class) public class DispatcherServletAutoConfiguration { public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet" ; public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration" ; @Configuration(proxyBeanMethods = false) @Conditional(DefaultDispatcherServletCondition.class) @ConditionalOnClass(ServletRegistration.class) @EnableConfigurationProperties(WebMvcProperties.class) protected static class DispatcherServletConfiguration { @Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServlet dispatcherServlet (WebMvcProperties webMvcProperties) { DispatcherServlet dispatcherServlet = new DispatcherServlet (); dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest()); dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound()); dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents()); dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails()); return dispatcherServlet; } @Bean @ConditionalOnBean(MultipartResolver.class) @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) public MultipartResolver multipartResolver (MultipartResolver resolver) { return resolver; } } @Configuration(proxyBeanMethods = false) @Conditional(DispatcherServletRegistrationCondition.class) @ConditionalOnClass(ServletRegistration.class) @EnableConfigurationProperties(WebMvcProperties.class) @Import(DispatcherServletConfiguration.class) protected static class DispatcherServletRegistrationConfiguration { @Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServletRegistrationBean dispatcherServletRegistration (DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) { DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean (dispatcherServlet, webMvcProperties.getServlet().getPath()); registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup()); multipartConfig.ifAvailable(registration::setMultipartConfig); return registration; } } ... }
DispatcherServlet
默认映射的是 /
路径,可以通过在配置文件修改spring.mvc.servlet.path=/mvc
。
58、嵌入式Servlet容器-【源码分析】切换web服务器与定制化 默认支持的WebServer
Tomcat
, Jetty
, or Undertow
。ServletWebServerApplicationContext
容器启动寻找ServletWebServerFactory
并引导创建服务器。原理
SpringBoot应用启动发现当前是Web应用,web场景包-导入tomcat。 web应用会创建一个web版的IOC容器 ServletWebServerApplicationContext
。 ServletWebServerApplicationContext
启动的时候寻找 ServletWebServerFactory
(Servlet 的web服务器工厂——>Servlet 的web服务器)。SpringBoot底层默认有很多的WebServer工厂(ServletWebServerFactoryConfiguration
内创建Bean),如:TomcatServletWebServerFactory
JettyServletWebServerFactory
UndertowServletWebServerFactory
底层直接会有一个自动配置类ServletWebServerFactoryAutoConfiguration
。 ServletWebServerFactoryAutoConfiguration
导入了ServletWebServerFactoryConfiguration
(配置类)。ServletWebServerFactoryConfiguration
根据动态判断系统中到底导入了那个Web服务器的包。(默认是web-starter导入tomcat包),容器中就有 TomcatServletWebServerFactory
TomcatServletWebServerFactory
创建出Tomcat服务器并启动;TomcatWebServer
的构造器拥有初始化方法initialize——this.tomcat.start();
内嵌服务器,与以前手动把启动服务器相比,改成现在使用代码启动(tomcat核心jar包存在)。 Spring Boot默认使用Tomcat服务器,若需更改其他服务器,则修改工程pom.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > <exclusions > <exclusion > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-tomcat</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jetty</artifactId > </dependency >
官方文档 - Use Another Web Server
定制Servlet容器 xxxxxCustomizer
:定制化器,可以改变xxxx的默认规则
1 2 3 4 5 6 7 8 9 10 11 12 13 import org.springframework.boot.web.server.WebServerFactoryCustomizer;import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;import org.springframework.stereotype.Component;@Component public class CustomizationBean implements WebServerFactoryCustomizer <ConfigurableServletWebServerFactory> { @Override public void customize (ConfigurableServletWebServerFactory server) { server.setPort(9000 ); } }
59、定制化原理-SpringBoot定制化组件的几种方式(小结) 定制化的常见方式 1 2 3 @Configuration public class AdminWebConfig implements WebMvcConfigurer { }
@EnableWebMvc
+ WebMvcConfigurer
— @Bean
可以全面接管SpringMVC,所有规则全部自己重新配置; 实现定制和扩展功能(高级功能,初学者退避三舍 )。原理:WebMvcAutoConfiguration
默认的SpringMVC的自动配置功能类,如静态资源、欢迎页等。一旦使用 @EnableWebMvc
,会@Import(DelegatingWebMvcConfiguration.class)
。 DelegatingWebMvcConfiguration
的作用,只保证SpringMVC最基本的使用把所有系统中的WebMvcConfigurer
拿过来,所有功能的定制都是这些WebMvcConfigurer
合起来一起生效。 自动配置了一些非常底层的组件,如RequestMappingHandlerMapping
,这些组件依赖的组件都是从容器中获取如。 public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
。WebMvcAutoConfiguration
里面的配置要能生效必须 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
。@EnableWebMvc 导致了WebMvcAutoConfiguration 没有生效。 原理分析套路 场景starter - xxxxAutoConfiguration
- 导入xxx组件 - 绑定xxxProperties
- 绑定配置文件项。
60、数据访问-数据库场景的自动配置分析与整合测试 导入JDBC场景 1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-jdbc</artifactId > </dependency >
接着导入数据库驱动包(MySQL为例)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <mysql.version > 8.0.22</mysql.version > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <properties > <java.version > 1.8</java.version > <mysql.version > 5.1.49</mysql.version > </properties >
相关数据源配置类 DataSourceAutoConfiguration
: 数据源的自动配置。
修改数据源相关的配置:spring.datasource
。 数据库连接池的配置,是自己容器中没有DataSource才自动配置的 。底层配置好的连接池是:HikariDataSource
。 DataSourceTransactionManagerAutoConfiguration
: 事务管理器的自动配置。
JdbcTemplateAutoConfiguration
: JdbcTemplate
的自动配置,可以来对数据库进行CRUD。
可以修改前缀为spring.jdbc
的配置项来修改JdbcTemplate
。 @Bean @Primary JdbcTemplate
:Spring容器中有这个JdbcTemplate
组件,使用@Autowired
。JndiDataSourceAutoConfiguration
: JNDI的自动配置。
XADataSourceAutoConfiguration
: 分布式事务相关的。
修改配置项 1 2 3 4 5 6 spring: datasource: url: jdbc:mysql://localhost:3306/db_account username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver
单元测试数据源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 class Boot05WebAdminApplicationTests { @Autowired JdbcTemplate jdbcTemplate; @Test void contextLoads () { Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl" , Long.class); log.info("记录总数:{}" ,aLong); } }
61、数据访问-自定义方式整合druid数据源 Druid官网
Druid是什么? 它是数据库连接池,它能够提供强大的监控和扩展功能。
官方文档 - Druid连接池介绍
Spring Boot整合第三方技术的两种方式:
自定义方式 添加依赖 :
1 2 3 4 5 <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.17</version > </dependency >
配置Druid数据源 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public class MyConfig { @Bean @ConfigurationProperties("spring.datasource") public DataSource dataSource () throws SQLException { DruidDataSource druidDataSource = new DruidDataSource (); return druidDataSource; } }
更多配置项
配置Druid的监控页功能 :
1 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 @Configuration public class MyConfig { @Bean @ConfigurationProperties("spring.datasource") public DataSource dataSource () throws SQLException { DruidDataSource druidDataSource = new DruidDataSource (); druidDataSource.setFilters("stat,wall" ); return druidDataSource; } @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; } @Bean public FilterRegistrationBean webStatFilter () { WebStatFilter webStatFilter = new WebStatFilter (); FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean <>(webStatFilter); filterRegistrationBean.setUrlPatterns(Arrays.asList("/*" )); filterRegistrationBean.addInitParameter("exclusions" ,"*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" ); return filterRegistrationBean; } }
62、数据访问-druid数据源starter整合方式 官方文档 - Druid Spring Boot Starter
引入依赖 :
1 2 3 4 5 <dependency > <groupId > com.alibaba</groupId > <artifactId > druid-spring-boot-starter</artifactId > <version > 1.1.17</version > </dependency >
分析自动配置 :
扩展配置项 spring.datasource.druid
自动配置类DruidDataSourceAutoConfigure
DruidSpringAopConfiguration.class
, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
DruidStatViewServletConfiguration.class
, 监控页的配置。spring.datasource.druid.stat-view-servlet
默认开启。DruidWebStatFilterConfiguration.class
,web监控配置。spring.datasource.druid.web-stat-filter
默认开启。DruidFilterConfiguration.class
所有Druid的filter的配置:1 2 3 4 5 6 7 8 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" ;
配置示例 :
1 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 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.* filters: stat,wall stat-view-servlet: enabled: true login-username: admin login-password: admin resetEnable: false web-stat-filter: enabled: true urlPattern: /* exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' filter: stat: slow-sql-millis: 1000 logSlowSql: true enabled: true wall: enabled: true config: drop-table-allow: false
63、数据访问-整合MyBatis-配置版 MyBatis的GitHub仓库
MyBatis官方
starter的命名方式 :
SpringBoot官方的Starter:spring-boot-starter-*
第三方的: *-spring-boot-starter
引入依赖 :
1 2 3 4 5 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.1.4</version > </dependency >
配置模式 :
全局配置文件
SqlSessionFactory
:自动配置好了
SqlSession
:自动配置了SqlSessionTemplate
组合了SqlSession
@Import(AutoConfiguredMapperScannerRegistrar.class)
Mapper
: 只要我们写的操作MyBatis的接口标准了@Mapper
就会被自动扫描进来
1 2 3 4 5 6 7 8 9 10 @EnableConfigurationProperties(MybatisProperties.class) @AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class }) public class MybatisAutoConfiguration { ... }@ConfigurationProperties(prefix = "mybatis") public class MybatisProperties { ... }
配置文件 :
1 2 3 4 5 6 7 8 9 10 11 spring: datasource: username: root password: 1234 url: jdbc:mysql://localhost:3306/my driver-class-name: com.mysql.jdbc.Driver mybatis: config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/*.xml
mybatis-config.xml :
1 2 3 4 5 6 7 8 <?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 > </configuration >
Mapper接口 :
1 2 3 4 5 6 7 8 9 10 <?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 > </mapper >
1 2 3 4 5 6 7 import com.lun.boot.bean.User;import org.apache.ibatis.annotations.Mapper;@Mapper public interface UserMapper { public User getUser (Integer id) ; }
POJO :
1 2 3 4 5 6 public class User { private Integer id; private String name; }
DB :
1 2 3 4 5 CREATE TABLE `user ` ( `id` int (11 ) NOT NULL AUTO_INCREMENT, `name` varchar (45 ) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE= InnoDB AUTO_INCREMENT= 3 DEFAULT CHARSET= utf8mb4;
Controller and Service :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Controller public class UserController { @Autowired private UserService userService; @ResponseBody @GetMapping("/user/{id}") public User getUser (@PathVariable("id") Integer id) { return userService.getUser(id); } }
1 2 3 4 5 6 7 8 9 10 11 @Service public class UserService { @Autowired private UserMapper userMapper; public User getUser (Integer id) { return userMapper.getUser(id); } }
配置private Configuration configuration;
也就是配置mybatis.configuration
相关的,就是相当于改mybatis全局配置文件中的值。(也就是说配置了mybatis.configuration
,就不需配置mybatis全局配置文件了)
1 2 3 4 5 6 7 mybatis: mapper-locations: classpath:mybatis/mapper/*.xml configuration: map-underscore-to-camel-case: true
小结 导入MyBatis官方Starter。 编写Mapper接口,需@Mapper
注解。 编写SQL映射文件并绑定Mapper接口。 在application.yaml
中指定Mapper配置文件的所处位置,以及指定全局配置文件的信息 (建议:配置在mybatis.configuration
)。 64、数据访问-整合MyBatis-注解配置混合版 你可以通过Spring Initializr添加MyBatis的Starer。
注解与配置混合搭配,干活不累 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @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) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?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 >
1 2 3 4 5 6 7 8 9 @MapperScan("com.lun.boot.mapper") @SpringBootApplication public class MainApplication { public static void main (String[] args) { SpringApplication.run(MainApplication.class, args); } }
65、数据访问-整合MyBatisPlus操作数据库 IDEA的MyBatis的插件 - MyBatisX
MyBatisPlus官网
MyBatisPlus官方文档
MyBatisPlus是什么 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
添加依赖:
1 2 3 4 5 <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.4.1</version > </dependency >
MybatisPlusAutoConfiguration
配置类,MybatisPlusProperties
配置项绑定。
SqlSessionFactory
自动配置好,底层是容器中默认的数据源。
mapperLocations
自动配置好的,有默认值classpath*:/mapper/**/*.xml
,这表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件放在 mapper下。
容器中也自动配置好了SqlSessionTemplate
。
@Mapper
标注的接口也会被自动扫描,建议直接 @MapperScan("com.lun.boot.mapper")
批量扫描。
MyBatisPlus优点 之一:只需要我们的Mapper继承MyBatisPlus的BaseMapper
就可以拥有CRUD能力,减轻开发工作。
1 2 3 4 5 6 import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.lun.hellomybatisplus.model.User;public interface UserMapper extends BaseMapper <User> { }
66、数据访问-CRUD实验-数据列表展示 官方文档 - CRUD接口
使用MyBatis Plus提供的IService
,ServiceImpl
,减轻Service层开发工作。
1 2 3 4 5 6 7 8 9 10 11 import com.lun.hellomybatisplus.model.User;import com.baomidou.mybatisplus.extension.service.IService;import java.util.List;public interface UserService extends IService <User> { }
1 2 3 4 5 6 7 8 9 10 11 12 13 import com.lun.hellomybatisplus.model.User;import com.lun.hellomybatisplus.mapper.UserMapper;import com.lun.hellomybatisplus.service.UserService;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service public class UserServiceImpl extends ServiceImpl <UserMapper,User> implements UserService { }
与下一节联合在一起
67、数据访问-CRUD实验-分页数据展示 与下一节联合在一起
68、数据访问-CRUD实验-删除用户完成 添加分页插件:
1 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 @Configuration public class MyBatisConfig { @Bean public MybatisPlusInterceptor paginationInterceptor () { MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor (); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor (); paginationInnerInterceptor.setOverflow(true ); paginationInnerInterceptor.setMaxLimit(500L ); mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor); return mybatisPlusInterceptor; } }
1 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 <table class ="display table table-bordered table-striped" id ="dynamic-table" > <thead > <tr > <th > #</th > <th > name</th > <th > age</th > <th > email</th > <th > 操作</th > </tr > </thead > <tbody > <tr class ="gradeX" th:each ="user: ${users.records}" > <td th:text ="${user.id}" > </td > <td > [[${user.name}]]</td > <td th:text ="${user.age}" > Win 95+</td > <td th:text ="${user.email}" > 4</td > <td > <a th:href ="@{/user/delete/{id}(id=${user.id},pn=${users.current})}" class ="btn btn-danger btn-sm" type ="button" > 删除</a > </td > </tr > </tfoot > </table > <div class ="row-fluid" > <div class ="span6" > <div class ="dataTables_info" id ="dynamic-table_info" > 当前第[[${users.current}]]页 总计 [[${users.pages}]]页 共[[${users.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 == users.current?'active':''}" th:each ="num:${#numbers.sequence(1,users.pages)}" > <a th:href ="@{/dynamic_table(pn=${num})}" > [[${num}]]</a > </li > <li class ="next disabled" > <a href ="#" > 下一页 → </a > </li > </ul > </div > </div > </div >
#numbers
表示methods for formatting numeric objects.link
1 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 @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" ; }@GetMapping("/dynamic_table") public String dynamic_table (@RequestParam(value="pn",defaultValue = "1") Integer pn,Model model) { Page<User> page = new Page <>(pn, 2 ); Page<User> userPage = userService.page(page, null ); model.addAttribute("users" ,userPage); return "table/dynamic_table" ; }
69、数据访问-准备阿里云Redis环境 添加依赖 :
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-redis</artifactId > </dependency > <dependency > <groupId > redis.clients</groupId > <artifactId > jedis</artifactId > </dependency >
RedisAutoConfiguration
自动配置类,RedisProperties 属性类 --> spring.redis.xxx是对redis的配置。连接工厂LettuceConnectionConfiguration
、JedisConnectionConfiguration
是准备好的。 自动注入了RedisTemplate<Object, Object>
,xxxTemplate
。 自动注入了StringRedisTemplate
,key,value都是String 底层只要我们使用StringRedisTemplate
、RedisTemplate
就可以操作Redis。 外网Redis环境搭建 :
阿里云按量付费Redis,其中选择经典网络 。
申请Redis的公网连接地址。
修改白名单,允许0.0.0.0/0
访问。
70、数据访问-Redis操作与统计小实验 相关Redis配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 spring: redis: # url: redis: host: r-bp1nc7reqesxisgxpipd.redis.rds.aliyuncs.com port: 6379 password: lfy:Lfy123456 client-type: jedis jedis: pool: max-active: 10 # lettuce:# 另一个用来连接redis的java框架 # pool: # max-active: 10 # min-idle: 5
测试Redis连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @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()); } }
Redis Desktop Manager:可视化Redis管理软件。
URL统计拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @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(); redisTemplate.opsForValue().increment(uri); return true ; } }
注册URL统计拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @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/**" ); } }
Filter、Interceptor 几乎拥有相同的功能?
Filter是Servlet定义的原生组件,它的好处是脱离Spring应用也能使用。 Interceptor是Spring定义的接口,可以使用Spring的自动装配等功能。 调用Redis内的统计数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @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" ; } }