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

时代网站管理系统怎么做网站个人介绍微电影网站模板

时代网站管理系统怎么做网站,个人介绍微电影网站模板,慈溪建设集团网站,服装定制官网1. 引言读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行#xff0c;至于谁来做选择数据库这件事儿#xff0c;无非两个#xff0c;要么中间件帮我们做#xff0c;要么程序自己做。因此#xff0c;一般来讲#xff0c;读写分离有两种实现方式。第一种是依靠中间…1. 引言读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行至于谁来做选择数据库这件事儿无非两个要么中间件帮我们做要么程序自己做。因此一般来讲读写分离有两种实现方式。第一种是依靠中间件(比如MyCat)也就是说应用程序连接到中间件中间件帮我们做SQL分离第二种是应用程序自己去做分离。这里我们选择程序自己来做主要是利用Spring提供的路由数据源以及AOP然而应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点因为数据源配置都是写在配置中的新增数据库意味着新加一个数据源必然改配置并重启应用。当然好处就是相对简单。2. AbstractRoutingDataSource基于特定的查找key路由到特定的数据源。它内部维护了一组目标数据源并且做了路由key与目标数据源之间的映射提供基于key查找数据源的方法。3. 实践3.1. maven依赖xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd4.0.0com.cjs.examplecjs-datasource-demo0.0.1-SNAPSHOTjarcjs-datasource-demoorg.springframework.bootspring-boot-starter-parent2.0.5.RELEASEUTF-8UTF-81.8org.springframework.bootspring-boot-starter-aoporg.springframework.bootspring-boot-starter-jdbcorg.springframework.bootspring-boot-starter-weborg.mybatis.spring.bootmybatis-spring-boot-starter1.3.2org.apache.commonscommons-lang33.8mysqlmysql-connector-javaruntimeorg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-maven-plugin3.2. 数据源配置application.ymlspring:datasource:master:jdbc-url: jdbc:mysql://192.168.102.31:3306/testusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverslave1:jdbc-url: jdbc:mysql://192.168.102.56:3306/testusername: pig # 只读账户password: 123456driver-class-name: com.mysql.jdbc.Driverslave2:jdbc-url: jdbc:mysql://192.168.102.36:3306/testusername: pig # 只读账户password: 123456driver-class-name: com.mysql.jdbc.Driver多数据源配置package com.cjs.example.config;import com.cjs.example.bean.MyRoutingDataSource;import com.cjs.example.enums.DBTypeEnum;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.boot.jdbc.DataSourceBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;/*** 关于数据源配置参考SpringBoot官方文档第79章《Data Access》* 79. Data Access* 79.1 Configure a Custom DataSource* 79.2 Configure Two DataSources*/Configurationpublic class DataSourceConfig {BeanConfigurationProperties(spring.datasource.master)public DataSource masterDataSource() {return DataSourceBuilder.create().build();}BeanConfigurationProperties(spring.datasource.slave1)public DataSource slave1DataSource() {return DataSourceBuilder.create().build();}BeanConfigurationProperties(spring.datasource.slave2)public DataSource slave2DataSource() {return DataSourceBuilder.create().build();}Beanpublic DataSource myRoutingDataSource(Qualifier(masterDataSource) DataSource masterDataSource,Qualifier(slave1DataSource) DataSource slave1DataSource,Qualifier(slave2DataSource) DataSource slave2DataSource) {Map targetDataSources new HashMap();targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);targetDataSources.put(DBTypeEnum.SLAVE2, slave2DataSource);MyRoutingDataSource myRoutingDataSource new MyRoutingDataSource();myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);myRoutingDataSource.setTargetDataSources(targetDataSources);return myRoutingDataSource;}}这里我们配置了4个数据源1个master2两个slave1个路由数据源。前3个数据源都是为了生成第4个数据源而且后续我们只用这最后一个路由数据源。MyBatis配置package com.cjs.example.config;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;import javax.sql.DataSource;EnableTransactionManagementConfigurationpublic class MyBatisConfig {Resource(name myRoutingDataSource)private DataSource myRoutingDataSource;Beanpublic SqlSessionFactory sqlSessionFactory() throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(myRoutingDataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath:mapper/*.xml));return sqlSessionFactoryBean.getObject();}Beanpublic PlatformTransactionManager platformTransactionManager() {return new DataSourceTransactionManager(myRoutingDataSource);}}由于Spring容器中现在有4个数据源所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。3.3 设置路由key / 查找数据源目标数据源就是那前3个这个我们是知道的但是使用的时候是如果查找数据源的呢首先我们定义一个枚举来代表这三个数据源package com.cjs.example.enums;public enum DBTypeEnum {MASTER, SLAVE1, SLAVE2;}接下来通过ThreadLocal将数据源设置到每个线程上下文中package com.cjs.example.bean;import com.cjs.example.enums.DBTypeEnum;import java.util.concurrent.atomic.AtomicInteger;public class DBContextHolder {private static final ThreadLocal contextHolder new ThreadLocal();private static final AtomicInteger counter new AtomicInteger(-1);public static void set(DBTypeEnum dbType) {contextHolder.set(dbType);}public static DBTypeEnum get() {return contextHolder.get();}public static void master() {set(DBTypeEnum.MASTER);System.out.println(切换到master);}public static void slave() {// 轮询int index counter.getAndIncrement() % 2;if (counter.get() 9999) {counter.set(-1);}if (index 0) {set(DBTypeEnum.SLAVE1);System.out.println(切换到slave1);}else {set(DBTypeEnum.SLAVE2);System.out.println(切换到slave2);}}}获取路由keypackage com.cjs.example.bean;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import org.springframework.lang.Nullable;public class MyRoutingDataSource extends AbstractRoutingDataSource {NullableOverrideprotected Object determineCurrentLookupKey() {return DBContextHolder.get();}}设置路由key默认情况下所有的查询都走从库插入/修改/删除走主库。我们通过方法名来区分操作类型(CRUD)package com.cjs.example.aop;import com.cjs.example.bean.DBContextHolder;import org.apache.commons.lang3.StringUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;AspectComponentpublic class DataSourceAop {Pointcut(!annotation(com.cjs.example.annotation.Master) (execution(* com.cjs.example.service..*.select*(..)) || execution(* com.cjs.example.service..*.get*(..))))public void readPointcut() {}Pointcut(annotation(com.cjs.example.annotation.Master) || execution(* com.cjs.example.service..*.insert*(..)) || execution(* com.cjs.example.service..*.add*(..)) || execution(* com.cjs.example.service..*.update*(..)) || execution(* com.cjs.example.service..*.edit*(..)) || execution(* com.cjs.example.service..*.delete*(..)) || execution(* com.cjs.example.service..*.remove*(..)))public void writePointcut() {}Before(readPointcut())public void read() {DBContextHolder.slave();}Before(writePointcut())public void write() {DBContextHolder.master();}/*** 另一种写法if...else... 判断哪些需要读从数据库其余的走主数据库*/// Before(execution(* com.cjs.example.service.impl.*.*(..)))// public void before(JoinPoint jp) {// String methodName jp.getSignature().getName();//// if (StringUtils.startsWithAny(methodName, get, select, find)) {// DBContextHolder.slave();// }else {// DBContextHolder.master();// }// }}有一般情况就有特殊情况特殊情况是某些情况下我们需要强制读主库针对这种情况我们定义一个主键用该注解标注的就读主库package com.cjs.example.annotation;public interface Master {}例如假设我们有一张表memberpackage com.cjs.example.service.impl;import com.cjs.example.annotation.Master;import com.cjs.example.entity.Member;import com.cjs.example.entity.MemberExample;import com.cjs.example.mapper.MemberMapper;import com.cjs.example.service.MemberService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.List;Servicepublic class MemberServiceImpl implements MemberService {Autowiredprivate MemberMapper memberMapper;TransactionalOverridepublic int insert(Member member) {return memberMapper.insert(member);}MasterOverridepublic int save(Member member) {return memberMapper.insert(member);}Overridepublic List selectAll() {return memberMapper.selectByExample(new MemberExample());}MasterOverridepublic String getToken(String appId) {// 有些读操作必须读主数据库// 比如获取微信access_token因为高峰时期主从同步可能延迟// 这种情况下就必须强制从主数据读return null;}}4. 测试package com.cjs.example;import com.cjs.example.entity.Member;import com.cjs.example.service.MemberService;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;RunWith(SpringRunner.class)SpringBootTestpublic class CjsDatasourceDemoApplicationTests {Autowiredprivate MemberService memberService;Testpublic void testWrite() {Member member new Member();member.setName(zhangsan);memberService.insert(member);}Testpublic void testRead() {for (int i 0; i 4; i) {memberService.selectAll();}}Testpublic void testSave() {Member member new Member();member.setName(wangwu);memberService.save(member);}Testpublic void testReadFromMaster() {memberService.getToken(1234);}}查看控制台5. 工程结构6. 参考https://www.jianshu.com/p/f2f4256a2310http://www.cnblogs.com/gl-developer/p/6170423.htmlhttps://www.cnblogs.com/huangjuncong/p/8576935.htmlhttps://blog.csdn.net/liu976180578/article/details/77684583推荐学习资料分享12 套 微服务、Spring Boot、Spring Cloud 核心技术资料这是部分资料目录Spring Security 认证与授权Spring Boot 项目实战(中小型互联网公司后台服务架构与运维架构)Spring Boot 项目实战(企业权限管理项目))Spring Cloud 微服务架构项目实战(分布式事务解决方案)...公众号后台回复arch028获取资料
http://www.zqtcl.cn/news/823230/

相关文章:

  • 做网站需注意事项会员卡管理系统下载
  • 嘉兴高端网站建设公司电子信息工程能进国家电网吗
  • 建网站 广州网站改版 理论
  • 门户网站简称昆明本地网站
  • 网站定位的核心意义离婚协议书模板 完整版
  • 网站首页改版方案长图制作网站
  • 网站的栏目有什么名字保定网络公司网站
  • 南京建设机械网站建设银行网站解除绑定
  • 厚街公司网站建设wordpress发邮件更新
  • wap网站制作网络设计公司经营范围
  • 织梦网站被做跳转还被删除文件第三方电子商务平台有哪些
  • 财经网站源码 织梦游戏ui培训
  • 石家庄站布局图网站建设公司怎么
  • 电商网站建设选迅法网东莞系统网站建设
  • 网站栏目 英文wordpress 情侣
  • 济南市历下区建设局官方网站wordpress 作者页
  • 武进建设银行网站首页大型网站建设哪家快
  • 做网站用vs怎么自己写代码做网站
  • 网站建设产品需求文档技术培训学校机构
  • 简单个人网站源码石景山网站seo优化排名
  • 用花生做网站房地产电子商务的网站建设
  • 宁波网站建设团队sem竞价托管多少钱
  • 工艺品东莞网站建设营销助手app
  • 怎么添加网站 多少钱wordpress 在线教育模板
  • 做鞋的垂直网站小型购物网站模板
  • 石家庄公司网站建设网站建设技术难点
  • 阿里云能放企业网站吗建设网站的建设费用包括什么
  • 网站对公司的作用是什么初学者学做网站用什么软件
  • 网站的建设模式高校后勤网站建设要求
  • 网站的导航栏怎么做的网站seo诊断报告怎么写