上一级页面:ssm-spring-boot速成学习索引
前言
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) : MyBatis配置项绑定类。 @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 几乎拥有相同的功能?
调用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"; } }
|
SpringBootWeb开发-9
spring-boot-单元测试
参考、引用、致谢