当前位置: 首页 > 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.sadfv.cn/news/217627/

相关文章:

  • 建设银行北京招聘网站房产信息官网查询
  • 电子商务网站建设影响因素一般做外单的有哪些网站
  • 景安 怎么把网站做别名网页培训机构
  • 织梦做中英文网站步骤绍兴越城区建设局网站
  • 塑胶包装东莞网站建设青岛外贸网站制作
  • 户网站建设的不全.炫酷的国外网站
  • 朔州网站建设费用营销系统官网
  • 网站建设绩效考核学生网站建设实训报告
  • 网站搭建合同范本海南住房和城乡建设网站
  • 台州建站模板搭建想做一个自己的网站 怎么做
  • c网站开发案例详解制作简易网站模板
  • 榆林网站建设电话wordpress 模板 排名
  • 国际网站怎么做优化网站加速器手机版
  • 网站开发常用中间件新闻发布会主持词
  • 桂林网站开发怎样开网店详细教程
  • 关键词采集网站在外国做玄幻小说网站
  • 深圳便宜建网站购物网站的前台用什么做
  • 给公司创建网站流程阿里域名购买
  • 北京建设银行官方网站苏州网站制作工作室
  • 优化网站排名解析推广wordpress破解管理员密码
  • 长春做网站长春网站设计网站视觉艺术设计及色彩搭配
  • wordpress做电影网站网站开发用电脑配置
  • 兰州网站建设设计wordpress用户名无效
  • 高端快速建站重大军事新闻最新消息
  • 织梦网站建设过程东莞百度seo
  • 跨境购物网站建设中职专业设计网站
  • 网站建设专家cmswordpress在线课程主题
  • 中文单页面网站模板免费下载三类人员 网站开发
  • 表单网站路由器带u盘接口的做网站
  • wordpress页面回收站个人兼职网站制作