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

网站滑动效果怎么做南京今日新闻头条

网站滑动效果怎么做,南京今日新闻头条,wordpress企业网站开发,ping网站怎么做读写分离的作用是为了缓解写库,也就是主库的压力,但一定要基于数据一致性的原则,就是保证主从库之间的数据一定要一致。如果一个方法涉及到写的逻辑,那么该方法里所有的数据库操作都要走主库。 一、环境部署 数据库:…

读写分离的作用是为了缓解写库,也就是主库的压力,但一定要基于数据一致性的原则,就是保证主从库之间的数据一定要一致。如果一个方法涉及到写的逻辑,那么该方法里所有的数据库操作都要走主库。

一、环境部署

  • 数据库:MySql
  • 2个,一主一从
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`user_id` bigint(20) NOT NULL COMMENT '用户id',`user_name` varchar(255) DEFAULT '' COMMENT '用户名称',`user_phone` varchar(50) DEFAULT '' COMMENT '用户手机',`address` varchar(255) DEFAULT '' COMMENT '住址',`weight` int(3) NOT NULL DEFAULT '1' COMMENT '权重,大者优先',`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `user` VALUES ('1196978513958141952', '测试1', '18826334748', '广州市海珠区', '1', '2019-11-20 10:28:51', '2019-11-22 14:28:26');
INSERT INTO `user` VALUES ('1196978513958141953', '测试2', '18826274230', '广州市天河区', '2', '2019-11-20 10:29:37', '2019-11-22 14:28:14');
INSERT INTO `user` VALUES ('1196978513958141954', '测试3', '18826273900', '广州市天河区', '1', '2019-11-20 10:30:19', '2019-11-22 14:28:30');

二、依赖

<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>2.1.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><!-- 动态数据源 所需依赖 ### start--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><scope>provided</scope></dependency><!-- 动态数据源 所需依赖 ### end--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
</dependencies>

在这里插入图片描述

三、application.yml配置主从数据源

server:port: 8001
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Drivermaster:url: jdbc:mysql://127.0.0.1:3307/user?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=trueusername: rootpassword:slave:url: jdbc:mysql://127.0.0.1:3308/user?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=trueusername: rootpassword:

四、Config配置

@Getter
public enum DynamicDataSourceEnum {MASTER("master"),SLAVE("slave");private String dataSourceName;DynamicDataSourceEnum(String dataSourceName) {this.dataSourceName = dataSourceName;}
}
@Configuration
@MapperScan(basePackages = "com.xjt.proxy.mapper", sqlSessionTemplateRef = "sqlTemplate")
public class DataSourceConfig{//主库@Bean@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDb(){return DruidDataSourceBuilder.create().build();}//从库@Bean@ConditionalOnProperty(prefix = "spring.datasource", name = "slave", matchIfMissing = true)@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource slaveDb() {return DruidDataSourceBuilder.create().build();}//主从动态配置@Beanpublic DynamicDataSource dynamicDb(@Qualifier("masterDb") DataSource masterDataSource,@Autowired(required = false) @Qualifier("slaveDb") DataSource slaveDataSource){DynamicDataSource dynamicDataSource = new DynamicDataSource();Map<Object,Object> targetDataSources = new HashMap<>();targetDataSources.put(DynamicDataSourceEnum.MASTER.getDataSourceName(), masterDataSource);if(slaveDataSource != null){targetDataSources.put(DynamicDataSourceEnum.SLAVE.getDataSourceName(), slaveDataSource);}dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(masterDataSource);return dynamicDataSource;}@Beanpublic SqlSessionFactory sessionFactory(){SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*Mapper.xml"));bean.setDataSource(dynamicDataSource);return bean.getObject();}@Beanpublic SqlSessionTemplate sqlTemplate(){return new SqlSessionTemplate(sqlSessionFactory);}@Bean(name = "dataourceTx")public DataSourceTransactionManager dataSourceTx(){DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dynamicDataSource);return dataSourceTransactionManager;}
}

五、设置路由

为了方便查找对应的数据源,我们可以用ThreadLocal保存数据源的信息到每个线程中,方便我们需要时获取

pubic class DataSourceContextHolder{private static final ThreadLocal<String> DYNAMIC_DATASOURCE_CONTEXT = new ThreadLocal<>();public static void set(String datasourceType) {DYNAMIC_DATASOURCE_CONTEXT.set(datasourceType);}public static String get() {return DYNAMIC_DATASOURCE_CONTEXT.get();}public static void clear() {DYNAMIC_DATASOURCE_CONTEXT.remove();}
}

AbstractRoutingDataSource的作用是基于查找key路由到对应的数据源,它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.get();}
}

六、数据源的注解

方便切换数据源,注解中包含数据源对应的枚举值,默认是主库

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface DataSourceSelector {DynamicDataSourceEnum value() default DynamicDataSourceEnum.MASTER;boolean clear() default true;
}

七、Aop切换数据源

定义一个aop类,对有注解的方法做切换数据源的操作

@Slf4j
@Aspect
@Order(value = 1)
@Component
public class DataSourceContextAop {@Around("@annotation(com.xjt.proxy.dynamicdatasource.DataSourceSelector)")public Object setDynamicDataSource(ProceedingJoinPoint pjp) throws Throwable {boolean clear = true;try {Method method = this.getMethod(pjp);DataSourceSelector dataSourceImport = method.getAnnotation(DataSourceSelector.class);//获取注解标注的方法clear = dataSourceImport.clear();DataSourceContextHolder.set(dataSourceImport.value().getDataSourceName());log.info("========数据源切换至:{}", dataSourceImport.value().getDataSourceName());return pjp.proceed();} finally {if (clear) {DataSourceContextHolder.clear();}}}private Method getMethod(JoinPoint pjp) {MethodSignature signature = (MethodSignature)pjp.getSignature();return signature.getMethod();}}

八、测试

写好Service文件,包含读取和更新两个方法

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@DataSourceSelector(value = DynamicDataSourceEnum.SLAVE)public List<User> listUser() {List<User> users = userMapper.selectAll();return users;}@DataSourceSelector(value = DynamicDataSourceEnum.MASTER)public int update() {User user = new User();user.setUserId(Long.parseLong("1196978513958141952"));user.setUserName("修改后的名字2");return userMapper.updateByPrimaryKeySelective(user);}@DataSourceSelector(value = DynamicDataSourceEnum.SLAVE)public User find() {User user = new User();user.setUserId(Long.parseLong("1196978513958141952"));return userMapper.selectByPrimaryKey(user);}
}

根据方法上的注解可以看出,读的方法走从库,更新的方法走主库,更新的对象是userId为1196978513958141953 的数据

@RunWith(SpringRunner.class)
@SpringBootTest
class UserServiceTest {@AutowiredUserService userService;@Testvoid listUser() {List<User> users = userService.listUser();for (User user : users) {System.out.println(user.getUserId());System.out.println(user.getUserName());System.out.println(user.getUserPhone());}}@Testvoid update() {userService.update();User user = userService.find();System.out.println(user.getUserName());}
}

读取方法
在这里插入图片描述

更新方法
在这里插入图片描述
执行之后,比对数据库就可以发现主从库都修改了数据,说明我们的读写分离是成功的。当然,更新方法可以指向从库,这样一来就只会修改到从库的数据,而不会涉及到主库。

http://www.hengruixuexiao.com/news/56124.html

相关文章:

  • 网站做的比较好的郴州seo快速排名
  • 杭州网站开发企业小程序开发公司哪里强
  • 专业做网站排名多少钱友情链接分析
  • 郑州做网站优化的公司网站宣传费用
  • 天河高端网站建设湖南网站设计
  • 想学做电商怎么入手西安seo服务公司排名
  • 网站大型网页游戏长沙优化排名
  • 什么叫网站建设日程表优化大师兑换码
  • 伍佰亿搜索引擎网站系统seo培训资料
  • 怎么在网上开店网站建设推广优化
  • 在网站上可以做哪些互动活动学电脑办公软件培训班
  • 公众号可以做自己网站的超链接营销推广费用方案
  • 做电影网站需要什么手续今日热点新闻事件2021
  • 襄阳专业做网站信息发布推广平台
  • 对运营网站有什么见解新闻式软文范例
  • dw做存资料网站seo每日工作内容
  • 织梦网站优化怎么写网站
  • 山西做网站公司百度最新秒收录方法2022
  • 已经有了域名怎么做网站备案查询
  • 挂号网站制作怎么提高seo关键词排名
  • 天津免费做网站seo关键词排名网络公司
  • 如何入侵网站后台百度关键词搜索量排行
  • 邢台做网站信息百度指数排行榜
  • app开发制作网站平台谷歌seo推广公司
  • 企业网站源码网怎么注册自己的网站域名
  • 网站sem托管企业软文代写
  • 佛山网站建设是哪个百度网站打不开
  • 做美食推广的网站楚雄今日头条新闻
  • 极简网站设计网络宣传平台有哪些
  • 建筑挂靠网网站关键词搜索排名优化