当前位置: 首页 > news >正文

姜堰做网站网页编辑软件有哪些?

姜堰做网站,网页编辑软件有哪些?,在线黑科技网站,网站 备案规定在复杂业务系统中#xff0c;多数据源切换已成为必备技能。本文将深入剖析三种主流实现方案#xff0c;带你从入门到精通#xff01; 一、多数据源应用场景 读写分离#xff1a;主库负责写操作#xff0c;从库处理读请求 多租户系统#xff1a;不同租户使用独立数据库 …在复杂业务系统中多数据源切换已成为必备技能。本文将深入剖析三种主流实现方案带你从入门到精通 一、多数据源应用场景 读写分离主库负责写操作从库处理读请求 多租户系统不同租户使用独立数据库 分库分表业务数据按规则分散存储 多数据库类型同时使用MySQL、Oracle等异构数据库 二、3种实现方案对比 方案实现复杂度侵入性维护成本适用场景AbstractRoutingDataSource中等高高简单读写分离多SqlSessionFactory高高高异构数据库dynamic-datasource低低低复杂多数据源 三、方案一AbstractRoutingDataSource 实现原理 通过继承Spring的AbstractRoutingDataSource类动态路由数据源 实现步骤 1. 添加依赖 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.27/version/dependency /dependencies 2. 配置多数据源 # application.yml spring:datasource:master:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: root123slave:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/slave_dbusername: rootpassword: root123 3. 动态数据源配置类 Configuration public class DataSourceConfig {BeanConfigurationProperties(spring.datasource.master)public DataSource masterDataSource() {return DataSourceBuilder.create().build();}BeanConfigurationProperties(spring.datasource.slave)public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}Beanpublic DataSource dynamicDataSource() {MapObject, Object targetDataSources new HashMap();targetDataSources.put(master, masterDataSource());targetDataSources.put(slave, slaveDataSource());DynamicDataSource dynamicDataSource new DynamicDataSource();dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(masterDataSource());return dynamicDataSource;} } 4. 自定义动态数据源 public class DynamicDataSource extends AbstractRoutingDataSource {Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceKey();}public static class DataSourceContextHolder {private static final ThreadLocalString contextHolder new ThreadLocal();public static void setDataSourceKey(String key) {contextHolder.set(key);}public static String getDataSourceKey() {return contextHolder.get();}public static void clearDataSourceKey() {contextHolder.remove();}} } 5. 自定义注解切换数据源 Target({ElementType.METHOD, ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface DataSource {String value() default master; } 6. AOP切面实现动态切换 Aspect Component public class DataSourceAspect {Before(annotation(dataSource))public void beforeSwitchDataSource(JoinPoint point, DataSource dataSource) {String dataSourceKey dataSource.value();DynamicDataSource.DataSourceContextHolder.setDataSourceKey(dataSourceKey);}After(annotation(dataSource))public void afterSwitchDataSource(JoinPoint point, DataSource dataSource) {DynamicDataSource.DataSourceContextHolder.clearDataSourceKey();} } 7. 业务层使用示例 Service public class UserService {Autowiredprivate JdbcTemplate jdbcTemplate;// 使用主库DataSource(master)public void createUser(User user) {String sql INSERT INTO users(name, email) VALUES(?, ?);jdbcTemplate.update(sql, user.getName(), user.getEmail());}// 使用从库DataSource(slave)public ListUser getAllUsers() {String sql SELECT * FROM users;return jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class));} } 方案优缺点 优点 纯Spring实现无第三方依赖 灵活控制数据源切换 缺点 事务管理复杂 需手动处理连接池 切换逻辑侵入业务代码 四、方案二多SqlSessionFactory 实现原理 为每个数据源创建独立的MyBatis SqlSessionFactory 实现步骤 1. 主数据源配置 Configuration MapperScan(basePackages com.example.mapper.master, sqlSessionFactoryRef masterSqlSessionFactory) public class MasterDataSourceConfig {BeanConfigurationProperties(spring.datasource.master)public DataSource masterDataSource() {return DataSourceBuilder.create().build();}Beanpublic SqlSessionFactory masterSqlSessionFactory(Qualifier(masterDataSource) DataSource dataSource) throws Exception {SqlSessionFactoryBean bean new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath:mapper/master/*.xml));return bean.getObject();}Beanpublic DataSourceTransactionManager masterTransactionManager(Qualifier(masterDataSource) DataSource dataSource) {return new DataSourceTransactionManager(dataSource);} } 2. 从数据源配置 Configuration MapperScan(basePackages com.example.mapper.slave, sqlSessionFactoryRef slaveSqlSessionFactory) public class SlaveDataSourceConfig {BeanConfigurationProperties(spring.datasource.slave)public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}Beanpublic SqlSessionFactory slaveSqlSessionFactory(Qualifier(slaveDataSource) DataSource dataSource) throws Exception {SqlSessionFactoryBean bean new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath:mapper/slave/*.xml));return bean.getObject();}Beanpublic DataSourceTransactionManager slaveTransactionManager(Qualifier(slaveDataSource) DataSource dataSource) {return new DataSourceTransactionManager(dataSource);} } 3. 业务层使用 Service public class OrderService {// 注入主库MapperAutowiredQualifier(masterOrderMapper)private OrderMapper masterOrderMapper;// 注入从库MapperAutowiredQualifier(slaveOrderMapper)private OrderMapper slaveOrderMapper;Transactional(transactionManager masterTransactionManager)public void createOrder(Order order) {masterOrderMapper.insert(order);}Transactional(transactionManager slaveTransactionManager)public Order getOrder(Long id) {return slaveOrderMapper.selectById(id);} } 方案优缺点 优点 各数据源完全隔离 事务管理清晰 支持异构数据库 缺点 配置复杂冗余代码多 Mapper需按数据源分包 动态切换不灵活 五、方案三dynamic-datasource框架 框架优势 零侵入通过注解实现数据源切换 功能丰富支持读写分离、分库分表等 简单易用简化多数据源配置 实现步骤 1. 添加依赖 dependencygroupIdcom.baomidou/groupIdartifactIddynamic-datasource-spring-boot-starter/artifactIdversion3.5.0/version /dependency 2. 配置数据源 spring:datasource:dynamic:primary: master # 默认数据源strict: false # 是否严格匹配数据源datasource:master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: root123slave1:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/slave_db1username: rootpassword: root123slave2:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/slave_db2username: rootpassword: root123oracle_db:driver-class-name: oracle.jdbc.OracleDriverurl: jdbc:oracle:thin:localhost:1521:orclusername: systempassword: oracle123 3. 使用DS注解切换数据源 Service public class ProductService {// 默认使用主库Autowiredprivate JdbcTemplate jdbcTemplate;// 使用主库DS(master)public void createProduct(Product product) {jdbcTemplate.update(INSERT INTO product(...) VALUES(...));}// 随机使用从库DS(slave)public Product getProduct(Long id) {return jdbcTemplate.queryForObject(SELECT * FROM product WHERE id ?, new BeanPropertyRowMapper(Product.class), id);}// 指定特定从库DS(slave1)public ListProduct getHotProducts() {return jdbcTemplate.query(SELECT * FROM product WHERE hot 1, new BeanPropertyRowMapper(Product.class));}// 使用Oracle数据库DS(oracle_db)public ListCategory getOracleCategories() {return jdbcTemplate.query(SELECT * FROM categories, new BeanPropertyRowMapper(Category.class));} } 4. 高级功能读写分离 spring:datasource:dynamic:primary: masterdatasource:master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://master-host:3306/dbusername: rootpassword: root123slave_1:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://slave1-host:3306/dbusername: rootpassword: root123slave_2:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://slave2-host:3306/dbusername: rootpassword: root123strategy: # 读写分离配置load-balance: # 负载均衡策略slave: round_robin # 从库轮询策略 5. 事务管理 DS(master) Transactional public void placeOrder(Order order) {// 1. 扣减库存productService.reduceStock(order.getProductId(), order.getQuantity());// 2. 创建订单orderMapper.insert(order);// 3. 记录日志logService.logOrder(order);// 所有操作都在主库事务中执行 } 最佳实践技巧 数据源分组管理 spring:datasource:dynamic:datasource:master_1: # 配置...master_2:# 配置...slave_1:# 配置...slave_2:# 配置...group:masters: master_1, master_2slaves: slave_1, slave_2 多租户数据源动态注册 Autowired private DynamicRoutingDataSource routingDataSource;public void addTenantDataSource(String tenantId, DataSourceProperty property) {DataSource dataSource dataSourceCreator.createDataSource(property);routingDataSource.addDataSource(tenantId, dataSource); } 自定义负载均衡策略 public class RandomStrategy implements LoadBalanceStrategy {Overridepublic String determineDataSource(ListString dataSourceNames) {Random random new Random();return dataSourceNames.get(random.nextInt(dataSourceNames.size()));} } 六、性能优化建议 连接池配置优化 spring:datasource:dynamic:datasource:master:# ...hikari:maximum-pool-size: 20minimum-idle: 5connection-timeout: 30000idle-timeout: 600000max-lifetime: 1800000 避免频繁切换数据源 将同一数据源操作集中处理 使用DSTransactional管理跨库事务 监控数据源状态 RestController public class DataSourceMonitor {Autowiredprivate DynamicRoutingDataSource routingDataSource;GetMapping(/datasources)public MapString, DataSource listDataSources() {return routingDataSource.getDataSources();}GetMapping(/datasources/stats)public MapString, Object getDataSourceStats() {MapString, Object stats new HashMap();routingDataSource.getDataSources().forEach((key, ds) - {if(ds instanceof HikariDataSource) {HikariDataSource hikari (HikariDataSource) ds;HikariPoolMXBean pool hikari.getHikariPoolMXBean();stats.put(key, Map.of(active, pool.getActiveConnections(),idle, pool.getIdleConnections(),total, pool.getTotalConnections()));}});return stats;} } 七、方案选型建议 中小型项目优先选用dynamic-datasource开发效率高 异构数据库系统选择多SqlSessionFactory方案隔离性好 需要高度定制AbstractRoutingDataSource提供最大灵活性 云原生环境dynamic-datasource Seata分布式事务 八、常见问题解决方案 数据源切换失效 检查方法是否被AOP代理 确保DS注解在public方法上 避免类内部方法调用 跨库事务问题 // 使用分布式事务 DS(order) GlobalTransactional public void createOrder(Order order) {// 操作订单库orderMapper.insert(order);// 操作库存库stockService.reduce(order.getProductId(), order.getQuantity()); } 连接泄露检测 Bean public DataSource dataSource(DataSourceProperties properties) {HikariDataSource dataSource properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();dataSource.setLeakDetectionThreshold(5000); // 5秒泄露检测return dataSource; } 九、结语 多数据源管理是现代应用开发的必备技能。通过本文介绍的三种方案 AbstractRoutingDataSourceSpring原生方案适合定制化场景 多SqlSessionFactory适合异构数据库系统 dynamic-datasource生产环境首选功能强大易用 最佳实践提示对于大多数Java项目推荐使用dynamic-datasource框架它提供了一站式的解决方案大大降低了多数据源管理的复杂度。同时结合Spring Cloud Alibaba Seata可轻松实现分布式事务管理。 扩展阅读 Spring官方文档数据访问 dynamic-datasource高级用法 MyBatis多数据源最佳实践 掌握多数据源切换技术让你的应用从容应对复杂数据场景
http://www.w-s-a.com/news/70241/

相关文章:

  • wordpress建站动画网站宣传的手段有哪些?(写出五种以上)
  • 做么网站有黄医疗机构网站备案
  • 企业年金是1比3还是1比4北京厦门网站优化
  • 政务信息网站建设工作方案云南建设工程质量监督网站
  • 如何做一份企业网站免费的短视频素材库
  • 云脑网络科技网站建设咸阳软件开发
  • seo对网站优化网站更换程序
  • 网站建设放什么科目中小学生在线做试卷的网站6
  • 网站建设推广公司排名绥化建设局网站
  • 凡科做的网站为什么打不开苏州行业网站建设
  • 南昌定制网站开发费用微信小商店官网入口
  • 深圳网站建设费用找人做的网站怎么看ftp
  • 做网站cookie传值dedecms网站后台
  • 温州网站推广网站建设要学会什么
  • c 网站开发框架品牌策划方案范文
  • 儿童摄影作品网站多元网络兰州网站建设
  • 电脑上不了建设厅网站常德网站建设费用
  • 做单页免费模板网站最新办公室装修风格效果图
  • 中国铁路建设投资公司网站熊学军想开网站建设公司
  • 优化一个网站多少钱网站开发北京
  • html教学关键词优化价格
  • 黄冈论坛网站有哪些给wordpress首页添加公告栏
  • 初中做数学题的网站做淘宝必备网站
  • 买拆车件上什么网站谁有那种手机网站
  • 一家专做有机蔬菜的网站万户网络是干嘛的
  • 十堰百度网站建设八宝山做网站公司
  • 地区电商网站系统建筑施工图纸培训班
  • 网站外包维护一年多少钱医院网站 功能
  • 电子商务市场的发展前景seo推广平台服务
  • 乐清网页设计公司哪家好seo推广任务小结