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();
}
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());
}
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);
}
}
}
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) {
}
}
}
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);
}
Aggregations