首页 文章 精选 留言 我的

精选列表

搜索[整合],共10000篇文章
优秀的个人博客,低调大师

spring-boot整合hazelcast实现高频交易撮合引擎缓存部分入门级

简介:官网:https://hazelcast.com/一.可用性Hazelcast的分布式架构为连续群集正常运行时间提供冗余,并始终提供可用数据,以满足最苛刻的应用需求。容量随着需求弹性增长,而不会影响性能或可用性。二.速度Hazelcast In-Memory解决方案可以更快地补充数据库和数量级。时间就是金钱; 为您的新应用提供推动业务发展所需的微秒响应时间。将数据保留保留在数据库中,并利用Hazelcast以数字速度进行数据处理。三.用户体验在数字时代,用户不会等待。无论是复杂的电子商务交易还是机器学习驱动的客户自助服务门户,速度都是一切。Hazelcast客户实际上利用我们的速度在其微小的处理窗口中创造更多时间,以便在更多更深层次的服务中分层,创造卓越的商业价值,同时提供业界最佳的用户体验。四.风险缓解有足够的速度和规模,

优秀的个人博客,低调大师

Spring Boot wwwxjf555888com 2.0 整合Spring15012038888 Batch Java配置示例

学习使用Java配置创建Spring批处理作业(具有多个步骤)。它使用Spring Boot 2,Spring batch 4和H2数据库来执行批处理作业。 项目结构在这个项目中,我们将创建一个包含两步任务的简单作业,并执行作业以观察日志。工作执行流程将是 - 开始工作执行任务一执行任务二完成工作Spring Batch Java配置示例Maven依赖我们需要包含spring-boot-starter-batch依赖性。Spring批处理依赖于作为持久数据存储的作业存储库。所以我们也需要一个DB。我正在使用H2(内存数据库),它与弹簧批量很好地集成。pom.xml 复制 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mave

优秀的个人博客,低调大师

SpringBoot2.0.3整合Mybatis添加动态数据源实现多库查询(DynamicDataSource)

最近由于项目使用了spring boot 2.0.3版本,业务从多个数据查询,必须支持动态数据源,由于2.0.3的版本与之前的版本有了较大的改动其实现上有些不同,再采坑以后在此记录 1、需要Java类 DynamicDataSource.java package com.a.dynamic; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * 〈动态数据源〉 * * @author zhoukai7 * @create 7/27/18 * @since 1.0.0 */ public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDataSourceType(); } } DynamicDataSourceAspect.java package com.a.dynamic; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * 〈一句话功能简述〉<br> * 〈动态数据源切面〉 * * @author zhoukai7 * @create 7/27/18 * @since 1.0.0 */ @Aspect @Order(-1)// 保证该AOP在@Transactional之前执行 @Component public class DynamicDataSourceAspect { private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class); @Before("@annotation(ds)") public void changeDataSource(JoinPoint point, TargetDataSource ds) throws Throwable { String dsId = ds.name(); if (!DynamicDataSourceContextHolder.containsDataSource(dsId)) { logger.error("数据源[{}]不存在,使用默认数据源 > {}", ds.name(), point.getSignature()); } else { logger.debug("Use DataSource : {} > {}", ds.name(), point.getSignature()); DynamicDataSourceContextHolder.setDataSourceType(ds.name()); } } @After("@annotation(ds)") public void restoreDataSource(JoinPoint point, TargetDataSource ds) { logger.debug("Revert DataSource : {} > {}", ds.name(), point.getSignature()); DynamicDataSourceContextHolder.clearDataSourceType(); } } DynamicDataSourceContextHolder.java package com.a.dynamic; import java.util.ArrayList; import java.util.List; /** * 〈一句话功能简述〉<br> * 〈动态数据源句柄〉 * * @author zhoukai7 * @create 7/27/18 * @since 1.0.0 */ public class DynamicDataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static List<String> dataSourceIds = new ArrayList<>(); public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } public static String getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } /** * 判断指定DataSrouce当前是否存在 * * @param dataSourceId * @author zhoukai7 * @create 7/27/18 */ public static boolean containsDataSource(String dataSourceId){ return dataSourceIds.contains(dataSourceId); } } DynamicDataSourceRegister.java package com.a.dynamic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotationMetadata; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * 〈一句话功能简述〉<br> * 〈注册中心〉 * * @author zhoukai7 * @create 7/27/18 * @since 1.0.0 */ public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware { private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceRegister.class); //指定默认数据源(springboot2.0默认数据源是hikari如何想使用其他数据源可以自己配置) //org.apache.tomcat.jdbc.pool.DataSource private static final String DATASOURCE_TYPE_DEFAULT = "com.zaxxer.hikari.HikariDataSource"; //默认数据源 private DataSource defaultDataSource; //用户自定义数据源 private Map<String, DataSource> slaveDataSources = new HashMap<>(); @Override public void setEnvironment(Environment environment) { initDefaultDataSource(environment); initslaveDataSources(environment); } private void initDefaultDataSource(Environment env) { // 读取主数据源 Map<String, Object> dsMap = new HashMap<>(); dsMap.put("type", env.getProperty("spring.datasource.type")); dsMap.put("driver", env.getProperty("spring.datasource.driverClassName")); dsMap.put("url", env.getProperty("spring.datasource.url")); dsMap.put("username", env.getProperty("spring.datasource.username")); dsMap.put("password", env.getProperty("spring.datasource.password")); defaultDataSource = buildDataSource(dsMap); } private void initslaveDataSources(Environment env) { // 读取配置文件获取更多数据源 String dsPrefixs = env.getProperty("slave.datasource.names"); for (String dsPrefix : dsPrefixs.split(",")) { // 多个数据源 Map<String, Object> dsMap = new HashMap<>(); dsMap.put("type", env.getProperty("slave.datasource." + dsPrefix + ".type")); dsMap.put("driver", env.getProperty("slave.datasource." + dsPrefix + ".driverClassName")); dsMap.put("url", env.getProperty("slave.datasource." + dsPrefix + ".url")); dsMap.put("username", env.getProperty("slave.datasource." + dsPrefix + ".username")); dsMap.put("password", env.getProperty("slave.datasource." + dsPrefix + ".password")); DataSource ds = buildDataSource(dsMap); slaveDataSources.put(dsPrefix, ds); } } @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { Map<Object, Object> targetDataSources = new HashMap<Object, Object>(); //添加默认数据源 targetDataSources.put("dataSource", this.defaultDataSource); DynamicDataSourceContextHolder.dataSourceIds.add("dataSource"); //添加其他数据源 targetDataSources.putAll(slaveDataSources); for (String key : slaveDataSources.keySet()) { DynamicDataSourceContextHolder.dataSourceIds.add(key); } //创建DynamicDataSource GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(DynamicDataSource.class); beanDefinition.setSynthetic(true); MutablePropertyValues mpv = beanDefinition.getPropertyValues(); mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource); mpv.addPropertyValue("targetDataSources", targetDataSources); //注册 - BeanDefinitionRegistry beanDefinitionRegistry.registerBeanDefinition("dataSource", beanDefinition); logger.info("Dynamic DataSource Registry"); } public DataSource buildDataSource(Map<String, Object> dataSourceMap) { try { Object type = dataSourceMap.get("type"); if (type == null) { type = DATASOURCE_TYPE_DEFAULT;// 默认DataSource } Class<? extends DataSource> dataSourceType; dataSourceType = (Class<? extends DataSource>) Class.forName((String) type); String driverClassName = dataSourceMap.get("driver").toString(); String url = dataSourceMap.get("url").toString(); String username = dataSourceMap.get("username").toString(); String password = dataSourceMap.get("password").toString(); // 自定义DataSource配置 DataSourceBuilder factory = DataSourceBuilder.create().driverClassName(driverClassName).url(url) .username(username).password(password).type(dataSourceType); return factory.build(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } } TargetDataSource.java package com.a.dynamic; import java.lang.annotation.*; /** * 〈一句话功能简述〉<br> * 〈数据源注解类〉 * * @author zhoukai7 * @create 7/27/18 * @since 1.0.0 */ @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource { String name(); } 2、yml文件配置 application.yml # Tomcat server: tomcat: uri-encoding: UTF-8 max-threads: 1000 min-spare-threads: 30 port: 8012 servlet: session: timeout: 1800 context-path: / # spring spring: # 环境 dev|test|pro profiles: active: dev # datasource: # type: com.alibaba.druid.pool.DruidDataSource # driverClassName: com.mysql.jdbc.Driver # jackson时间格式化 jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss # 文件上传 servlet: multipart: enabled: true max-file-size: 100MB max-request-size: 100MB # 指定静态资源的路径 resources: static-locations: classpath:/static/,classpath:/views/ # Spring devtools devtools: restart: enabled: true thymeleaf: cache: false # Mybatis配置 #mybatis: # mapperLocations: classpath*:mapper/**/*.xml # configLocation: classpath:mybatis.xml #mybatis mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml #实体扫描,多个package用逗号或者分号分隔 typeAliasesPackage: com.asiainfo.**.entity global-config: #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; id-type: 0 #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" field-strategy: 2 #驼峰下划线转换 db-column-underline: true #刷新mapper 调试神器 refresh-mapper: true #数据库大写下划线转换 #capital-mode: true #序列接口实现类配置 #key-generator: com.baomidou.springboot.xxx #逻辑删除配置 logic-delete-value: 0 logic-not-delete-value: 1 #自定义填充策略接口实现 #meta-object-handler: com.baomidou.springboot.xxx #自定义SQL注入器 #sql-injector: com.baomidou.springboot.xxx configuration: map-underscore-to-camel-case: true cache-enabled: false application-dev.yml spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver # 添加&useSSL=true后会报错 url: jdbc:mysql://localhost:3309/aas?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8 username: root password: root #连接池的配置信息 initialSize: 10 minIdle: 10 maxActive: 100 # 配置获取连接等待超时的时间 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,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 slave: datasource: names: ds1,ds2 ds1: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver # 添加&useSSL=true后会报错 url: jdbc:mysql://localhost:3309/bbs?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10 username: root password: root #连接池的配置信息 initialSize: 10 minIdle: 10 maxActive: 100 # 配置获取连接等待超时的时间 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,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 ds2: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver # 添加&useSSL=true后会报错 url: jdbc:mysql://localhost:3309/dds?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10 username: root password: root #连接池的配置信息 initialSize: 10 minIdle: 10 maxActive: 100 # 配置获取连接等待超时的时间 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,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 #useGlobalDataSourceStat: true # redis: # host: 140.143.23.15 # port: 6379 # # Redis服务器连接密码(默认为空) # password: redis@root&hp # # Redis数据库索引(默认为0) # database: 1 # # 连接超时时间(毫秒) 2.0中需要suffix # timeout: 10000 # jedis: # pool: # # 连接池中的最大空闲连接 # max-idle: 50 # # 连接池中的最小空闲连接 # min-idle: 8 # # 连接池最大连接数(使用负值表示没有限制) # max-active: 1024 # # 连接池最大阻塞等待时间(使用负值表示没有限制) # max-wait: -1 upload: image: url: /data/image/release 3、使用方式 @TargetDataSource(name="ds1") @Override public List<Demo> queryList(){ Map<String,Object> map = new HashMap<>(); return demoDao.queryList(map); } @TargetDataSource(name="ds2") @Override public List<Demo> selectList(){ Map<String,Object> map = new HashMap<>(); return demoDao.queryList(map); } 说明:@TargetDataSource(name="ds2")只能添加在接口实现类上,而不能添加在接口上,推荐添加在service层的impl实现类上。 如果你的工程使用的mapper接口@Mapper public interface DemoDao extends BaseMapper<Demo> 则不能在此处使用@TargetDataSource,如果想要在持久层使用,必须有实现类。强烈推荐在service使用。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册