Search in sources :

Example 11 with MapperMetadata

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

the class MybatisMapperParser method parseMapperFile.

private static void parseMapperFile(Map<String, MapperMetadata> entityInfos, String fileName, InputStream inputStream) throws Exception {
    XPathParser parser = new XPathParser(inputStream, true, null, new XMLMapperEntityResolver());
    XNode evalNode = parser.evalNode("/mapper");
    String mapperClass = evalNode.getStringAttribute("namespace");
    MapperMetadata entityInfo = entityInfos.get(mapperClass);
    if (entityInfo == null) {
        entityInfo = new MapperMetadata(mapperClass);
        entityInfos.put(mapperClass, entityInfo);
    }
    if (entityInfo.getEntityClass() == null) {
        log.warn("can't parse entityClass for:{}", mapperClass);
        return;
    }
    mapperKeyMappings.put(mapperClass, entityInfo);
    mapperKeyMappings.put(entityInfo.getEntityClass().getName(), entityInfo);
    Map<String, String> includes = new HashMap<>();
    List<XNode> children = evalNode.getChildren();
    for (XNode xNode : children) {
        if ("sql".equalsIgnoreCase(xNode.getName())) {
            includes.put(xNode.getStringAttribute("id"), xNode.getStringBody());
            continue;
        }
    }
    for (XNode xNode : children) {
        if ("select|insert|update|delete".contains(xNode.getName().toLowerCase())) {
            String sql = parseSql(fileName, xNode, includes);
            entityInfo.addSql(xNode.getName().toLowerCase(), xNode.getStringAttribute("id"), sql);
        }
    }
    inputStream.close();
}
Also used : XMLMapperEntityResolver(org.apache.ibatis.builder.xml.XMLMapperEntityResolver) XPathParser(org.apache.ibatis.parsing.XPathParser) HashMap(java.util.HashMap) XNode(org.apache.ibatis.parsing.XNode) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata)

Example 12 with MapperMetadata

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

the class MybatisMapperParser method doParse.

private static synchronized void doParse(String group, Resource[] mapperLocations) {
    if (entitiesGroupMap.containsKey(group))
        return;
    Map<String, MapperMetadata> entityInfos = new HashMap<>();
    try {
        // 
        String propKeyPrefix = "";
        if (!DataSourceConfig.DEFAULT_GROUP_NAME.equals(group)) {
            propKeyPrefix = "group[" + group + "].";
        }
        List<String> mapperPackages = ResourceUtils.getList(propKeyPrefix + "mybatis.mapper-package");
        for (String mapperPackage : mapperPackages) {
            String classNameToResourcePath = ClassUtils.convertClassNameToResourcePath(mapperPackage);
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + classNameToResourcePath + "/**/*.class";
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(pattern);
            for (Resource res : resources) {
                String mapperClass = StringUtils.splitByWholeSeparator(res.getURI().getPath(), classNameToResourcePath)[1];
                mapperClass = mapperPackage + "." + mapperClass.substring(1).substring(0, mapperClass.lastIndexOf(".") - 1);
                mapperClass = ClassUtils.convertResourcePathToClassName(mapperClass);
                entityInfos.put(mapperClass, new MapperMetadata(mapperClass));
            }
        }
    } catch (Exception e) {
    }
    // 解析xml
    try {
        for (Resource resource : mapperLocations) {
            parseMapperFile(entityInfos, resource.getFilename(), resource.getInputStream());
        }
    } catch (Exception e) {
        log.error("解析mapper文件异常", e);
        throw new RuntimeException("解析mapper文件异常");
    }
    List<MapperMetadata> list = entityInfos.values().stream().filter(e -> e.getEntityClass() != null).collect(Collectors.toList());
    for (MapperMetadata mapperMetadata : list) {
        mapperMetadata.setGroup(group);
    }
    entitiesGroupMap.put(group, list);
    log.info(">parse group[{}] finish,size:{}", group, entityInfos.size());
}
Also used : Logger(org.slf4j.Logger) ClassUtils(org.springframework.util.ClassUtils) NodeList(org.w3c.dom.NodeList) Enumeration(java.util.Enumeration) LoggerFactory(org.slf4j.LoggerFactory) DataSourceConfig(com.mendmix.mybatis.datasource.DataSourceConfig) HashMap(java.util.HashMap) JarFile(java.util.jar.JarFile) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata) Collectors(java.util.stream.Collectors) StringUtils(org.apache.commons.lang3.StringUtils) ArrayList(java.util.ArrayList) PathMatchingResourcePatternResolver(org.springframework.core.io.support.PathMatchingResourcePatternResolver) JarEntry(java.util.jar.JarEntry) List(java.util.List) XPathParser(org.apache.ibatis.parsing.XPathParser) Map(java.util.Map) XNode(org.apache.ibatis.parsing.XNode) ResourceUtils(com.mendmix.common.util.ResourceUtils) ResourcePatternResolver(org.springframework.core.io.support.ResourcePatternResolver) XMLMapperEntityResolver(org.apache.ibatis.builder.xml.XMLMapperEntityResolver) InputStream(java.io.InputStream) Resource(org.springframework.core.io.Resource) HashMap(java.util.HashMap) Resource(org.springframework.core.io.Resource) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata) PathMatchingResourcePatternResolver(org.springframework.core.io.support.PathMatchingResourcePatternResolver)

Example 13 with MapperMetadata

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

the class AutoFieldFillHandler method start.

@Override
public void start(JeesuiteMybatisInterceptor context) {
    List<MapperMetadata> mappers = MybatisMapperParser.getMapperMetadatas(context.getGroupName());
    String tenantSharddingField = MybatisConfigs.getTenantSharddingField(context.getGroupName());
    for (MapperMetadata mm : mappers) {
        Field[] createdFields = new Field[4];
        Field[] updatedFields = new Field[3];
        Field[] fields = FieldUtils.getAllFields(mm.getEntityClass());
        for (Field field : fields) {
            if (field.isAnnotationPresent(Id.class) && !field.isAnnotationPresent(GeneratedValue.class)) {
                field.setAccessible(true);
                createdFields[0] = field;
            } else if (field.isAnnotationPresent(CreatedBy.class)) {
                field.setAccessible(true);
                createdFields[1] = field;
            } else if (field.isAnnotationPresent(CreatedAt.class)) {
                field.setAccessible(true);
                createdFields[2] = field;
            } else if (field.isAnnotationPresent(UpdatedBy.class)) {
                field.setAccessible(true);
                updatedFields[1] = field;
            } else if (field.isAnnotationPresent(UpdatedAt.class)) {
                field.setAccessible(true);
                updatedFields[2] = field;
            } else if (tenantSharddingField != null && field.getName().endsWith(tenantSharddingField)) {
                field.setAccessible(true);
                createdFields[3] = field;
            }
        }
        String keyPrefix = mm.getMapperClass().getName() + ".";
        if (hasAnyValue(createdFields)) {
            methodFieldMappings.put(keyPrefix + "insert", createdFields);
            methodFieldMappings.put(keyPrefix + "insertSelective", createdFields);
            methodFieldMappings.put(keyPrefix + INSERT_LIST_METHOD_NAME, createdFields);
        }
        if (hasAnyValue(updatedFields)) {
            methodFieldMappings.put(keyPrefix + "updateByPrimaryKey", updatedFields);
            methodFieldMappings.put(keyPrefix + "updateByPrimaryKeySelective", updatedFields);
            methodFieldMappings.put(keyPrefix + "updateByPrimaryKeyWithVersion", updatedFields);
        }
    }
}
Also used : Field(java.lang.reflect.Field) UpdatedBy(com.mendmix.mybatis.plugin.autofield.annotation.UpdatedBy) CreatedBy(com.mendmix.mybatis.plugin.autofield.annotation.CreatedBy) Id(javax.persistence.Id) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata)

Example 14 with MapperMetadata

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

the class CacheHandler method removeCacheByDyncQuery.

/**
 * 根据动态查询内容清理缓存
 * @param sqlMetadata 查询主键列表SQL语句信息
 * @param parameter 参数
 * @throws Exception
 */
private void removeCacheByDyncQuery(MapperMetadata mapperMeta, BoundSql boundSql, SqlMetadata sqlMetadata) {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet rs = null;
    try {
        parseDyncQueryParameters(boundSql, sqlMetadata);
        connection = dataSource.getConnection();
        statement = connection.prepareStatement(sqlMetadata.getSql());
        List<Object> parameters = sqlMetadata.getParameters();
        for (int i = 0; i < parameters.size(); i++) {
            statement.setObject(i + 1, parameters.get(i));
        }
        rs = statement.executeQuery();
        List<String> ids = new ArrayList<>();
        while (rs.next()) {
            ids.add(rs.getString(1));
        }
        if (ids != null && !ids.isEmpty()) {
            List<String> idCacheKeys = ids.stream().map(id -> {
                return mapperMeta.getEntityClass().getSimpleName() + ID_CACHEKEY_JOIN + id.toString();
            }).collect(Collectors.toList());
            CacheUtils.remove(idCacheKeys.toArray(new String[0]));
            if (logger.isDebugEnabled()) {
                logger.debug("remove cacheKeys:{}", idCacheKeys);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        final String groupName = mapperMeta.getEntityClass().getSimpleName();
        clearCacheGroup(groupName);
    } finally {
        try {
            rs.close();
        } catch (Exception e2) {
        }
        try {
            statement.close();
        } catch (Exception e2) {
        }
        try {
            connection.close();
        } catch (Exception e2) {
        }
    }
}
Also used : MybatisSqlUtils(com.mendmix.mybatis.kit.MybatisSqlUtils) Arrays(java.util.Arrays) SqlCommandType(org.apache.ibatis.mapping.SqlCommandType) Connection(java.sql.Connection) MybatisConfigs(com.mendmix.mybatis.MybatisConfigs) LoggerFactory(org.slf4j.LoggerFactory) CacheExpires(com.mendmix.cache.CacheExpires) MapperMetadata(com.mendmix.mybatis.metadata.MapperMetadata) StringUtils(org.apache.commons.lang3.StringUtils) CrudMethods(com.mendmix.mybatis.crud.CrudMethods) ResultSet(java.sql.ResultSet) Map(java.util.Map) ParameterMapping(org.apache.ibatis.mapping.ParameterMapping) Cache(com.mendmix.mybatis.plugin.cache.annotation.Cache) MybatisRuntimeContext(com.mendmix.mybatis.MybatisRuntimeContext) Method(java.lang.reflect.Method) DigestUtils(com.mendmix.common.util.DigestUtils) AuthUser(com.mendmix.common.model.AuthUser) InstanceFactory(com.mendmix.spring.InstanceFactory) Collection(java.util.Collection) Set(java.util.Set) ColumnMetadata(com.mendmix.mybatis.metadata.ColumnMetadata) PreparedStatement(java.sql.PreparedStatement) MapperMethod(com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod) Collectors(java.util.stream.Collectors) StandardThreadFactory(com.mendmix.common.async.StandardThreadExecutor.StandardThreadFactory) MybatisMapperParser(com.mendmix.mybatis.parser.MybatisMapperParser) Executors(java.util.concurrent.Executors) Serializable(java.io.Serializable) BaseEntity(com.mendmix.mybatis.core.BaseEntity) List(java.util.List) MybatisHanlerInitException(com.mendmix.mybatis.exception.MybatisHanlerInitException) Annotation(java.lang.annotation.Annotation) GlobalConstants(com.mendmix.common.GlobalConstants) JsonUtils(com.mendmix.common.util.JsonUtils) ReflectUtils(com.mendmix.common.util.ReflectUtils) InvocationVals(com.mendmix.mybatis.plugin.InvocationVals) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SqlMetadata(com.mendmix.mybatis.metadata.SqlMetadata) InterceptorHandler(com.mendmix.mybatis.core.InterceptorHandler) BoundSql(org.apache.ibatis.mapping.BoundSql) Table(javax.persistence.Table) CacheKeyUtils(com.mendmix.mybatis.kit.CacheKeyUtils) DataSource(javax.sql.DataSource) CacheUtils(com.mendmix.cache.CacheUtils) FieldUtils(org.apache.commons.lang3.reflect.FieldUtils) ExecutorService(java.util.concurrent.ExecutorService) Id(javax.persistence.Id) Param(org.apache.ibatis.annotations.Param) CurrentRuntimeContext(com.mendmix.common.CurrentRuntimeContext) Logger(org.slf4j.Logger) CacheIgnore(com.mendmix.mybatis.plugin.cache.annotation.CacheIgnore) Field(java.lang.reflect.Field) JeesuiteMybatisInterceptor(com.mendmix.mybatis.plugin.JeesuiteMybatisInterceptor) MappedStatement(org.apache.ibatis.mapping.MappedStatement) SqlRewriteHandler(com.mendmix.mybatis.plugin.rewrite.SqlRewriteHandler) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) MybatisHanlerInitException(com.mendmix.mybatis.exception.MybatisHanlerInitException)

Example 15 with MapperMetadata

use of com.mendmix.mybatis.metadata.MapperMetadata 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

MapperMetadata (com.mendmix.mybatis.metadata.MapperMetadata)18 ArrayList (java.util.ArrayList)10 HashMap (java.util.HashMap)6 MappedStatement (org.apache.ibatis.mapping.MappedStatement)6 List (java.util.List)5 ColumnMetadata (com.mendmix.mybatis.metadata.ColumnMetadata)4 JeesuiteMybatisInterceptor (com.mendmix.mybatis.plugin.JeesuiteMybatisInterceptor)4 Map (java.util.Map)4 BoundSql (org.apache.ibatis.mapping.BoundSql)4 CurrentRuntimeContext (com.mendmix.common.CurrentRuntimeContext)3 AuthUser (com.mendmix.common.model.AuthUser)3 OrderBy (com.mendmix.common.model.OrderBy)3 PageParams (com.mendmix.common.model.PageParams)3 ResourceUtils (com.mendmix.common.util.ResourceUtils)3 MybatisConfigs (com.mendmix.mybatis.MybatisConfigs)3 MybatisRuntimeContext (com.mendmix.mybatis.MybatisRuntimeContext)3 InterceptorHandler (com.mendmix.mybatis.core.InterceptorHandler)3 CrudMethods (com.mendmix.mybatis.crud.CrudMethods)3 MybatisSqlUtils (com.mendmix.mybatis.kit.MybatisSqlUtils)3 MapperMethod (com.mendmix.mybatis.metadata.MapperMetadata.MapperMethod)3