<del id="nnjnj"></del><track id="nnjnj"></track>

<p id="nnjnj"></p>

<address id="nnjnj"></address>

    <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

      <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>

      • 自動秒收錄
      • 軟件:1973
      • 資訊:57811|
      • 收錄網站:279872|

      IT精英團

      解決ShardingJdbc不支持復雜SQL問題的說明

      解決ShardingJdbc不支持復雜SQL問題的說明

      瀏覽次數:
      評論次數:
      編輯: 陽煦
      信息來源: ITPUB
      更新日期: 2022-09-10 08:53:20
      摘要

      背景介紹公司最近做分庫分表業務,接入了ShardingJDBC,接入完成后,回歸測試時發現好幾個SQL執行報錯,關鍵這幾個表都還不是分片表。報錯如下:這下糟了嘛。熟悉ShardingJDB

      • 正文開始
      • 相關閱讀
      • 推薦作品

      00-1010最近公司從事數據庫和表拆分業務,接入了分片JDBC。訪問完成后,在回歸測試中發現了幾個SQL執行錯誤,但關鍵是這些表不是碎片表。錯誤報告如下:

      這太可怕了。熟悉分片JDBC的學生應該知道它不支持許多SQL。官方截圖如下:

      修改這些復雜的SQL可能要花很多時間。那我該怎么辦?我們只能從哈丁JDBC身上找到突破口。經過兩天的研究,我們提出了以下解決方案,可以輕松解決哈丁JDBC不支持復雜SQL的問題。

      00-1010我在本地編寫了一個復雜的SQL進行測試:

      public ListMapString,Object queryOrder(){

      ListMapString,Object orders=border repository . find orders();

      退貨單;

      }

      公共接口BOrderRepository擴展JpaRepositoryBOrder,Long {

      @ query(value=' select * from(select id,當company _ id=1時為case,當company_id=4時為' small ',然后' in' ELSE' big' end ascom,user _ id作為userid from b _ order 0) t其中t.com=' middle ',nativeQuery=true)

      ListMapString,Object find orders();

      }

      我編寫了一個測試控制器來調用,它在調用后報告了一個錯誤。

      00-1010由于復雜SQL查詢的表不是碎片表,您能否在不分割JDBC的情況下指定這些復雜查詢的數據源?

      在注入分片JDBC數據源的地方做處理,注入一個用戶自定義的數據源,這樣我們在得到連接的時候就可以返回原生數據源了。此外,我們聲明一個注釋,如果注釋被識別,我們將返回原生數據源,否則,我們將返回Harding數據源

      背景介紹

      ,并編寫一個autoConfig類來替換ShardingShareToConfiguration類。

      /**

      *動態數據源核心自動配置類

      *

      *

      */

      @配置

      @ components can(' org . Apache . sharding sphere . spring . boot . converter ')

      @ EnableConfigurationProperties(springbootpropertiesconfiguration . class)

      @ condition alon property(prefix=' spring . sha

      rdingsphere", name = "enabled", havingValue = "true", matchIfMissing = true)@AutoConfigureBefore(DataSourceAutoConfiguration.class)public class DynamicDataSourceAutoConfiguration implements EnvironmentAware { private String databaseName; private final SpringBootPropertiesConfiguration props; private final Map<String, DataSource> dataSourceMap = new LinkedHashMap<>(); public DynamicDataSourceAutoConfiguration(SpringBootPropertiesConfiguration props) { this.props = props; } /** * Get mode configuration. * * @return mode configuration */ @Bean public ModeConfiguration modeConfiguration() { return null == props.getMode() ? null : new ModeConfigurationYamlSwapper().swapToObject(props.getMode()); } /** * Get ShardingSphere data source bean. * * @param rules rules configuration * @param modeConfig mode configuration * @return data source bean * @throws SQLException SQL exception */ @Bean @Conditional(LocalRulesCondition.class) @Autowired(required = false) public DataSource shardingSphereDataSource(final ObjectProvider<List<RuleConfiguration>> rules, final ObjectProvider<ModeConfiguration> modeConfig) throws SQLException { Collection<RuleConfiguration> ruleConfigs = Optional.ofNullable(rules.getIfAvailable()).orElseGet(Collections::emptyList); DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig.getIfAvailable(), dataSourceMap, ruleConfigs, props.getProps()); return new WrapShardingDataSource((ShardingSphereDataSource) dataSource,dataSourceMap); } /** * Get data source bean from registry center. * * @param modeConfig mode configuration * @return data source bean * @throws SQLException SQL exception */ @Bean @ConditionalOnMissingBean(DataSource.class) public DataSource dataSource(final ModeConfiguration modeConfig) throws SQLException { DataSource dataSource = !dataSourceMap.isEmpty() ? ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig, dataSourceMap, Collections.emptyList(), props.getProps()) : ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig); return new WrapShardingDataSource((ShardingSphereDataSource) dataSource,dataSourceMap); } /** * Create transaction type scanner. * * @return transaction type scanner */ @Bean public TransactionTypeScanner transactionTypeScanner() { return new TransactionTypeScanner(); } @Override public final void setEnvironment(final Environment environment) { dataSourceMap.putAll(DataSourceMapSetter.getDataSourceMap(environment)); databaseName = DatabaseNameSetter.getDatabaseName(environment); } @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @Bean @ConditionalOnProperty(prefix = "spring.datasource.dynamic.aop", name = "enabled", havingValue = "true", matchIfMissing = true) public Advisor dynamicDatasourceAnnotationAdvisor() { DynamicDataSourceAnnotationInterceptor interceptor = new DynamicDataSourceAnnotationInterceptor(true); DynamicDataSourceAnnotationAdvisor advisor = new DynamicDataSourceAnnotationAdvisor(interceptor, DS.class); return advisor; }}

      1. 自定義數據源

      public class WrapShardingDataSource extends AbstractDataSourceAdapter implements AutoCloseable{    private ShardingSphereDataSource dataSource;    private Map<String, DataSource> dataSourceMap;    public WrapShardingDataSource(ShardingSphereDataSource dataSource, Map<String, DataSource> dataSourceMap) {        this.dataSource = dataSource;        this.dataSourceMap = dataSourceMap;    }    public DataSource getTargetDataSource(){        String peek = DynamicDataSourceContextHolder.peek();        if(StringUtils.isEmpty(peek)){            return dataSource;        }        return dataSourceMap.get(peek);    }    @Override    public Connection getConnection() throws SQLException {        return getTargetDataSource().getConnection();    }    @Override    public Connection getConnection(final String username, final String password) throws SQLException {        return getConnection();    }    @Override    public void close() throws Exception {        DataSource targetDataSource = getTargetDataSource();        if (targetDataSource instanceof AutoCloseable) {            ((AutoCloseable) targetDataSource).close();        }    }    @Override    public int getLoginTimeout() throws SQLException {        DataSource targetDataSource = getTargetDataSource();        return targetDataSource ==null ?  : targetDataSource.getLoginTimeout();    }    @Override    public void setLoginTimeout(final int seconds) throws SQLException {        DataSource targetDataSource = getTargetDataSource();        targetDataSource.setLoginTimeout(seconds);    }}

      1. 聲明指定數據源注解

      @Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface DS {    /**     * 數據源名     */    String value();}

      1. 另外使用 AOP 的方式攔截使用了注解的類或方法,并且要將這些用了注解的方法存起來,在獲取數據源連接的時候取出來進行判斷。這就還要用到 ThreadLocal。

      aop 攔截器:

      public class DynamicDataSourceAnnotationInterceptor implements MethodInterceptor {    private final DataSourceClassResolver dataSourceClassResolver;    public DynamicDataSourceAnnotationInterceptor(Boolean allowedPublicOnly) {        dataSourceClassResolver = new DataSourceClassResolver(allowedPublicOnly);    }    @Override    public Object invoke(MethodInvocation invocation) throws Throwable {        String dsKey = determineDatasourceKey(invocation);        DynamicDataSourceContextHolder.push(dsKey);        try {            return invocation.proceed();        } finally {            DynamicDataSourceContextHolder.poll();        }    }    private String determineDatasourceKey(MethodInvocation invocation) {        String key = dataSourceClassResolver.findKey(invocation.getMethod(), invocation.getThis());        return key;    }}

      aop 切面定義:

      /** * aop Advisor */public class DynamicDataSourceAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {    private final Advice advice;    private final Pointcut pointcut;    private final Class<? extends Annotation> annotation;    public DynamicDataSourceAnnotationAdvisor(MethodInterceptor advice,                                               Class<? extends Annotation> annotation) {        this.advice = advice;        this.annotation = annotation;        this.pointcut = buildPointcut();    }    @Override    public Pointcut getPointcut() {        return this.pointcut;    }    @Override    public Advice getAdvice() {        return this.advice;    }    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        if (this.advice instanceof BeanFactoryAware) {            ((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);        }    }    private Pointcut buildPointcut() {        Pointcut cpc = new AnnotationMatchingPointcut(annotation, true);        Pointcut mpc = new AnnotationMethodPoint(annotation);        return new ComposablePointcut(cpc).union(mpc);    }    /**     * In order to be compatible with the spring lower than 5.0     */    private static class AnnotationMethodPoint implements Pointcut {        private final Class<? extends Annotation> annotationType;        public AnnotationMethodPoint(Class<? extends Annotation> annotationType) {            Assert.notNull(annotationType, "Annotation type must not be null");            this.annotationType = annotationType;        }        @Override        public ClassFilter getClassFilter() {            return ClassFilter.TRUE;        }        @Override        public MethodMatcher getMethodMatcher() {            return new AnnotationMethodMatcher(annotationType);        }        private static class AnnotationMethodMatcher extends StaticMethodMatcher {            private final Class<? extends Annotation> annotationType;            public AnnotationMethodMatcher(Class<? extends Annotation> annotationType) {                this.annotationType = annotationType;            }            @Override            public boolean matches(Method method, Class<?> targetClass) {                if (matchesMethod(method)) {                    return true;                }                // Proxy classes never have annotations on their redeclared methods.                if (Proxy.isProxyClass(targetClass)) {                    return false;                }                // The method may be on an interface, so let's check on the target class as well.                Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);                return (specificMethod != method && matchesMethod(specificMethod));            }            private boolean matchesMethod(Method method) {                return AnnotatedElementUtils.hasAnnotation(method, this.annotationType);            }        }    }}

      /** * 數據源解析器 * */public class DataSourceClassResolver {    private static boolean mpEnabled = false;    private static Field mapperInterfaceField;    static {        Class<?> proxyClass = null;        try {            proxyClass = Class.forName("com.baomidou.mybatisplus.core.override.MybatisMapperProxy");        } catch (ClassNotFoundException e1) {            try {                proxyClass = Class.forName("com.baomidou.mybatisplus.core.override.PageMapperProxy");            } catch (ClassNotFoundException e2) {                try {                    proxyClass = Class.forName("org.apache.ibatis.binding.MapperProxy");                } catch (ClassNotFoundException ignored) {                }            }        }        if (proxyClass != null) {            try {                mapperInterfaceField = proxyClass.getDeclaredField("mapperInterface");                mapperInterfaceField.setAccessible(true);                mpEnabled = true;            } catch (NoSuchFieldException e) {                e.printStackTrace();            }        }    }    /**     * 緩存方法對應的數據源     */    private final Map<Object, String> dsCache = new ConcurrentHashMap<>();    private final boolean allowedPublicOnly;    /**     * 加入擴展, 給外部一個修改aop條件的機會     *     * @param allowedPublicOnly 只允許公共的方法, 默認為true     */    public DataSourceClassResolver(boolean allowedPublicOnly) {        this.allowedPublicOnly = allowedPublicOnly;    }    /**     * 從緩存獲取數據     *     * @param method       方法     * @param targetObject 目標對象     * @return ds     */    public String findKey(Method method, Object targetObject) {        if (method.getDeclaringClass() == Object.class) {            return "";        }        Object cacheKey = new MethodClassKey(method, targetObject.getClass());        String ds = this.dsCache.get(cacheKey);        if (ds == null) {            ds = computeDatasource(method, targetObject);            if (ds == null) {                ds = "";            }            this.dsCache.put(cacheKey, ds);        }        return ds;    }    /**     * 查找注解的順序     * 1. 當前方法     * 2. 橋接方法     * 3. 當前類開始一直找到Object     * 4. 支持mybatis-plus, mybatis-spring     *     * @param method       方法     * @param targetObject 目標對象     * @return ds     */    private String computeDatasource(Method method, Object targetObject) {        if (allowedPublicOnly && !Modifier.isPublic(method.getModifiers())) {            return null;        }        //1. 從當前方法接口中獲取        String dsAttr = findDataSourceAttribute(method);        if (dsAttr != null) {            return dsAttr;        }        Class<?> targetClass = targetObject.getClass();        Class<?> userClass = ClassUtils.getUserClass(targetClass);        // JDK代理時,  獲取實現類的方法聲明.  method: 接口的方法, specificMethod: 實現類方法        Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);        specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);        //2. 從橋接方法查找        dsAttr = findDataSourceAttribute(specificMethod);        if (dsAttr != null) {            return dsAttr;        }        // 從當前方法聲明的類查找        dsAttr = findDataSourceAttribute(userClass);        if (dsAttr != null && ClassUtils.isUserLevelMethod(method)) {            return dsAttr;        }        //since 3.4.1 從接口查找,只取第一個找到的        for (Class<?> interfaceClazz : ClassUtils.getAllInterfacesForClassAsSet(userClass)) {            dsAttr = findDataSourceAttribute(interfaceClazz);            if (dsAttr != null) {                return dsAttr;            }        }        // 如果存在橋接方法        if (specificMethod != method) {            // 從橋接方法查找            dsAttr = findDataSourceAttribute(method);            if (dsAttr != null) {                return dsAttr;            }            // 從橋接方法聲明的類查找            dsAttr = findDataSourceAttribute(method.getDeclaringClass());            if (dsAttr != null && ClassUtils.isUserLevelMethod(method)) {                return dsAttr;            }        }        return getDefaultDataSourceAttr(targetObject);    }    /**     * 默認的獲取數據源名稱方式     *     * @param targetObject 目標對象     * @return ds     */    private String getDefaultDataSourceAttr(Object targetObject) {        Class<?> targetClass = targetObject.getClass();        // 如果不是代理類, 從當前類開始, 不斷的找父類的聲明        if (!Proxy.isProxyClass(targetClass)) {            Class<?> currentClass = targetClass;            while (currentClass != Object.class) {                String datasourceAttr = findDataSourceAttribute(currentClass);                if (datasourceAttr != null) {                    return datasourceAttr;                }                currentClass = currentClass.getSuperclass();            }        }        // mybatis-plus, mybatis-spring 的獲取方式        if (mpEnabled) {            final Class<?> clazz = getMapperInterfaceClass(targetObject);            if (clazz != null) {                String datasourceAttr = findDataSourceAttribute(clazz);                if (datasourceAttr != null) {                    return datasourceAttr;                }                // 嘗試從其父接口獲取                return findDataSourceAttribute(clazz.getSuperclass());            }        }        return null;    }    /**     * 用于處理嵌套代理     *     * @param target JDK 代理類對象     * @return InvocationHandler 的 Class     */    private Class<?> getMapperInterfaceClass(Object target) {        Object current = target;        while (Proxy.isProxyClass(current.getClass())) {            Object currentRefObject = AopProxyUtils.getSingletonTarget(current);            if (currentRefObject == null) {                break;            }            current = currentRefObject;        }        try {            if (Proxy.isProxyClass(current.getClass())) {                return (Class<?>) mapperInterfaceField.get(Proxy.getInvocationHandler(current));            }        } catch (IllegalAccessException ignore) {        }        return null;    }    /**     * 通過 AnnotatedElement 查找標記的注解, 映射為  DatasourceHolder     *     * @param ae AnnotatedElement     * @return 數據源映射持有者     */    private String findDataSourceAttribute(AnnotatedElement ae) {        AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, DS.class);        if (attributes != null) {            return attributes.getString("value");        }        return null;    }}

      ThreadLocal:

      public final class DynamicDataSourceContextHolder {    /**     * 為什么要用鏈表存儲(準確的是棧)     * <pre>     * 為了支持嵌套切換,如ABC三個service都是不同的數據源     * 其中A的某個業務要調B的方法,B的方法需要調用C的方法。一級一級調用切換,形成了鏈。     * 傳統的只設置當前線程的方式不能滿足此業務需求,必須使用棧,后進先出。     * </pre>     */    private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new NamedThreadLocal<Deque<String>>("dynamic-datasource") {        @Override        protected Deque<String> initialValue() {            return new ArrayDeque<>();        }    };    private DynamicDataSourceContextHolder() {    }    /**     * 獲得當前線程數據源     *     * @return 數據源名稱     */    public static String peek() {        return LOOKUP_KEY_HOLDER.get().peek();    }    /**     * 設置當前線程數據源     * <p>     * 如非必要不要手動調用,調用后確保最終清除     * </p>     *     * @param ds 數據源名稱     */    public static String push(String ds) {        String dataSourceStr = StringUtils.isEmpty(ds) ? "" : ds;        LOOKUP_KEY_HOLDER.get().push(dataSourceStr);        return dataSourceStr;    }    /**     * 清空當前線程數據源     * <p>     * 如果當前線程是連續切換數據源 只會移除掉當前線程的數據源名稱     * </p>     */    public static void poll() {        Deque<String> deque = LOOKUP_KEY_HOLDER.get();        deque.poll();        if (deque.isEmpty()) {            LOOKUP_KEY_HOLDER.remove();        }    }    /**     * 強制清空本地線程     * <p>     * 防止內存泄漏,如手動調用了push可調用此方法確保清除     * </p>     */    public static void clear() {        LOOKUP_KEY_HOLDER.remove();    }}

      1. 啟動類上做如下配置:

      引入我們寫的自動配置類,排除 ShardingJdbc 的自動配置類。

      @SpringBootApplication(exclude = ShardingSphereAutoConfiguration.class)@Import({DynamicDataSourceAutoConfiguration.class})public class ShardingRunApplication {    public static void main(String[] args) {        SpringApplication.run(ShardingRunApplication.class);    }}

      最后,我們給之前寫的 Repository 加上注解:

      public interface BOrderRepository extends JpaRepository<BOrder,Long> {    @DS("slave0")    @Query(value = "SELECT * FROM (SELECT id,CASE WHEN company_id =1 THEN '小' WHEN company_id=4 THEN '中' ELSE '大' END AS com,user_id as userId FROM b_order0) t WHERE t.com ='中'",nativeQuery =true)    List<Map<String, Object>> findOrders();}

      再次調用,查詢成功?。?!

      企業操作和維護實踐-丟棄docker構建
      ? 上一篇 2022-09-10
      你知道信息架構圖和功能架構圖的區別嗎?
      下一篇 ? 2022-09-13
      • 如何在Ubuntu中保留文件系統并備份當前開發板鏡像
        0閱讀 0條評論 個贊
        在Ubuntu保留文件系統或者說備份當前開發板鏡像的需求在不斷增加。比如Ubuntu文件系統需要安裝庫文件的話直接使用apt-get工具就可以下載,但由于需要下載的核心板較多,比較費時間,這時需要將安……
      • 國產核心板全志T507助力消防系統升級
        0閱讀 0條評論 個贊
        9月16日下午,位于湖南長沙市區內的中國電信大樓發生火災,建筑高度218米,現場濃煙滾滾,數十層樓體燃燒劇烈。消防救援人員趕到現場后很快將火勢控制住,目前大樓火勢已被撲滅,所幸未發現人員傷亡。湖南電信……
      • 教大家如何處理Spring Boot易流中的用戶和群體!
        0閱讀 0條評論 個贊
        1.準備工作2.用戶操作2.1添加用戶2.2修改用戶2.3刪除用戶2.4查詢用戶3.組操作3.1添加組3.2修改組3.3刪除組3.4查詢組4.查看表詳情雖然說我們在實際開發中,……
      • 從PG15開始WAL壓縮優化
        0閱讀 0條評論 個贊
        PG15傳聞中的超級令人激動的功能大多數跳票了,年初我也寫過一個關于PG15新功能跳票的文章。PG15BETA已經發出幾個月了,似乎PG15里令人激動人心的功能不多,不過從長長的新功能列表里,……
      • 深入了解美團葉子發射器開源方案
        0閱讀 0條評論 個贊
        大家好,我是樹哥。之前我們有聊過「如何設計一個分布式ID發號器」,其中有講過4種解決方案,分別是:UUID類雪花算法數據庫自增主鍵Redis原子自增美團以第2、3種解決方案為基礎,開發出……
      發表評論 共有條評論
      用戶名: 密碼:
      驗證碼: 匿名發表
      • Python條件語句的用法
        0閱讀 0條評論 個贊
        python條件語句使用if表達式,難度不高,需要注意的是嵌套用法,以及如何設置對應的條件。if條件判斷語句python語句是按固定順序執行的,先執行前面的語句,再執行后面的語句。如果你像要程……
      • smile——Java機器學習引擎
        2閱讀 0條評論 個贊
        資源https://haifengl.github.io/https://github.com/haifengl/smile介紹Smile(統計機器智能和學習引擎)是一個基于Java和Scala的快速……
      • Linux系統的docker部署 網絡核心3.1
        0閱讀 0條評論 個贊
        此篇文章演示基本的基于docker部署.netcore服務,linux系統騰訊云ubuntu,.netcore版本3.1。1.安裝dockeraptinstalldocker.io2.拉取.ne……
      • 計算機網絡-了解-DNS和HTTPDNS
        0閱讀 0條評論 個贊
        DNS和HTTPDNSDNS域名解析的過程傳統DNS存在的問題1、域名緩存問題2、域名轉發問題3、出口NAT問題4、DNS域名更新問題5、解析延遲問題6、運營商劫持HTTPDNSHTTP……
      • 卡夫卡數據丟失問題優化總結及重復消費原因分析(二)
        0閱讀 0條評論 個贊
        .css-1yuhvjn{margin-top:16px;}.css-3jt6os.FileLinkCard{-webkit-align-items:center;-webkit-box-align……
      • 滲透攻擊和防御網絡-簡單的SQL注入
        0閱讀 0條評論 個贊
        1背景京東SRC(SecurityResponseCenter)收錄大量外部白帽子提交的sql注入漏洞,漏洞發生的原因多為sql語句拼接和Mybatis使用不當導致。2手工檢測2.1前置知識……
      • SQL Server備份和還原攻略
        0閱讀 0條評論 個贊
        一、知識點完全備份:備份全部選中的文件夾,并不依賴文件的存檔屬性來確定備份那些文件。(在備份過程中,任何現有的標記都被清除,每個文件都被標記為已備份,換言之,清除存檔屬性)。完全備份也叫完整備份。差異……
      • 設計模式介紹——單一模式
        0閱讀 0條評論 個贊
        簡介一個類只允許創建一個對象(或實例),那么這個類就是一個單例類,這種設計模式稱作單例設計模式(SingletonDesignPattern),簡稱單例模式。單例模式保證系統內存中只存在一個對象,……
      • sql server索引I摘要
        0閱讀 0條評論 個贊
        一、存儲結構在SQLServer中,有許多不同的可用排列規則選項。二進制:按字符的數字表示形式排序(ASCII碼中,用數字32表示空格,用68表示字母"D")。因為所有內容都表示為數字,所以……
      • 強大的多云混合多K8S集群管理平臺Rancher入門級實戰
        0閱讀 0條評論 個贊
        目錄概述定義為何使用其他產品安裝簡述規劃基礎環境Docker安裝Rancher安裝創建用戶創建集群添加Node節點配置kubectl創建項目和名稱空間發布應用偏好設置概述定義Rancher官網htt……
      • SQL Server復制:事務發布
        0閱讀 0條評論 個贊
        一、背景在復制的運用場景中,事務發布是使用最為廣泛的,我遇到這樣一個場景:在Task數據庫中有Basic與Group兩個表,需要提供這兩個表的部分字段給其它程序讀取放入緩存,程序需要比較及時的獲取……
      • 每分鐘寫6億條數據 攜程監控系統Dashboard存儲升級實踐
        0閱讀 0條評論 個贊
        .css-1yuhvjn{margin-top:16px;}.css-3jt6os.FileLinkCard{-webkit-align-items:center;-webkit-box-align……
      • 海量小文件總結及解決策略(三)NameNode、Hadoop歸檔文件等
        0閱讀 0條評論 個贊
        .css-1yuhvjn{margin-top:16px;}.css-3jt6os.FileLinkCard{-webkit-align-items:center;-webkit-box-align……
      • 公司排班系統遇到瓶頸?我自己造一個!
        10閱讀 0條評論 個贊
        本期名人堂我們有幸邀請到了白鯨開源的聯合創始人代立冬先生。代立冬先生與我們分享了自己社區開源的經歷,詳細介紹了一個開源項目是如何加入Apache孵化器,如何在導師的輔導下慢慢孵化、成長的過程,以及自己……
      • 在i.MX8MP開發板中移植OpenSSL工具
        0閱讀 0條評論 個贊
        飛凌嵌入式OKMX8MP-C開發板采用NXPi.MX8MPlus高性能處理器開發,AI計算能力高達2.3TOPS,可滿足輕量級邊緣計算需求。同時靈活的I/O接口配置和先進豐富的多媒體資源,方便客戶……
      • spring MVC(II)——請求處理參數和響應數據處理
        0閱讀 0條評論 個贊
        1、請求處理參數1.1請求參數@RequestParam1.1.1不使用@RequestParam注解請求參數處理,不使用參數注解:1.如果請求參數名和請求處理的形參名一致,springMv……
      • 數據倉庫及其維度(層次)建模(ODS DWD DWS DWT ADS)
        0閱讀 0條評論 個贊
        一.數倉及其維度1.什么是數倉?數據倉庫,簡稱數倉,(DataWarehouse)。從邏輯上理解,數據庫和數倉沒有區別,都是通過數據庫軟件實現存放數據的地方,只不過從數據量來……
      • Java開發學習(29)——Maven依賴轉移、可選依賴和排除依賴分析
        0閱讀 0條評論 個贊
        現在的項目一般是拆分成一個個獨立的模塊,當在其他項目中想要使用獨立出來的這些模塊,只需要在其pom.xml使用標簽來進行jar包的引入即可。其實就是依賴……
      • k8s網絡持久存儲的StorageClass(如何一步步實現動態持久存儲)
        0閱讀 0條評論 個贊
        StorageClass的作用:創建pv時,先要創建各種固定大小的PV,而這些PV都是手動創建的,當業務量上來時,需要創建很多的PV,過程非常麻煩。而且開發人員在申請PVC資源時,還不一定有匹配條件的……
      • 圖系列中推薦算法的召回與粗排實踐
        3閱讀 0條評論 個贊
        一、轉轉推薦算法介紹1.1什么是推薦系統?1.2轉轉推薦主要場景及流程二、圖算法原理介紹及轉轉實踐2.1經典GraphEmbedding方法:DeepWalk2.2結構性與同質性:node2……
      最近發布資訊
      更多
      警花高潮嗷嗷叫
      <del id="nnjnj"></del><track id="nnjnj"></track>

      <p id="nnjnj"></p>

      <address id="nnjnj"></address>

        <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

          <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>