Spring Boot2.X+mybatis+Druid+PageHelper实现多数据源并分页,支持多个字段动态排序,结构层级分明,代码耦合,框架入门

Stella981
• 阅读 1099

一、SpringBoot整合Mybatis、Druid和PageHelper 并实现多数据源和分页,支持多个字段动态排序,其中对分页插件进行了封装,满足于任何场景的开发

Druid是一个数据库连接池。Druid可以说是目前最好的数据库连接池!因其优秀的功能、性能和扩展性方面,深受开发人员的青睐。

Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid是阿里巴巴开发的号称为监控而生的数据库连接池!

Druid的主要功能如下:

  • 是一个高效、功能强大、可扩展性好的数据库连接池。

  • 可以监控数据库访问性能。

  • 数据库密码加密

  • 获得SQL执行日志

  • 扩展JDBC

二、首先是Maven依赖 ​​​​​​,这里只贴部分依赖了,其他可以在本人gitee仓库获取  代码地址

_<_dependency_> _ _<_groupId_>com.github.pagehelper</_groupId_> _ _<_artifactId_>pagehelper-spring-boot-starter</_artifactId_> _ _<_version_>1.3.0</_version_> _ _</_dependency_> _

_<_dependency_> _ _<_groupId_>com.alibaba</_groupId_> _ _<_artifactId_>druid</_artifactId_> _ _<_version_>1.1.8</_version_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>mysql</_groupId_> _ _<_artifactId_>mysql-connector-java</_artifactId_> _ _<_version_>8.0.11</_version_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>org.mybatis.spring.boot</_groupId_> _ _<_artifactId_>mybatis-spring-boot-starter</_artifactId_> _ _<_version_>1.2.0</_version_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>org.springframework.boot</_groupId_> _ _<_artifactId_>spring-boot-starter</_artifactId_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>org.springframework.boot</_groupId_> _ _<_artifactId_>spring-boot-starter-web</_artifactId_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>com.alibaba</_groupId_> _ _<_artifactId_>druid-spring-boot-starter</_artifactId_> _ _<_version_>1.1.14</_version_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>log4j</_groupId_> _ _<_artifactId_>log4j</_artifactId_> _ _<_version_>1.2.17</_version_> _ _</_dependency_> _ _<_dependency_> _ _<_groupId_>org.apache.commons</_groupId_> _ _<_artifactId_>commons-lang3</_artifactId_> _ </_dependency_>

三、配置方面,主要的只需要在application.yml添加如下就可以了

server: port: 8080 tomcat: uri-encoding: utf-8

# 第一个数据源 默认数据源 master: datasource: driverClassName: com.mysql.cj.jdbc.Driver # _这里换成你的数据源 账号密码 _ url: jdbc:mysql://xxxxx:3306/hwswgp?useUnicode=true&characterEncoding=utf-8&&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8 username: xxxx password: xxxx # 第二个数据源 cluster: datasource: driverClassName: com.mysql.cj.jdbc.Driver # _这里换成你的数据源 账号密码 _ url: jdbc:mysql://xxxxx:3306/hwswioc?useUnicode=true&characterEncoding=utf-8&&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8 username: xxxx password: xxxxx # 连接池的配置信息 # 初始化大小,最小,最大 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 # _配置获取连接等待超时的时间 _ maxWait: 60000 # _配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 _ timeBetweenEvictionRunsMillis: 60000 # _配置一个连接在池中最小生存的时间,单位是毫秒 _ minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开__PSCache__,并且指定每个连接上__PSCache__的大小 _ poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的__filters__,去掉后监控界面__sql__无法统计,'wall'__用于防火墙 _ filters: stat,wall,log4j # _通过__connectProperties__属性来打开__mergeSql__功能;慢__SQL__记录 _ connectionProperties: druid: stat: mergeSql: true slowSqlMillis: 5000 logging: level: com: debug

四、成功添加了配置文件之后,我们再来编写Druid相关的类。

首先是MasterDataSourceConfig.java这个类,这个是默认的数据源配置类

package com.atxiaodei.pagehelp.mybatispagehelper.config; import com.alibaba.druid.pool.DruidDataSource; import com.github.pagehelper.PageInterceptor; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import java.util.Properties; /** _ * @author wangmeng _ * @date 2020/9/22 _ * 第一数据源配置类 _ **/ @Configuration @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourceConfig { _ // PACKAGE类型是public 主数据源 持久层就要扫描master包下 public static final String PACKAGE = "com.atxiaodei.pagehelp.mybatispagehelper.dao.master"; // 主数据源扫描master下面的 *.xml public static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml"; @Value("${master.datasource.url}") _ private String url; @Value_("${master.datasource.username}") _ private String username; @Value_("${master.datasource.password}") _ private String password; @Value_("${master.datasource.driverClassName}") _ private String driverClassName; @Value_("${spring.datasource.initialSize}") _ private int initialSize; @Value_("${spring.datasource.minIdle}") _ private int minIdle; @Value_("${spring.datasource.maxActive}") _ private int maxActive; @Value_("${spring.datasource.maxWait}") _ private int maxWait; @Value_("${spring.datasource.timeBetweenEvictionRunsMillis}") _ private int timeBetweenEvictionRunsMillis; @Value_("${spring.datasource.minEvictableIdleTimeMillis}") _ private int minEvictableIdleTimeMillis; @Value_("${spring.datasource.validationQuery}") _ private String validationQuery; @Value_("${spring.datasource.testWhileIdle}") _ private boolean testWhileIdle; @Value_("${spring.datasource.testOnBorrow}") _ private boolean testOnBorrow; @Value_("${spring.datasource.testOnReturn}") _ private boolean testOnReturn; @Value_("${spring.datasource.poolPreparedStatements}") _ private boolean poolPreparedStatements; @Value_("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}") _ private int maxPoolPreparedStatementPerConnectionSize; @Value_("${spring.datasource.filters}") _ private String filters; @Value_("{spring.datasource.connectionProperties}") _ private String connectionProperties; @Bean_(name = "masterDataSource") _ @Primary //标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。 public DataSource masterDataSource_() { _ DruidDataSource dataSource = new DruidDataSource_(); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); dataSource.setDriverClassName(driverClassName); //具体配置 dataSource.setInitialSize(initialSize); dataSource.setMinIdle(minIdle); dataSource.setMaxActive(maxActive); dataSource.setMaxWait(maxWait); dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); dataSource.setValidationQuery(validationQuery); dataSource.setTestWhileIdle(testWhileIdle); dataSource.setTestOnBorrow(testOnBorrow); dataSource.setTestOnReturn(testOnReturn); dataSource.setPoolPreparedStatements(poolPreparedStatements); dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); try { _ dataSource.setFilters(filters); } catch (SQLException e) { _ e.printStackTrace(); } _ dataSource.setConnectionProperties(connectionProperties); return dataSource; } _ @Bean(name = "masterTransactionManager") _ @Primary public DataSourceTransactionManager masterTransactionManager_() { _ return new DataSourceTransactionManager_(masterDataSource()); } @Bean(name = "masterSqlSessionFactory") _ @Primary public SqlSessionFactory masterSqlSessionFactory_(@Qualifier("masterDataSource")_ DataSource masterDataSource_) _ throws Exception { _ final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(masterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() _ .getResources_(MasterDataSourceConfig.MAPPER_LOCATION)); //分页插件 Interceptor interceptor = new PageInterceptor(); Properties properties = new Properties(); //数据库 properties.setProperty("helperDialect", "mysql"); //是否将参数offset作为PageNum使用 properties.setProperty("offsetAsPageNum", "true"); //是否进行count查询 properties.setProperty("rowBoundsWithCount", "true"); //是否分页合理化 properties.setProperty("reasonable", "false"); interceptor.setProperties(properties); sessionFactory.setPlugins(new Interceptor_[] {interceptor}); return sessionFactory.getObject_()_; } }

第二数据源前往gitee代码仓库查看    地址下载:代码地址

其中这两个注解说明下:

  • @Primary :标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean
    优先被考虑。多数据源配置的时候注意,必须要有一个主数据源,用 @Primary 标志该 Bean。

  • @MapperScan: 扫描 Mapper 接口并容器管理。

需要注意的是sqlSessionFactoryRef 表示定义一个唯一 SqlSessionFactory 实例。

_四、_上面的配置完之后,就可以将Druid作为连接池使用了。但是Druid并不简简单单的是个连接池,它也可以说是一个监控应用,它自带了web监控界面,可以很清晰的看到SQL相关信息。

在SpringBoot中运用Druid的监控作用,只需要编写StatViewServlet和WebStatFilter类,实现注册服务和过滤规则。这里我们可以将这两个写在一起,使用@Configuration和@Bean。

package com.atxiaodei.pagehelp.mybatispagehelper.config; import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import com.alibaba.druid.util.Utils; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 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.*; import java.io.IOException; /** _ * @author wangmeng _ * @date 2020/9/22 _ * druid__监控界面设置 _ **/ @Configuration @Slf4j public class DruidConfiguration { _ @Bean public ServletRegistrationBean druidStatViewServle() { _ //注册服务 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); // 白名单(为空表示,所有的都可以访问,多个IP的时候用逗号隔开) servletRegistrationBean.addInitParameter_("allow", "127.0.0.1"); // IP黑名单 (存在共同时,deny优先于allow) servletRegistrationBean.addInitParameter("deny", "127.0.0.2"); // 设置登录的用户名和密码 servletRegistrationBean.addInitParameter("loginUsername", "xiaodei"); servletRegistrationBean.addInitParameter("loginPassword", "123456"); // 是否能够重置数据. servletRegistrationBean.addInitParameter("resetEnable", "false"); return servletRegistrationBean; } @Bean public FilterRegistrationBean druidStatFilter() { _ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean_(new WebStatFilter()); // 添加过滤规则 filterRegistrationBean.addUrlPatterns("/*"); // 添加不需要忽略的格式信息 filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); log.info("druid初始化成功!")_; return filterRegistrationBean; }

/** _ * 去除监控页面底部的广告 _ */ _ @SuppressWarnings({ "rawtypes", "unchecked" }) _ @Bean @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") _ public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) _ { // 获取web监控页面的参数 DruidStatProperties.StatViewServlet config = properties.getStatViewServlet_(); // 提取common.js的配置路径 String pattern = config.getUrlPattern()_ != null ? config.getUrlPattern_()_ : "/druid/*"; String commonJsPattern = pattern.replaceAll_("\\*", "js/common.js"); final String filePath = "support/http/resources/js/common.js"; // 创建filter进行过滤 Filter filter = new Filter() _ { @Override public void init_(javax.servlet.FilterConfig filterConfig)_ throws ServletException { _ } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) _ throws IOException, ServletException { _ chain.doFilter(request, response); // 重置缓冲区,响应头不会被重置 response.resetBuffer(); // 获取common.js String text = Utils.readFromResource(filePath); // 正则替换banner, 除去底部的广告信息 text = text.replaceAll("<a.*?banner\">
", ""
); text = text.replaceAll("powered.*?shrek.wang", ""); response.getWriter().write(text); } @Override public void destroy() _ { } }; FilterRegistrationBean registrationBean = new FilterRegistrationBean_(); registrationBean.setFilter(filter); registrationBean.addUrlPatterns(commonJsPattern)_; return registrationBean; } }

五、项目中的代码目录结构

Spring Boot2.X+mybatis+Druid+PageHelper实现多数据源并分页,支持多个字段动态排序,结构层级分明,代码耦合,框架入门

结构层级分明,代码耦合,框架入门

成功写完配置之后,启动程序,进行测试。

Spring Boot2.X+mybatis+Druid+PageHelper实现多数据源并分页,支持多个字段动态排序,结构层级分明,代码耦合,框架入门

Spring Boot2.X+mybatis+Druid+PageHelper实现多数据源并分页,支持多个字段动态排序,结构层级分明,代码耦合,框架入门

详细查看代码地址:_代码地址_

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
SSH实现动态数据源切换,事务场景下使用AOP
上周写代码遇到了切换数据源的问题,在同一个方法中向两个不同数据源做一些操作,但是这个方法使用了事务,所以网上一般动态切换数据源的方法就失效了。框架是spirngmvchibernate,数据库是oracle,连接池druid。一般情况下,操作数据都是在DAO层进行处理。一种办法是使用多个DataSource然后创建多个SessionFa
Stella981 Stella981
3年前
SpringBoot 开启Druid监控统计功能教程
Druid数据连接池简介Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。性能好,同时自带监控页面,可以实时监控应用的连接池情况以及其中性能差的sql,方便我们找出应用中连接池方面的问题。Druid是一个JDBC组件,它包括三部分:1.DruidDriver代理
Easter79 Easter79
3年前
SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
1.前言本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。使用技术:SpringBoot、mybatis、shiro、thymeleaf、pagehelper、Mapper插件、druid、dataTables、ztree、jQuery开发工具:intellijidea数据库:mys
Stella981 Stella981
3年前
Spring Boot 集成 Mybatis 实现双数据源
这里用到了SpringBootMybatisDynamicDataSource配置动态双数据源,可以动态切换数据源实现数据库的读写分离。添加依赖加入Mybatis启动器,这里添加了Druid连接池、Oracle数据库驱动为例。<dependency<groupIdorg.mybatis.spring
Stella981 Stella981
3年前
Druid.jar包
首先了解一下,什么是Druid. Druid是Java语言中最好的数据库连接池,它能够提供强大的监控和扩展功能。 Druid是一个JDBC组件,它包括三部分: 1)DruidDriver代理Driver,能够提供基于Filter-Chain模式的插件体系。 2)DruidDataSource高效可管理的
Stella981 Stella981
3年前
SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
1.前言本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。使用技术:SpringBoot、mybatis、shiro、thymeleaf、pagehelper、Mapper插件、druid、dataTables、ztree、jQuery开发工具:intellijidea数据库:mys
可莉 可莉
3年前
0018SpringBoot连接docker中的mysql并使用druid数据源
由于druid数据源自带监控功能,所以引用druid数据源1、centos7中安装并启动docker2、docker安装并启动mysql3、pom.xml中引入druid依赖4、application.yml中配置数据库连接及druid数据源信息5、编写DruidConfig配置文件,绑定4中所配置的数据源信息6、编写HelloCon
Stella981 Stella981
3年前
Spring4.0 + druid 配置动态配置数据源以及多数据源切换功能实现
数据源连接池使用druid其他的数据源基本原理相同spring中配置默认数据源连接池如下:<!数据源配置,使用BoneCP数据库连接池   <beanid"dataSourceOne"class"com.alibaba.druid.pool.DruidDataSource"initmethod"
Stella981 Stella981
3年前
Spring Boot2.0 整合mybatis、分页插件、druid
前言本文主要是针对SpringBoot2.0.2版本,实现整合mybatis、分页插件、druid等组件,实现完整的web服务,提供restful风格接口。SpringBoot集成MyBatis有两种方式,一种简单的方式就是使用MyBatis官方提供的:一、mybatisspringbootstarter(本文讲解的)二、
弹性数据库连接池探活策略调研(二)——Druid | 京东云技术团队
前言在中,我们介绍了弹性数据库连接失效的背景,并探讨了HikariCP连接池探活策略的相关内容。在本文中,我们将会继续探讨另一个线上常用的连接池——Druid,并为您介绍如何在使用Druid时实现最佳实践的弹性数据库连接池探活策略。DruidDruid的版