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

佛山市和城乡建设局网站网站开发工程师面试题

佛山市和城乡建设局网站,网站开发工程师面试题,一元云淘网站开发,建设银行网站在哪设置查询密码[ Spring 动态数据源 动态数据源是什么#xff1f;它能解决什么#xff1f;#xff1f;#xff1f; 在实际的开发中#xff0c;同一个项目中使用多个数据源是很常见的场景。比如#xff0c;一个读写分离的项目存在主数据源与读数据源。 所谓动态数据源#xff0c;就…[ Spring 动态数据源 动态数据源是什么它能解决什么 在实际的开发中同一个项目中使用多个数据源是很常见的场景。比如一个读写分离的项目存在主数据源与读数据源。 所谓动态数据源就是通过Spring的一些配置来自动控制某段数据操作逻辑是走哪一个数据源。举个读写分离的例子项目中引用了两个数据源master、slave。通过Spring配置或扩展能力来使得一个接口中调用了查询方法会自动使用slave数据源。 一般实现这种效果可以通过 使用MapperScan注解指定某个包下的所有方法走固定的数据源这个比较死板些,会产生冗余代码到也可以达到效果可以作为临时方案使用; 使用注解AOPAbstractRoutingDataSource的形式来指定某个方法下的数据库操作是走那个数据源。 通过 Sharding-JDBC组件来实现需要引入外部依赖如果项目本身引用了该组件建议用这种方式实现 hr关键核心类 这里主要介绍通过注解AOPAbstractRoutingDataSource的联动来实现动态数据源的方式。 一切的起点是AbstractRoutingDataSource这个类此类实现了 DataSource 接口 public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {// .... 省略 ... Nullableprivate MapObject, Object targetDataSources;Nullableprivate MapObject, DataSource resolvedDataSources;public void setTargetDataSources(MapObject, Object targetDataSources) {this.targetDataSources targetDataSources;}public void setDefaultTargetDataSource(Object defaultTargetDataSource) {this.defaultTargetDataSource defaultTargetDataSource;}Overridepublic void afterPropertiesSet() {// 初始化 targetDataSources、resolvedDataSourcesif (this.targetDataSources null) {throw new IllegalArgumentException(Property targetDataSources is required);}this.resolvedDataSources new HashMap(this.targetDataSources.size());this.targetDataSources.forEach((key, value) - {Object lookupKey resolveSpecifiedLookupKey(key);DataSource dataSource resolveSpecifiedDataSource(value);this.resolvedDataSources.put(lookupKey, dataSource);});//加入Java开发交流君样756584822一起吹水聊天if (this.defaultTargetDataSource ! null) {this.resolvedDefaultDataSource resolveSpecifiedDataSource(this.defaultTargetDataSource);}}Overridepublic Connection getConnection() throws SQLException {return determineTargetDataSource().getConnection();}Overridepublic Connection getConnection(String username, String password) throws SQLException {return determineTargetDataSource().getConnection(username, password);}/*** Retrieve the current target DataSource. Determines the* {link #determineCurrentLookupKey() current lookup key}, performs* a lookup in the {link #setTargetDataSources targetDataSources} map,* falls back to the specified* {link #setDefaultTargetDataSource default target DataSource} if necessary.* see #determineCurrentLookupKey()*/protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, DataSource router not initialized);// 1 startObject lookupKey determineCurrentLookupKey();DataSource dataSource this.resolvedDataSources.get(lookupKey);// 1 endif (dataSource null (this.lenientFallback || lookupKey null)) {dataSource this.resolvedDefaultDataSource;}if (dataSource null) {throw new IllegalStateException(Cannot determine target DataSource for lookup key [ lookupKey ]);}return dataSource;}/*** 返回一个key这个key用来从 resolvedDataSources 数据源中获取具体的数据源对象 见* //加入Java开发交流君样756584822一起吹水聊天 1*/Nullableprotected abstract Object determineCurrentLookupKey();}可以看到AbstractRoutingDataSource中有个可扩展抽象方法determineCurrentLookupKey()利用这个方法可以来实现动态数据源效果。 从零写一个简单动态数据源组件 从上一个part我们知道可以通过实现AbstractRoutingDataSource的 determineCurrentLookupKey() 方法动态设置一个key然后 在配置类下通过setTargetDataSources()方法设置我们提前准备好的DataSource Map。 注解常量定义 /*** author axin* Summary 动态数据源注解定义*/ Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface MyDS {String value() default default; }/*** author axin* Summary 动态数据源常量*/ public interface DSConst {String 默认 default;String 主库 master;String 从库 slave;String 统计 stat; } /*** author axin* Summary 动态数据源 ThreadLocal 工具*/ public class DynamicDataSourceHolder {//加入Java开发交流君样756584822一起吹水聊天//保存当前线程所指定的DataSourceprivate static final ThreadLocalString THREAD_DATA_SOURCE new ThreadLocal();public static String getDataSource() {return THREAD_DATA_SOURCE.get();}public static void setDataSource(String dataSource) {THREAD_DATA_SOURCE.set(dataSource);}public static void removeDataSource() {THREAD_DATA_SOURCE.remove();} }自定义一个AbstractRoutingDataSource类 /*** author axin* Summary 动态数据源*/ public class DynamicDataSource extends AbstractRoutingDataSource {/*** 从数据源中获取目标数据源的key* return*/Overrideprotected Object determineCurrentLookupKey() {// 从ThreadLocal中获取keyString dataSourceKey DynamicDataSourceHolder.getDataSource();if (StringUtils.isEmpty(dataSourceKey)) {return DSConst.默认;}return dataSourceKey;} }AOP实现 /*** author axin* Summary 数据源切换AOP*/ Slf4j Aspect Service public class DynamicDataSourceAOP {public DynamicDataSourceAOP() {log.info(/*---------------------------------------*/);log.info(/*---------- ----------*/);log.info(/*---------- 动态数据源初始化... ----------*/);log.info(/*---------- ----------*/);log.info(/*---------------------------------------*/);}/*** 切点*/Pointcut(value annotation(xxx.xxx.MyDS))private void method(){}/*** 方法执行前切换到指定的数据源* param point*/Before(method())public void before(JoinPoint point) {MethodSignature methodSignature (MethodSignature) point.getSignature();//获取被代理的方法对象Method targetMethod methodSignature.getMethod();//获取被代理方法的注解信息CultureDS cultureDS AnnotationUtils.findAnnotation(targetMethod, CultureDS.class);// 方法链条最外层的动态数据源注解优先级最高//加入Java开发交流君样756584822一起吹水聊天String key DynamicDataSourceHolder.getDataSource();if (!StringUtils.isEmpty(key)) {log.warn(提醒动态数据源注解调用链上出现覆盖场景请确认是否无问题);return;}if (cultureDS ! null ) {//设置数据库标志DynamicDataSourceHolder.setDataSource(MyDS.value());}}/*** 释放数据源*/AfterReturning(method())public void doAfter() {DynamicDataSourceHolder.removeDataSource();} }DataSourceConfig配置 通过以下代码来将动态数据源配置到 SqlSession 中去 /*** 数据源的一些配置主要是配置读写分离的sqlsession这里没有使用mybatis annotation* Configuration EnableTransactionManagement EnableAspectJAutoProxy class DataSourceConfig {/** 可读写的SQL Session */public static final String BEANNAME_SQLSESSION_COMMON sqlsessionCommon;/** 事务管理器的名称如果有多个事务管理器时需要指定beanName */public static final String BEANNAME_TRANSACTION_MANAGER transactionManager;/** 主数据源必须配置spring启动时会执行初始化数据操作无论是否真的需要选择查找DataSource class类型的数据源 配置通用数据源可读写连接的是主库 */BeanPrimaryConfigurationProperties(prefix datasource.common)public DataSource datasourceCommon() {// 数据源配置 可更换为其他实现方式return DataSourceBuilder.create().build();}/*** 动态数据源* returnr*/Beanpublic DynamicDataSource dynamicDataSource() {DynamicDataSource dynamicDataSource new DynamicDataSource();LinkedHashMapObject, Object hashMap Maps.newLinkedHashMap();hashMap.put(DSConst.默认, datasourceCommon());hashMap.put(DSConst.主库, datasourceCommon());hashMap.put(DSConst.从库, datasourceReadOnly());hashMap.put(DSConst.统计, datasourceStat());// 初始化数据源 MapdynamicDataSource.setTargetDataSources(hashMap);dynamicDataSource.setDefaultTargetDataSource(datasourceCommon());return dynamicDataSource;}/*** 配置事务管理器*/PrimaryBean(name BEANNAME_TRANSACTION_MANAGER)public DataSourceTransactionManager createDataSourceTransactionManager2() {DataSource dataSource this.dynamicDataSource();DataSourceTransactionManager manager new DataSourceTransactionManager(dataSource);return manager;}/*** 配置读写sqlsession*/PrimaryBean(name BEANNAME_SQLSESSION_COMMON)public SqlSession readWriteSqlSession() throws Exception {SqlSessionFactoryBean factory new SqlSessionFactoryBean();//加入Java开发交流君样756584822一起吹水聊天// 设置动态数据源factory.setDataSource(this.dynamicDataSource());PathMatchingResourcePatternResolver resolver new PathMatchingResourcePatternResolver();factory.setConfigLocation(resolver.getResource(mybatis/mybatis-config.xml));factory.setMapperLocations(resolver.getResources(mybatis/mappers/**/*.xml));return new SqlSessionTemplate(factory.getObject());} } 总结 综上利用AOP注解实现了一个简单的Spring动态数据源功能使用的时候仅需要在目标方法上加上 MyDS 注解即可。许多开源组件会在现有的基础上增加一个扩展功能比如路由策略等等。 顺便聊一下 sharding-jdbc 的实现方式更新写入类sql自动走主库查询类自动走读库如果是新项目无历史债务的话是可以使用该方案的。如果你是在原有旧的项目上进行读写分离改造那如果你使用了 sharding-jdbc 读写分离方案你就必须梳理已有代码逻辑中的sql调用情况来避免主从延迟造成数据不一致对业务的影响。 主从延迟造成读取数据不一致的情况是指主从在同步的时候是有一定的延迟时间的不管是什么网络的情况这个延迟的值都是存在的一般在毫秒级左右。这个时候如果使用sharding-jdbc进行读写分离处理进行实时数据插入并查询判断的时候就会出现判断异常的情况。 最后祝大家早日学有所成拿到满意offer
http://www.yutouwan.com/news/217627/

相关文章:

  • dede网站搬家教程什么网站专门做自由行的
  • 网站备案要关站吗多个域名指向同一个网站 备案
  • 内江做网站哪里便宜网站建设与管理 情况总结
  • 江苏南京建设厅网站音乐制作软件
  • 网站系统源代码郑州市做网站
  • 网站建设财务计划与预测软件开发学院
  • 网页升级紧急通知页面seo服务商
  • 域名网站负责人的责任wordpress每页不显示文章
  • 汇泽网站建设asp网站下载
  • 顺德网站建设要多少钱木藕设计网
  • 郑州手机网站搭建免费白嫖国外服务器app
  • 龙华响应式网站建设唐山哪个公司可以建网站
  • 烟台网站制作公司在线咨询怎么自己开发app软件
  • 网站友链查询接口梅州高铁
  • 电子商务如何做网站销售启航做网站好吗
  • 潍坊企业网站制作wordpress 链接失效
  • 沈阳做网站优秀公司制作图片工具
  • 电子商务企业网站建设计划书泰安网站建设泽讯
  • 百度网站官方认证怎么做温州网络推广平台建设
  • 济南网站建设q479185700惠网站开发的案例分析模板
  • 自己建的网站有乱码wordpress中文网站
  • 软文网站外包全球网站域名
  • 案例学 网页设计与网站建设关于房子的最新政策
  • php开源网站 网上商城卖房网站排名
  • 公司设计网站有哪些辽宁省网站备案注销
  • 中国建设规划采购网站公司培训网站需要广播证吗
  • 简易购物网站前端模板设计公司是做什么的
  • 南明区住房和城乡建设局网站上网站关键词快速排名
  • 福州网站建设新闻十大最好的网站
  • vue适合做门户网站吗服装订单接单网站