`
qmzpanda
  • 浏览: 16325 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

加载一些文件的常用方法

阅读更多
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resourcePatternResolver.getResources(“classpath:/rule/**/*.drl”);


/**
 * 检索对象 HQL 解析器
 */
@SuppressWarnings("unchecked")
public class HqlParser implements SearcherParser {
	
	protected final Log logger = LogFactory.getLog(getClass());

	private Dto2PoCache dto2PoCache;
		
	public Dto2PoCache getDto2PoCache() {
		return dto2PoCache;
	}

	public void setDto2PoCache(Dto2PoCache dto2PoCache) {
		this.dto2PoCache = dto2PoCache;
	}

	/**
	 * 解析查询条件,生成查询语句
	 * @param request 查询请求
	 * @return 查询语句
	 */
	public String parse(SearchRequest request) {
		StringBuilder hql = new StringBuilder();
		
		try {
			//如果有集合查询,则加上distinct
			if (this.hasMemberOf(request)) {
				request.setDistinct(true);
			}
			// dynamic search response
			SearchResponse response = new SearchResponse();
			
			// from clause
			String fromClause = resolveFromClause(request, response);
			if (StringUtils.isBlank(fromClause)) {
				throw new DynamicBuildHqlFailedException(request, fromClause);
			} else {
				if (logger.isDebugEnabled()) {
					logger.debug("from clause -> " + fromClause);
				}
			}

			// select clause
			String selectClause = resolveSelectClause(request, response);

			// condition clause
			String whereClause = resolveWhereClause(request, response);
			if (!StringUtils.isBlank(whereClause)) {
				if (logger.isDebugEnabled()) {
					logger.debug("where clause -> " + whereClause);
				}
			} 
			
			// group clause
			String groupClause = resolveGroupClause(request, response);
			if (!StringUtils.isBlank(groupClause)) {
				if (logger.isDebugEnabled()) {
					logger.debug("group clause -> " + groupClause);
				}					
			}
			
			// having clause
			String havingClause = resolveHavingClause(request, response);
			if (!StringUtils.isBlank(havingClause)) {
				if (logger.isDebugEnabled()) {
					logger.debug("having clause -> " + havingClause);
				}
			}
			
			// order clause
			String orderClause = resolveOrderClause(request, response);
			if (!StringUtils.isBlank(orderClause)) {
				if (logger.isDebugEnabled()) {
					logger.debug("order clause -> " + orderClause);
				}
			}
			
			// result resolver, query object
			hql.append(selectClause).append(" ")
				.append(fromClause).append(" ")
				.append(whereClause).append(" ")
				.append(groupClause).append(" ")
				.append(havingClause).append(" ")
				.append(orderClause);
			String q = hql.toString().replaceAll("[ ]+", " ");
			
			if (logger.isDebugEnabled()) {
				logger.debug("build hql - > " + q);
			}			
			
			Formatter formatter = new Formatter(q);
			logger.info("Hql Parser Result -> " + formatter.format());
			return q;
			
		} catch (Exception e) {
			logger.error("Dynamic build hql failed, " + e.getMessage());
			throw new DynamicBuildHqlFailedException(request, hql.toString());
		}
	}

	/**
	 * resolve dynamic search from clause
	 * @return from clause or "" 
	 */
	private String resolveFromClause(SearchRequest request,
			SearchResponse response) {
		
		// entity resolver, at least one entity should be provided
		// here entity name should be mapped to hibernate class name
		StringBuilder sb = new StringBuilder(); 		
		List<SearchEntityDto> entities = request.getEntities();
		if (null == entities || entities.size() < 1) {
			response.setSuccess(false);
		} else {
			sb.append("from ");
			for (int i = 0; i < entities.size(); ++i) {
				String clazz = entities.get(i).getValue();
				//将DTO类名转成PO类名
				Class poClass = dto2PoCache.lookupEnityClazz(clazz);
				String poClassName = poClass.getName();
				poClassName = poClassName.substring(poClassName.lastIndexOf(".") + 1);
				if (i == entities.size() - 1) {
					sb.append(poClass.getName()).append(" ").append(poClassName).append(" ");
				} else {
					sb.append(poClass.getName()).append(" ").append(poClassName).append(",");
				}
			}	
			handleMemberOf(request, sb);
		}
		return sb.toString();
	}
	
	/**
	 * 做两表或多表关联查询时,将查询条件的DTO的属性值替换成相应的实体属性
	 */
	private String replaceProperty(SearchRequest request, String property) {
		if (property !=null && !property.startsWith("'") && property.indexOf('.') > 0) {
			return replaceDtoClassWithPoClass(request, property);
		} else {
			return property;
		}
	}
	
	/**
	 * 将 DTO 和相应的属性转化为 PO 以及相应的属性
	 */
	private String replaceDtoClassWithPoClass(SearchRequest request, String property) {
		if (property == null) {
			return null;
		}
		
		// 将DTO中的属性映射成PO中的属性,如: DtoClass.dtoProperty 映射成 PoClass.poProperty
		for (SearchEntityDto searchEntity: request.getEntities()) {
			// 将 DTO 类名转成 PO 类名
			String dtoClassName = searchEntity.getValue();
			Class<?> poClass = dto2PoCache.lookupEnityClazz(dtoClassName);
			dtoClassName = dtoClassName.substring(dtoClassName.lastIndexOf(".") + 1);
			String poClassName = poClass.getName();
			Map<String, String> propertyMapping = dto2PoCache.lookupPropertyMapping(searchEntity.getValue());
			poClassName = poClassName.substring(poClassName.lastIndexOf(".") + 1);
	        String regex = dtoClassName + "[.[A-Za-z_]+]+";
	        Pattern ptn = Pattern.compile(regex);
	        Matcher m = ptn.matcher(property);
	        StringBuilder sb = new StringBuilder();
	        boolean matched = false;
	        while (m.find()) {
	        	matched = true;
	            String s = m.group();
	            //DtoClass前面部分
	            sb.append(property.substring(0,m.start()));
	            //PO
	            sb.append(poClassName);
	            sb.append('.');
	            //PO属性值
	            String s2 = propertyMapping.get( (s.substring(s.indexOf('.') + 1)).trim() );
	            if (StringUtils.isBlank(s2)) {
	            	s2 = s.substring(s.indexOf('.') + 1);
	            }
	            sb.append(s2);	            
	            //DtoClass.property后面部分
	            sb.append(property.substring(m.end()));
	        }
			property = matched ? sb.toString() : property;
		}
		return property;
	}
	
	/**
	 * resolve dynamic search select clause
	 * @return select clause or "" 
	 */
	private String resolveSelectClause(SearchRequest request,
			SearchResponse response) {
		
		// property resolver
		StringBuilder sb = new StringBuilder(""); 
		
		List<SearchPropertyDto> properties = request.getProperties();
		if (null == properties || properties.size() < 1) {
			// no specific property, search entity
			String clazz = request.getEntities().get(0).getValue();			
			// 将DTO类名转成PO类名
			Class<?> poClass = dto2PoCache.lookupEnityClazz(clazz);
			String poClassName = poClass.getName();
			poClassName = poClassName.substring(poClassName.lastIndexOf(".") + 1);
			
			// TODO 
			sb.append("select ").append(request.isDistinct() ? "distinct " : "").append(poClassName).append(" ");
			// sb.append("select ").append("distinct ").append(poClassName).append(" ");
		} else {
			// specify request entity property
			sb.append("select ").append(request.isDistinct() ? "distinct " : "");
			for (int i = 0; i < properties.size(); ++i) {
				sb.append(replaceDtoClassWithPoClass(request, properties.get(i).getValue()));
				if (i == properties.size() - 1) {
					sb.append(" ");
				} else {
					sb.append(",");
				}
			}
		}
		return sb.toString();
	}
	
	/**
	 * 做member of查询时,返回对应的实体名
	 * @param dtoName member of 属性名
	 * @return 实体名
	 */
	private String getEntityShortName(SearchRequest request, String dtoName) {
		String result = "";
		if (StringUtils.isNotBlank(dtoName)) {
			for (SearchEntityDto searchEntity: request.getEntities()) {
				// 将 DTO 类名转成 PO 类名
				String dtoClassName = searchEntity.getValue();
				String shortName = dtoClassName.substring(dtoClassName.lastIndexOf('.') + 1);
				if (dtoName.equals(shortName)) {
					Class<?> poClass = dto2PoCache.lookupEnityClazz(dtoClassName);
					result = poClass.getSimpleName();
					break;
				}
			}
		} else {
			result = request.getEntities().get(0).getValue();
			result = result.substring(result.lastIndexOf('.') + 1);
		}
		return result;
	}

	/**
	 * 判断查询请求中是否包含集合查询 
	 */
	private boolean hasMemberOf(SearchRequest request) {
		for (SearchConditionDto scd: request.getConditions()) {
			if (isMemberOfProperty(scd.getProperty().getValue())) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 判断属性是否为集合查询
	 * @param property 属性名
	 * @return true是集合查询,false不是集合查询
	 */
	private boolean isMemberOfProperty(String property) {
		return  property.startsWith("com_wisdom_") || property.indexOf(".com_wisdom_") > 0;
	}
	
	/**
	 * 判断查询实体中是否包含 memberEntityClass
	 * @param request 查询请求
	 * @param memberEntityClass 查询实体
	 * @param entityList 查询实体列表
	 * @return true包含,false不包含
	 */
	private boolean hasEntityClass(SearchRequest request, String memberEntityClass, List<String> entityList) {
		for (SearchEntityDto sed: request.getEntities()) {
			if (sed.getValue().equals(memberEntityClass)) {
				return true;
			}
		}
		for (String s: entityList) {
			if (s.equals(memberEntityClass)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 处理根据集合内数据查找的请求,将相关实体加入请求中
	 */
	private void handleMemberOf(SearchRequest request, StringBuilder sb) {
		List<String> entityList = new ArrayList<String>();
		for (SearchConditionDto scd: request.getConditions()) {
			if (isMemberOfProperty(scd.getProperty().getValue())) {
				String property = scd.getProperty().getValue();
				int iPoint = property.indexOf('.');
				if (iPoint > 0) {
					property = property.substring(iPoint + 1);
				}
				property = property.replaceAll("_", ".");
				int p = 0;
				if (property.indexOf('[')>0) {
					p = property.substring(0,property.indexOf('[')).lastIndexOf('.');
				} else {
					p = property.lastIndexOf('.');					
				}
				String memberEntityClass = property.substring(0, p);//关联实体全限定名
				if (!hasEntityClass(request, memberEntityClass, entityList)) {
					entityList.add(memberEntityClass);
				}
			}
		}
		for (String s: entityList) {
			String shortName = s.substring(s.lastIndexOf('.') + 1);
			sb.append(",").append(s).append(" ").append(shortName);
		}
	}
	
	/**
	 * 处理根据集合内数据查找的请求
	 */
	private void handleMemberOf(SearchRequest request, StringBuilder sb, String dtoProperty, String operator, String value) {
		String property = dtoProperty;
		int iPoint = property.indexOf('.');
		String dtoName = "";
		if (iPoint>=0) {
			dtoName = property.substring(0, iPoint);
			property = property.substring(iPoint + 1);
		}
		String entityName = getEntityShortName(request, dtoName);//实体名
		property = property.replaceAll("_", ".");
		int p = 0;
		if (property.indexOf('[')>0) {
			p = property.substring(0,property.indexOf('[')).lastIndexOf('.');
		} else {
			p = property.lastIndexOf('.');					
		}
		String memberEntityClass = property.substring(0, p);//关联实体全限定名
		String memberEntityClassName = memberEntityClass.substring(memberEntityClass.lastIndexOf('.') + 1);
		property = property.substring(p+1, property.length());
		if (operator.equalsIgnoreCase(SearchConditionDto.R_IN)
				|| operator.equalsIgnoreCase(SearchConditionDto.R_NOT_IN)) {
			if (value != null && !value.startsWith("(")) {//如果没加括号,则加上
				value = "(" + value + ")";
			}
			operator = operator.equalsIgnoreCase(SearchConditionDto.R_IN) ? " in " : " not in ";
		}
		String memberEntityProperty = "id";
		if (dtoProperty.indexOf('[') > 0 && dtoProperty.indexOf(']')>0) {
			memberEntityProperty = dtoProperty.substring(dtoProperty.indexOf('[') + 1, dtoProperty.indexOf(']'));
			//去年property中的[*]
			property = property.substring(0, property.indexOf('['));
		}
		sb.append(memberEntityClassName).append(" in elements(").append(entityName).append('.')
			.append(property).append(") and ").append(memberEntityClassName)
			.append(".").append(memberEntityProperty).append(" ").append(operator).append(value);
	}
	
	private boolean isLeftBracket(SearchConditionDto c) {
		return SearchConditionDto.B_LB.equals(c.getLeftBracket().getValue())
				&& "".equals(c.getOperater().getValue())
				&& "".equals(c.getProperty().getValue());
	}

	private boolean isRightBracket(SearchConditionDto c) {
		return SearchConditionDto.B_RB.equals(c.getRightBracket().getValue())
				&& "".equals(c.getOperater().getValue())
				&& "".equals(c.getProperty().getValue());
	}

	/**
	 * resolve dynamic search where clause
	 * @return where clause or "" 
	 */
	private String resolveWhereClause(SearchRequest request,
			SearchResponse response) {
		// condition resolver
		StringBuilder sb = new StringBuilder(""); 
		
		List<SearchConditionDto> conditions = request.getConditions();
		if (null == conditions || conditions.size() < 1) {
			// no condition restriction
		} else {
			// compute condition clause
			sb.append("where ");
			for (int i = 0; i < conditions.size(); ++i) {
				SearchConditionDto c = conditions.get(i);				
				String relation = c.getRelation().getValue();
				relation = "".equals(relation) ? (i < conditions.size()-1 ? SearchConditionDto.O_AND : relation) : relation;
				String property = null;
				
				// 判断是否含有member of语句
				boolean isMemberOf = isMemberOfProperty(c.getProperty().getValue());
				if (isMemberOf) {
					property = c.getProperty().getValue();					
				} else {
					property = replaceDtoClassWithPoClass(request, c.getProperty().getValue());
				}
				String operator = c.getOperater().getValue();
				sb.append(c.getLeftBracket().getValue());
				if (!SearchConditionDto.R_IS_NULL.equalsIgnoreCase(operator)
						&& !SearchConditionDto.R_IS_NOT_NULL.equalsIgnoreCase(operator)
						&& !isMemberOf ){ // 对is null,is not null, member of 特殊处理
				  sb.append(property).append(" ");
				}
				{
					// 完善运算符具体逻辑功能
					String value = replaceProperty(request, c.getValue().getValue());				
					//对boolean特殊处理
					if ("true".equalsIgnoreCase(value)) {
						value = "1";
					} else if ("false".equalsIgnoreCase(value)) {
						value = "0";
					}					
					if (isMemberOf) {//member of,如 PartnerDto.com_wisdom_partner_model_PartnerEntity_equipmentTypeParams
						handleMemberOf(request, sb, property, operator, value);
					} else if (operator.equalsIgnoreCase(SearchConditionDto.R_LIKE)) {
						value = value.replace("'", "%");
						String str = operator.replace("{$0}", "'" + value + "'");
						sb.append(str);
					}
					// (not) in
					else if (operator.equalsIgnoreCase(SearchConditionDto.R_IN)
							|| operator.equalsIgnoreCase(SearchConditionDto.R_NOT_IN)) {
						if (value != null && !value.startsWith("(")) {//如果没加括号,则加上
							value = "(" + value + ")";
						}
						String str = operator.replace("{$0}", value);
						sb.append(str + " ");
					}
					// (not) between ... and ...
					else if (operator.equalsIgnoreCase(SearchConditionDto.R_BETWEEN) 
							|| operator.equalsIgnoreCase(SearchConditionDto.R_NOT_BETWEEN)) {
						String[] strs = value.split(",");
						String str = operator.replace("{$0}", strs[0]);
						str = operator.replace("${1}", strs[1]);
						sb.append(str + " ");
					} else if (SearchConditionDto.R_IS_NULL.equalsIgnoreCase(operator)
							|| SearchConditionDto.R_IS_NOT_NULL.equalsIgnoreCase(operator)) { //is null  / is not null
						int pos = property.lastIndexOf('.');
						if (property.indexOf('.') != pos) {//如果是MenuEntity.role.roleCode,则转换成MenuEntity.role
							property = property.substring(0, pos);
						}
						sb.append(property).append(" ");
						sb.append(operator + " ");
					}  else { // 直接使用运算符
						if ("".equals(operator) && value == null) {//没有操作符号,是括号或者是	AND/OR
							value = "";
						}
						sb.append(operator + " ").append(value + " ");
					}					
				}  
				// 只有括号时,relation为空则保留空值, 如果下一条是个右括号,则不加and
				if (isLeftBracket(c)
						|| (i < conditions.size() - 1 && isRightBracket(conditions.get(i + 1)))) {
					// TODO relation = "";
				}
				sb.append(c.getRightBracket().getValue()).append(" ")
				  .append(relation).append(" "); 
			}
		}
		
		String result = sb.toString();
		boolean terminated = false;
		String backStr = new String(result);
		while (!terminated) {
			result = result.replaceAll("[ ]+", " ");
			result = result.replaceAll(" [ and ]+ ", " and ");
			result = result.replaceAll(" [ or ]+ ", " or ");
			result = result.replaceAll(" and or ", " or ");
			result = result.replaceAll(" and[ ]*\\)", " )");
			result = result.replaceAll(" or[ ]*\\)", " )");
			result = result.replaceAll(" \\([ ]*or", " (");
			result = result.replaceAll(" \\([ ]*and", " (");
			result = result.replaceAll(" \\([ ]*\\)", "");
			
			// recompute
			terminated = result.equals(backStr);
			backStr = new String(result);
		}
		
		logger.info("rebuild where clause string = " + result);
		return result;
	}
	
	/**
	 * resolve dynamic search group clause
	 * @return group clause or "" 
	 */
	private String resolveGroupClause(SearchRequest request,
			SearchResponse response) {
		
		// group resolver
		StringBuilder sb = new StringBuilder(""); 

		List<SearchGroupDto> groups = request.getGroups();
		if (null == groups || groups.size() < 1) {
			// no group requirement
		} else {
			// append group info for hql
			sb.append("group by ");
			for (int i = 0; i < groups.size(); ++i) {
				sb.append(replaceDtoClassWithPoClass(request, groups.get(i).getValue()));
				if (i == groups.size() - 1) {
					sb.append(" ");
				} else {
					sb.append(",");
				}
			}
		}		
		return sb.toString();
	}
	
	/**
	 * resolve dynamic search having clause
	 * @return having clause or "" 
	 */
	private String resolveHavingClause(SearchRequest request,
			SearchResponse response) {
		
		// having resolver
		StringBuilder sb = new StringBuilder(""); 
		
		List<SearchHavingDto> havings = request.getHavings();
		if (null == havings || havings.size() < 1) {
			// no having requirement
		} else {
			// append having restriction 
			// and group key word must be provided, not check grammer here
			sb.append("having ");
			for (int i = 0; i < havings.size(); ++i) {
				SearchConditionDto c = havings.get(i);				
				String relation = c.getRelation().getValue();
				relation = "".equals(relation) ? (i < havings.size()-1 ? SearchConditionDto.O_AND : relation) : relation;
				sb.append(c.getLeftBracket().getValue())
				  .append(replaceDtoClassWithPoClass(request, c.getProperty().getValue()))
				  .append(c.getOperater().getValue())
				  .append(replaceDtoClassWithPoClass(request, c.getValue().getValue()))
				  .append(c.getRightBracket().getValue()).append(" ")
				  .append(relation).append(" "); 
			}
		}		
		return sb.toString();
	}
	
	/**
	 * resolve dynamic search order clause
	 * @return order clause or "" 
	 */
	private String resolveOrderClause(SearchRequest request,
			SearchResponse response) {
		
		// order resolver
		StringBuilder sb = new StringBuilder(""); 
		
		List<SearchOrderDto> orders = request.getOrders();
		if (null == orders || orders.size() < 1) {
			// no order info provided
		} else {
			// append order
			sb.append("order by ");
			for (int i = 0; i < orders.size(); ++i) {
				sb.append(replaceDtoClassWithPoClass(request, orders.get(i).getValue()));
				sb.append(" ");
				sb.append(orders.get(i).getOrder());
				if (i == orders.size() - 1) {
					sb.append(" ");
				} else {
					sb.append(",");
				}
			}
		}
		return sb.toString();
	}

}

分享到:
评论

相关推荐

    cesium 加载shp原文件

    一个常用的选择是`geoserver`或者`openlayers`,它们可以将Shp文件转换为GeoJSON或其他Cesium能理解的格式。另外,JavaScript库如`shapefile-js`或者`shp-write`可以用来在客户端解析Shp文件。 3. **数据转换**:...

    C# BIN文件加载

    C#学习,在制作固件升级的上位机时候常用到BIN文件和HEX文件加载,BIN文件相对特殊,是纯粹的二进制数据域,没有多余的协议格式,所以会用到特殊的加载方式,两种方法实现BIN文件加载,速度上的却别让你领悟技巧的...

    加载资源文件的PDF

    使用`AssetManager`可以从`assets`目录加载文件,如下所示: ```java AssetManager assetManager = getAssets(); InputStream inputStream = assetManager.open("your_pdf_file.pdf"); ``` 或者,如果PDF位于...

    cad线型加载文件

    5. **预定义线型与自定义线型**:CAD软件通常预设了一些常用线型,如“CONTINUOUS”(连续线),“DASHED”(虚线)等。自定义线型则允许用户根据需求创建个性化的线条样式,例如,创建代表特定建筑结构的线型。 6....

    用MapControl加载shape格式文件

    ### 使用MapControl加载Shape格式文件 #### 概述 在地理信息系统(GIS)开发中,经常需要处理多种矢量数据格式。其中,Shapefile是最常用的一种格式,它由ESRI公司开发并广泛应用于各种GIS软件中。Shapefile以其...

    浅谈SpringBoot2.4 配置文件加载机制大变化

    Volume 配置挂载是 Kubernetes 的一项常用功能,其中 ConfigMap 指令用于直接在文件系统上显示配置。 二、ConfigFileApplicationListener 问题 ConfigFileApplicationListener 属于比较核心的底层代码,每次维护都...

    Android通过JS在线用webview加载PDF文件(无限放大版本)

    在Android开发中,有时我们需要在应用内部展示PDF文件,而Webview是一个常用的选择。Webview不仅可以加载HTML页面,还可以通过JavaScript接口与Android原生代码交互,实现更多功能。本教程将详细讲解如何在Android的...

    ADS下的分散加载文件应用实例

    在ADS中,分散加载文件通常以`.sct`或`.lds`为扩展名,它是链接器指令语言的文本文件,定义了程序内存映射的详细规则。 首先,我们需要理解分散加载文件的基本结构。一个典型的分散加载文件由多个加载节(Load ...

    摄像机+X文件的加载

    此外,"X文件"(.x文件)是一种常用的3D模型文件格式,由Microsoft DirectX SDK提供。在DirectX 3D程序中,我们可以加载X文件来导入3D模型。加载过程可能涉及以下步骤: 1. 加载X文件:使用`D3DXLoadMeshFromX`函数...

    vue动态加载外部依赖js代码实现

    - **created钩子**: 当组件实例创建后,自动调用`load`方法来加载指定的JS文件。 - **load方法**: 此方法接受一个参数`src`,根据该参数动态创建并插入`&lt;script&gt;`标签到DOM中。同时,它还监听`onload`事件,以便在...

    flash加载外部文件

    这样,在加载文件时就不会出现路径问题。 **2. 加载TXT文件** Flash提供了一个内置函数`loadVariables()`用于加载外部变量数据。在这个例子中,我们将使用这个函数来加载一个TXT文件的内容,并将其存储在一个变量...

    ArcEngine 可加载的数据的几种方法

    ArcEngine 可加载的数据的几种方法 ArcEngine 是一个功能强大且广泛应用的 GIS 软件开发平台,它可以加载多种类型的数据,包括 Shapefile 数据、栅格数据、点数据、经纬度等数据格式。下面我们将详细介绍 ArcEngine...

    Log4j配置文件解析以及加载自己的配置文件.doc

    可以在Java代码中指定配置文件路径,例如使用`PropertyConfigurator.configure("path/to/config/file.properties")`,或者在类路径下放置名为`log4j.properties`或`log4j.xml`的文件,Log4j会自动加载。 总结起来,...

    动态加载树结构实现方法

    根据提供的信息,我们可以深入探讨关于“动态加载树结构实现方法”的相关知识点,特别是递归调用在树结构中的应用。 ### 动态加载树结构实现方法 #### 1. 树结构简介 树结构是一种非线性的数据结构,用于表示具有...

    Spring Junit单元测试加载配置文件失败问题

    Spring Junit单元测试加载配置文件失败问题解决方法 在软件开发过程中,单元测试是一个非常重要的步骤,它可以帮助开发者检测代码中的错误、提高代码的可靠性和稳定性。Spring Junit是一个常用的单元测试框架,它...

    VC++允许库合集,解决未能加载文件或程序集CefSharp.Core.dll问题

    当您遇到“未能加载文件或程序集CefSharp.Core.dll”这样的错误时,通常意味着您的系统缺少与CefSharp相关的VC++运行库支持。 CefSharp是一个开源项目,它提供了对Chromium Embedded Framework(CEF)的.NET绑定,...

    Android-用于加载GIF文件的Android库

    这个库虽然已不再更新,但在过去是Android开发者常用的库之一,也支持GIF加载。现在,推荐使用更新且更活跃的库,如Glide或Fresco。 7. 自定义GIF解析器: 如果你对性能有特殊要求,或者想要更深入地控制GIF的播放...

    c# 动态加载dll文件,并实现调用其中的方法(推荐)

    标题和描述中提到的知识点是关于在C#中动态...总之,C#动态加载DLL并调用其方法是.NET应用程序中常用的技术,特别是在需要模块化和扩展性时。通过上述步骤和相关类的使用,开发者可以在运行时实现高度灵活的功能扩展。

    list加载文件

    本文将对“List加载文件”的概念进行详细介绍,并进一步探讨其具体实现方法。 #### 二、List数据结构简介 `List`是Java中最常用的数据结构之一,它属于集合框架的一部分。`List`接口继承自`Collection`接口,是一...

Global site tag (gtag.js) - Google Analytics