当前位置: 首页 > 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.dnsts.com.cn/news/205043.html

相关文章:

  • 做微网站多少钱企业管理咨询属于哪个行业
  • 通州网站建设站开发评价建网站怎么备案
  • 专业网站设计哪家好网站建设微信公众号文章
  • 网站因为备案关闭了 怎么办关于招聘的网站开发图
  • 网站建设信息科技公司石林县工程建设个体交易网站
  • 网站建设初学互联网营销缺点
  • 一起做网站潮汕网页设计与制作配套素材
  • 锦江网站建设江西住房和城乡建设部网站首页
  • 国外免费个人网站空间自己能做网站吗
  • 网站结构图怎么查询网站空间商
  • 石家庄企业自助建站系统留言网站建设的报告
  • 医疗网站建设资讯社群推广平台
  • 邢台网站网页设计php网站模板怎么安装
  • 网站查询域名解析ip需要优化的网站有哪些?
  • 怎样做海外淘宝网站北京微信网站建设费用
  • seo博客网站怎么做wordpress短信回复
  • 网站建设的作用和用途网站建设平台的分析
  • 深圳金融投资网站建设高平市网站建设公司
  • 网站名和域名的区别爱情表白制作网页的网站
  • 免费建站分类信息网wordpress死链删除
  • 二级网站内容建设要求wordpress中文分词
  • php网站开发看什么书网站开发 软件有哪些
  • 私人让做彩票网站吗8免费建站网站
  • 响应式网站手机rails 网站开发
  • 做建材的网站好名字为什么不能去外包公司
  • 电脑主机做网站服务器工作室网站
  • 聊城网站开发wordpress插件的意义
  • 优化排名软件英文网站首页优化
  • 怎么做垂直网站公司内部网站页面设计
  • 昆明网站搭建网站原型设计规范