按查询方法生成缓存key前缀
@param entityClassName
@param method
@return
320998
private QueryMethodCache generateQueryMethodCacheByMethod(EntityInfo entityInfo,Method method){

		Class<?> mapperClass = entityInfo.getMapperClass();
		Class<?> entityClass = entityInfo.getEntityClass();
		QueryMethodCache methodCache = new QueryMethodCache();
		String methodName = mapperClass.getName() + SPLIT_PONIT + method.getName();
		methodCache.methodName = methodName;
		methodCache.fieldNames = new String[method.getParameterTypes().length];
		methodCache.cacheGroupKey = entityClass.getSimpleName() + GROUPKEY_SUFFIX;
		//
		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;
		}
		
		StringBuilder sb = new StringBuilder(entityClass.getSimpleName()).append(SPLIT_PONIT).append(method.getName());
		
		Annotation[][] annotations = method.getParameterAnnotations();
		
		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(!methodCache.groupRalated && MybatisMapperParser.entityHasProperty(entityClass, fieldName)){					
					methodCache.fieldNames[i] = fieldName;
				}
			}else{
				if(!methodCache.groupRalated){
					throw new MybatisHanlerInitException(String.format("unique查询方法[%s] 使用了自动缓存Annotation @Cache,参数必须使用 @Param 绑定属性名称", methodName));
				}
			}
			//
			sb.append(i == 0 ? ":" : "_").append("%s");
		}
		
		if(!methodCache.groupRalated && methodCache.fieldNames.length == 1 && entityInfo.getIdProperty().equals(methodCache.fieldNames[0])){
			throw new MybatisHanlerInitException(String.format("按主键查询方法[%s] 使用了自动缓存Annotation @Cache,请使用默认方法[%s]代替", methodName,methodDefine.selectName()));
			}
		methodCache.keyPattern = sb.toString();
		
		return methodCache;
	}
474713
public String createMethodTypeSignature(ExecutableElement method) {
    if (!hasGenericSignature(method)) {
      return null;
    }
    StringBuilder sb = new StringBuilder();
    genMethodTypeSignature(method, sb);
    return sb.toString();
  }
719120
private static byte[] getByteNameWithCaching(String entityName) {
    byte[] name = cachedByteClassNames.get(entityName);
    if (name == null) {
      name = prepareCachedNameBytes(entityName);
      // if the cache max capacity is not exceeded, cache the name
      if (cachedByteClassNames.size() < CACHE_MAX_SIZE) {
        cachedByteClassNames.put(entityName, name);
      }
    }
    // this should never be null
    return name;
  }
215249
private void validateExternalCallback(Method method, CallbackType callbackType) {
    Class<?>[] parameters = method.getParameterTypes();
    if (!parameters[0].isAssignableFrom(entityClass)) {
      String message = String.format("Method %s in class %s is not valid for entity %s",
          method.getName(), method.getDeclaringClass().getName(), entityClass.getName());
      throw new EntityManagerException(message);
    }
    CallbackMetadata callbackMetadata = new CallbackMetadata(EntityListenerType.EXTERNAL,
        callbackType, method);
    metadata.put(callbackType, callbackMetadata);
  }
1154702
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        Assert.notNull(clazz, "类型不能为空");
        Assert.notNull(methodName, "方法名不能为空");

        return METHOD_CACHE.compute(new MethodKey(methodName, clazz, parameterTypes), (k, v) -> {
            if (v == null) {
                try {
                    return allowAccess(clazz.getDeclaredMethod(methodName, parameterTypes));
                } catch (NoSuchMethodException e) {
                    log.error(
                        StringUtils.format("类[{0}]中不存在方法名为[{1}]、方法列表为[{2}]的方法", clazz, methodName,
                            parameterTypes == null ? "null" : Arrays.toString(parameterTypes)));
                    throw new ReflectException(
                        StringUtils.format("类[{0}]中不存在方法名为[{1}]、方法列表为[{2}]的方法", clazz, methodName,
                            parameterTypes == null ? "null" : Arrays.toString(parameterTypes)),
                        e);
                }
            } else {
                return v;
            }
        });
    }
339246
String computeCacheKey(Class cls, String methodName, String argpart) {
		String cachekey = keyMaker.getMd5(cls.getName() + "." + methodName);
		if (!argpart.isEmpty()) {
			cachekey += "_" + keyMaker.getMd5(argpart);
		}
		logger.debug("CACHEID : {}.{}_{} = {}", cls.getName(), methodName, argpart, cachekey);
		return cachekey;
	}
1350521
public static EntityTable getEntityTable(Class<?> entityClass) {
        EntityTable entityTable = entityTableMap.get(entityClass);
        if (entityTable == null) {
            throw new MapperException("无法获取实体类" + entityClass.getCanonicalName() + "对应的表名!");
        }
        return entityTable;
    }
652128
private byte[] getBody(String method) {
        byte[] body = null;
    	String methodsWithInputEntity = HttpMethod.POST.name() + "|" + HttpMethod.PUT.name() + "|" + HttpMethod.DELETE.name();
    	if (method.matches(methodsWithInputEntity)) {
            if (isCompound()) {
                body = Utils.toBytes(getQueryInputEntity());
            }
            else {
                if (metadataJson.containsKey(INPUT_ENTITY)) {
                    JSONable data = (JSONable)commandParams.get(metadataJson.getString(INPUT_ENTITY));
                    if (data != null) {
                        body = Utils.toBytes(data.toJSON());
                    }
                }
            }
        }
        return body;
    }
885924
private static Method getMethod(Class<?> clazz, String methodName)
    {
        try
        {
            char string[] = methodName.toCharArray();
            string[0] = Character.toUpperCase(string[0]);
            methodName = new String(string);
            try
            {
                return clazz.getDeclaredMethod("get" + methodName);
            }
            catch (NoSuchMethodException e)
            {
                return clazz.getDeclaredMethod("is" + methodName);
            }
        }
        catch (NoSuchMethodException e)
        {
            return null;
        }
    }
1096677
public Method getMethod(String methodName) {
        return checkNotNull(methods().get(checkNotNull(methodName)), 
        		"The method %s is not exists of object %s", methodName, delegateClass().getName());
    }
956710
public static boolean checkExampleEntityClass(Object parameter, String entityFullName) {
        if (parameter != null && parameter instanceof Example && StringUtil.isNotEmpty(entityFullName)) {
            Example example = (Example) parameter;
            Class<?> entityClass = example.getEntityClass();
            if (!entityClass.getCanonicalName().equals(entityFullName)) {
                throw new MapperException("当前 Example 方法对应实体为:" + entityFullName
                        + ", 但是参数 Example 中的 entityClass 为:" + entityClass.getCanonicalName());
            }
        }
        return true;
    }
66940
public static ApiVersionDoc build(Method method) {
		ApiVersionDoc apiVersionDoc = null;
		ApiVersion methodAnnotation = method.getAnnotation(ApiVersion.class);
		ApiVersion typeAnnotation = method.getDeclaringClass().getAnnotation(ApiVersion.class);
		
		if(typeAnnotation != null) {
			apiVersionDoc = buildFromAnnotation(typeAnnotation);
		}
		
		if(methodAnnotation != null) {
			apiVersionDoc = buildFromAnnotation(method.getAnnotation(ApiVersion.class));
		}
		
		return apiVersionDoc;
	}
554280
public static String wherePKColumns(Class<?> entityClass, String entityName, boolean useVersion) {
        StringBuilder sql = new StringBuilder();
        boolean hasLogicDelete = hasLogicDeleteColumn(entityClass);

        sql.append("<where>");
        //获取全部列
        Set<EntityColumn> columnSet = EntityHelper.getPKColumns(entityClass);
        //当某个列有主键策略时，不需要考虑他的属性是否为空，因为如果为空，一定会根据主键策略给他生成一个值
        for (EntityColumn column : columnSet) {
            sql.append(" AND ").append(column.getColumnEqualsHolder(entityName));
        }
        if (useVersion) {
            sql.append(whereVersion(entityClass));
        }

        if (hasLogicDelete) {
            sql.append(whereLogicDelete(entityClass, false));
        }

        sql.append("</where>");
        return sql.toString();
    }
86115
String getCppName(Method method) {
        ClassMapping mapping = mappings.get(method.getDeclaringClass());

        if (mapping != null) {
            String name = method.getName() + "(" + Datatype.generateJNISignature(method.getParameterTypes()) + ")";
            Wrappe wrappedMethod = mapping.getMethods().findWrappe(name);
            if (wrappedMethod != null && !Utils.isNullOrEmpty(wrappedMethod.getCppName())) {
                return wrappedMethod.getCppName();
            }
        }
        Java4CppWrappe annot = method.getAnnotation(Java4CppWrappe.class);
        if (annot != null && !Utils.isNullOrEmpty(annot.value())) {
            return annot.value();
        }
        return mappings.escapeName(method.getName());
    }
121222
@UnstableApi
    public final void setPrivateKeyMethod(OpenSslPrivateKeyMethod method) {
        ObjectUtil.checkNotNull(method, "method");
        Lock writerLock = ctxLock.writeLock();
        writerLock.lock();
        try {
            SSLContext.setPrivateKeyMethod(ctx, new PrivateKeyMethod(engineMap, method));
        } finally {
            writerLock.unlock();
        }
    }
547707
public MethodDeclaration getMethod(String name, String signature) {
    for (EntityDeclaration node : type.getMembers()) {
      if (node.getEntityType() == EntityType.METHOD) {
        MethodDeclaration method = (MethodDeclaration) node;
        if (method.getName().equals(name) && signature.equals(signature(method))) {
          return method;
        }
      }
    }
    return null;
  }
198405
public static String buildSpecializedPagedResultClass(TypeSpec.Builder classBuilder, SQLiteModelMethod method) {
		// TypeName entityTypeName =
		// TypeUtility.typeName(method.getParent().getEntityClassName());
		TypeName entityTypeName = TypeUtility.typeName(method.getEntity().getName());

		String pagedResultName = "PaginatedResult" + (pagedResultCounter++);

		TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(pagedResultName).addModifiers(Modifier.PUBLIC)
				.superclass(TypeUtility.parameterizedTypeName(TypeUtility.className(PagedResultImpl.class), entityTypeName));

		// add fields and define constructor
		MethodSpec.Builder setupBuilder = MethodSpec.constructorBuilder();

		MethodSpec.Builder executeBuilder = MethodSpec.methodBuilder("execute").addModifiers(Modifier.PUBLIC)
				.returns(TypeUtility.parameterizedTypeName(TypeUtility.className(List.class), entityTypeName));
		executeBuilder.addComment("Executor builder - BEGIN");

		ClassName daoFactoryClassName = BindDaoFactoryBuilder.generateDaoFactoryClassName(method.getParent().getParent());
		MethodSpec.Builder executeWithDaoFactortBuilder = MethodSpec.methodBuilder("execute").addParameter(daoFactoryClassName, "daoFactory").addModifiers(Modifier.PUBLIC)
				.returns(TypeUtility.parameterizedTypeName(TypeUtility.className(List.class), entityTypeName));
		executeWithDaoFactortBuilder.addCode("return daoFactory.get$L().$L(", method.getParentName(), method.getName());

		if (!method.isPagedLiveData()) {
			executeBuilder.addCode("list=$T.this.$L(", TypeUtility.typeName(method.getParent().getElement(), BindDaoBuilder.SUFFIX), method.getName());
		}

		// we have always a first parameter
		String separator = "";
		ParameterSpec parameterSpec;
		for (Pair<String, TypeName> item : method.getParameters()) {
			if (method.hasDynamicPageSizeConditions() && method.dynamicPageSizeName.equals(item.value0)) {
				setupBuilder.addStatement("this.pageSize=$L", item.value0);
			} else {
				// field
				typeBuilder.addField(item.value1, item.value0);
				setupBuilder.addStatement("this.$L=$L", item.value0, item.value0);
			}

			// construtor
			parameterSpec = ParameterSpec.builder(item.value1, item.value0).build();
			setupBuilder.addParameter(parameterSpec);

			// execute
			if (method.dynamicPageSizeName != null && method.dynamicPageSizeName.equals(item.value0)) {
				if (!method.isPagedLiveData()) {
					executeBuilder.addCode(separator + "this.pageSize");
				}
				executeWithDaoFactortBuilder.addCode(separator + "this.pageSize");
			} else {
				if (!method.isPagedLiveData()) {
					executeBuilder.addCode(separator + item.value0);
				}
				executeWithDaoFactortBuilder.addCode(separator + item.value0);
			}
			separator = ", ";
		}

		if (method.isPagedLiveData()) {
			// if method is not paged live data, add complete execute method
			executeBuilder.addComment("paged result is used in live data, so this method must be empty");
			executeBuilder.addStatement("return null");
		} else {
			executeBuilder.addCode(separator + "this);\n");
			executeBuilder.addStatement("return list");
		}
		executeBuilder.addComment("Executor builder - END");

		typeBuilder.addMethod(executeBuilder.build());

		if (!method.hasDynamicPageSizeConditions()) {
			ModelAnnotation annotation = method.getAnnotation(BindSqlSelect.class);
			int pageSize = annotation.getAttributeAsInt(AnnotationAttributeType.PAGE_SIZE);

			// in case pageSize is not specified (only for liveData)
			if (pageSize == 0) {
				pageSize = 20;
			}

			setupBuilder.addStatement("this.pageSize=$L", pageSize);
		}

		typeBuilder.addMethod(setupBuilder.build());

		executeWithDaoFactortBuilder.addCode(separator + "this);\n");

		typeBuilder.addMethod(executeWithDaoFactortBuilder.build());

		classBuilder.addType(typeBuilder.build());

		return pagedResultName;
	}