Search in sources :

Example 1 with MapperMethod

use of com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod in project jeesuite-libs by vakinge.

the class CacheHandler method generateQueryMethodCacheByMethod.

/**
 * 按查询方法生成缓存key前缀
 * @param entityClassName
 * @param method
 * @return
 */
private QueryCacheMethodMetadata generateQueryMethodCacheByMethod(MapperMetadata mapperMeta, MapperMethod mapperMethod) {
    Method method = mapperMethod.getMethod();
    Cache cacheAnnotation = method.getAnnotation(Cache.class);
    String[] evictOnMethods = cacheAnnotation.evictOnMethods();
    Class<?> mapperClass = mapperMeta.getMapperClass();
    Class<?> entityClass = mapperMeta.getEntityClass();
    QueryCacheMethodMetadata methodCache = new QueryCacheMethodMetadata();
    methodCache.methodName = mapperClass.getName() + InvocationVals.DOT + method.getName();
    methodCache.concurrency = cacheAnnotation.concurrency();
    methodCache.uniqueIndex = cacheAnnotation.uniqueIndex();
    methodCache.cacheGroupKey = entityClass.getSimpleName() + GROUPKEY_SUFFIX;
    if (cacheAnnotation.userScope()) {
        methodCache.contextParam = CURRENT_USER_CONTEXT_NAME;
    } else if (cacheAnnotation.scopeContext().length > 0) {
        methodCache.contextParam = cacheAnnotation.scopeContext()[0];
    }
    if (cacheAnnotation.refKey().length > 0) {
        methodCache.refKey = cacheAnnotation.refKey()[0];
    }
    if (methodCache.contextParam != null && evictOnMethods.length == 0) {
        evictOnMethods = new String[] { "*" };
    }
    methodCache.checkExpired = evictOnMethods.length > 0;
    if (cacheAnnotation.expire() > 0) {
        methodCache.expire = cacheAnnotation.expire();
    } else if (cacheAnnotation.userScope()) {
        methodCache.expire = IN_1MINS * 10 < defaultCacheExpire ? IN_1MINS * 10 : defaultCacheExpire;
    }
    if (methodCache.uniqueIndex && method.getReturnType() != entityClass) {
        throw new MybatisHanlerInitException("@Cache with[uniqueIndex = true] but ReturnType not Match [" + entityClass.getName() + "]");
    }
    methodCache.collectionResult = method.getReturnType() == List.class || method.getReturnType() == Set.class;
    if (methodCache.collectionResult) {
        methodCache.groupRalated = true;
    } else {
        // count等统计查询
        methodCache.groupRalated = method.getReturnType().isAnnotationPresent(Table.class) == false;
    }
    methodCache.fieldNames = new String[method.getParameterTypes().length];
    Annotation[][] annotations = method.getParameterAnnotations();
    boolean uniqueQuery = method.getReturnType().isAnnotationPresent(Table.class);
    for (int i = 0; i < annotations.length; i++) {
        Annotation[] aa = annotations[i];
        if (aa.length > 0) {
            String fieldName = null;
            inner: for (Annotation annotation : aa) {
                if (annotation.toString().contains(Param.class.getName())) {
                    fieldName = ((Param) annotation).value();
                    break inner;
                }
            }
            if (uniqueQuery && mapperMeta.getEntityMetadata().getProp2ColumnMappings().containsKey(fieldName)) {
                methodCache.fieldNames[i] = fieldName;
            }
        }
    // 
    }
    methodCache.keyPattern = new StringBuilder(entityClass.getSimpleName()).append(InvocationVals.DOT).append(method.getName()).append(":%s").toString();
    if (uniqueQuery) {
        for (String name : methodCache.fieldNames) {
            if (StringUtils.isBlank(name)) {
                methodCache.fieldNames = null;
                break;
            }
        }
    }
    // 
    buildEvictOnMethods(mapperClass.getName(), mapperMethod, evictOnMethods);
    return methodCache;
}
Also used : Method(java.lang.reflect.Method) MapperMethod(com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod) Annotation(java.lang.annotation.Annotation) Param(org.apache.ibatis.annotations.Param) MybatisHanlerInitException(com.mendmix.mybatis.exception.MybatisHanlerInitException) Cache(com.mendmix.mybatis.plugin.cache.annotation.Cache)

Example 2 with MapperMethod

use of com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod in project jeesuite-libs by vakinge.

the class CacheHandler method buildEvictOnMethods.

/**
 * 构建自定义缓存更新关系
 * @param mapperClassName
 * @param method
 * @param evictOnMethods
 */
private void buildEvictOnMethods(String mapperClassName, MapperMethod method, String[] evictOnMethods) {
    if (evictOnMethods == null || evictOnMethods.length == 0) {
        return;
    }
    String targetMethodFullNamePrefix = mapperClassName.substring(0, mapperClassName.lastIndexOf(".") + 1);
    String targetMapperClassName = null;
    for (String methodName : evictOnMethods) {
        if ("*".equals(methodName)) {
            methodName = mapperClassName + ".*";
        } else if (!methodName.contains(InvocationVals.DOT)) {
            methodName = mapperClassName + InvocationVals.DOT + methodName;
        }
        if (!methodName.startsWith(targetMethodFullNamePrefix)) {
            methodName = targetMethodFullNamePrefix + methodName;
        }
        targetMapperClassName = methodName.substring(0, methodName.lastIndexOf("."));
        if (!methodName.endsWith("*")) {
            addCacheCheckRelations(methodName, method.getFullName());
        } else {
            MapperMetadata methodEntityInfo = MybatisMapperParser.getMapperMetadata(targetMapperClassName);
            if (methodEntityInfo == null) {
                continue;
            }
            for (MapperMethod mm : methodEntityInfo.getMapperMethods().values()) {
                if (mm.getSqlType() == SqlCommandType.SELECT)
                    continue;
                if (mm.getFullName().contains(methodName.replace("*", ""))) {
                    addCacheCheckRelations(mm.getFullName(), method.getFullName());
                }
            }
        }
    }
}
Also used : MapperMethod(com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata)

Example 3 with MapperMethod

use of com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod in project jeesuite-libs by vakinge.

the class CacheHandler method start.

@Override
public void start(JeesuiteMybatisInterceptor context) {
    dataSourceGroupName = context.getGroupName();
    Map<String, DataSource> dataSources = InstanceFactory.getBeansOfType(DataSource.class);
    if (dataSources.size() == 1) {
        dataSource = new ArrayList<>(dataSources.values()).get(0);
    } else {
        for (String beanName : dataSources.keySet()) {
            if (beanName.startsWith(dataSourceGroupName)) {
                dataSource = dataSources.get(beanName);
                break;
            }
        }
    }
    defaultCacheExpire = Long.parseLong(MybatisConfigs.getProperty(context.getGroupName(), MybatisConfigs.CACHE_EXPIRE_SECONDS, "0"));
    List<MapperMetadata> mappers = MybatisMapperParser.getMapperMetadatas(context.getGroupName());
    Class<BaseEntity> baseEntityClass = BaseEntity.class;
    QueryCacheMethodMetadata methodCache = null;
    for (MapperMetadata mm : mappers) {
        if (mm.getMapperClass().isAnnotationPresent(CacheIgnore.class))
            continue;
        if (!baseEntityClass.isAssignableFrom(mm.getEntityClass())) {
            logger.warn("[{}] not extends from [{}],ignore register auto cache!!!!", mm.getEntityClass().getName(), baseEntityClass.getName());
            continue;
        }
        Class<?> mapperClass = mm.getMapperClass();
        // 按主键查询方法定义
        QueryCacheMethodMetadata queryByPKMethod = generateQueryByPKMethod(mapperClass, mm.getEntityClass());
        if (queryByPKMethod == null)
            continue;
        Map<String, QueryCacheMethodMetadata> tmpMap = new HashMap<>();
        // 主键查询方法
        tmpMap.put(queryByPKMethod.methodName, queryByPKMethod);
        String keyPatternForPK = queryByPKMethod.keyPattern;
        // 接口定义的自动缓存方法
        for (MapperMethod method : mm.getMapperMethods().values()) {
            if (method.getMethod().isAnnotationPresent(Cache.class)) {
                if (tmpMap.containsKey(method.getFullName()))
                    continue;
                methodCache = generateQueryMethodCacheByMethod(mm, method);
                tmpMap.put(method.getFullName(), methodCache);
                logger.info("解析查询方法{}自动缓存配置 ok,keyPattern:[{}]", methodCache.methodName, methodCache.keyPattern);
            }
        }
        // 缓存需要自动缓存的mapper
        cacheEnableMappers.add(mm.getMapperClass().getName());
        logger.info("解析查询方法{}自动缓存配置 ok,keyPattern:[{}]", queryByPKMethod.methodName, queryByPKMethod.keyPattern);
        queryCacheMethods.put(mapperClass.getName(), tmpMap);
        // 更新缓存方法
        generateUpdateByPkCacheMethod(mapperClass, mm.getEntityClass(), keyPatternForPK);
    }
    // 
    logger.info(">>>customUpdateCacheMapppings:{}", customUpdateCacheMapppings);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BaseEntity(com.mendmix.mybatis.core.BaseEntity) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata) DataSource(javax.sql.DataSource) MapperMethod(com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod)

Aggregations

MapperMethod (com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod)3 MapperMetadata (com.mendmix.mybatis.metadata.MapperMetadata)2 BaseEntity (com.mendmix.mybatis.core.BaseEntity)1 MybatisHanlerInitException (com.mendmix.mybatis.exception.MybatisHanlerInitException)1 Cache (com.mendmix.mybatis.plugin.cache.annotation.Cache)1 Annotation (java.lang.annotation.Annotation)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 DataSource (javax.sql.DataSource)1 Param (org.apache.ibatis.annotations.Param)1