All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.beetl.sql.mapper.builder.MapperMethodParser Maven / Gradle / Ivy

The newest version!
package org.beetl.sql.mapper.builder;

import org.beetl.sql.annotation.builder.Builder;
import org.beetl.sql.clazz.kit.*;
import org.beetl.sql.core.SqlId;
import org.beetl.sql.core.mapping.StreamData;
import org.beetl.sql.mapper.MapperInvoke;
import org.beetl.sql.mapper.annotation.*;
import org.beetl.sql.mapper.identity.BatchUpdateRMI;
import org.beetl.sql.mapper.identity.PageRMI;
import org.beetl.sql.mapper.identity.SelectRMI;
import org.beetl.sql.mapper.identity.UpdateRMI;
import org.beetl.sql.mapper.ready.BatchSqlReadyMI;
import org.beetl.sql.mapper.ready.PageSqlReadyMI;
import org.beetl.sql.mapper.ready.SelectSqlReadyMI;
import org.beetl.sql.mapper.ready.UpdateSqlReadyMI;
import org.beetl.sql.mapper.stream.StreamSqlIdMI;
import org.beetl.sql.mapper.stream.StreamSqlReadyMI;
import org.beetl.sql.mapper.stream.StreamTemplateSqlMI;
import org.beetl.sql.mapper.template.BatchUpdateTemplateMI;
import org.beetl.sql.mapper.template.PageTemplateMI;
import org.beetl.sql.mapper.template.SelectTemplateMI;
import org.beetl.sql.mapper.template.UpdateTemplateMI;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 解析Mapper方法,得到MapperInvoke类,能解析内置的的Sql,TemplateSql,也支持通过Builder注解自定义注解
 * @author xiandafu
 */
@Plugin
public class MapperMethodParser implements BaseMethodParser {
	//mapper类的泛型类型
	protected Class defaultRetType;
	protected Method method = null;
	protected Class mapperClass = null;
	protected int preferredSqlLen = -1;


	public MapperMethodParser() {

	}

	/**
	 * 映射方法解析器
	 *
	 * @param defaultRetType 接口实体类
	 * @param mapperClass BaseMapper接口或子接口
	 * @param method 调用的接口方法
	 */
	@Override
	public void init(Class defaultRetType, Class mapperClass, Method method) {
		this.defaultRetType = defaultRetType;
		this.mapperClass = mapperClass;
		this.method = method;
		this.preferredSqlLen = PropertiesKit.getInstance().getIntValue("MAPPER_SQL_MAX_LENGTH", "-1");
	}

	/**
	 * 解析Mapper中定于定义方法,采用对应的MapperInvoke
	 * @return
	 */
	@Override
	public MapperInvoke parse() {

		/*方法单独指定BaseMapper实现*/
		AutoMapper autoMapper = method.getAnnotation(AutoMapper.class);
		if (autoMapper != null) {
			MapperInvoke invoke = BeanKit.newSingleInstance(autoMapper.value());
			return invoke;
		}
		/*允许使用Stream 方式读取结果集*/
		if (StreamData.class.isAssignableFrom(method.getReturnType())) {
			MapperInvoke invoke = parseStreamMethod();
			return invoke;
		}
		/*直接提供jdbc的PrepareStatement语句*/
		Sql sqlAnnotation = method.getAnnotation(Sql.class);
		if (sqlAnnotation != null) {
			MapperInvoke invoke = parseSqlMethod(sqlAnnotation);
			return invoke;
		}

		/*不使用模板文件,直接在Template注解中写模板sql语句*/
		Template templateAnnotation = method.getAnnotation(Template.class);
		if (templateAnnotation != null) {
			MapperInvoke invoke = parseSqlTemplateMethod(templateAnnotation);
			return invoke;
		}

		MapperExtBuilder mapperBuilder = findExtBuilder();
		if (mapperBuilder != null) {
			MapperInvoke invoke = mapperBuilder.parse(defaultRetType, method);
			return invoke;
		}

		//默认,通过sqlId方式定位sql模板资源位置
		MapperInvoke invoke = others();
		return invoke;

	}

	protected  MapperInvoke others(){
		MapperInvoke invoke = parseSqlId();
		return invoke;
	}


	protected String getNamespace() {
		SqlResource methodSqlResoruce = method.getAnnotation(SqlResource.class);
		if (methodSqlResoruce != null) {
			return methodSqlResoruce.value();
		}
		SqlResource sqlResource = (SqlResource) mapperClass.getAnnotation(SqlResource.class);
		if (sqlResource != null) {
			return sqlResource.value();
		}
		//从实体名获取
		if (defaultRetType != null) {
			String namespace = StringKit.toLowerCaseFirstOne(defaultRetType.getSimpleName());
			return namespace;
		}
		throw new BeetlSQLException(BeetlSQLException.MAPPER_ERROR, "需要使用@SqlResource");
	}

	protected MapperInvoke parseSqlId() {
		//TODO 咋搞
		String namespace = getNamespace();
		String id = method.getName();
		SqlId sqlId = SqlId.of(namespace, id);
		Annotation action = getSqlType(method);
		//返回值说明
		ReturnTypeParser returnTypeParser = new ReturnTypeParser(method, defaultRetType);
		//参数说明
		ParameterParser parameterParser = new ParameterParser(method);
		MethodParamsHolder paramsHolder = parameterParser.getHolder();
		if (action == null || action instanceof Select) {
			if (paramsHolder.hasPageRequest()) {
				Class targetRetType = returnTypeParser.getPageResultType();
				if (returnTypeParser.isPageResult()) {
					return new PageRMI(sqlId, targetRetType, true, paramsHolder);
				} else {
					return new PageRMI(sqlId, targetRetType, false, paramsHolder);
				}

			} else {
				if (returnTypeParser.isCollection()) {
					Class targetRetType = returnTypeParser.getCollectionType();
					return new SelectRMI(sqlId, targetRetType, paramsHolder, false);
				} else {
					Class targetRetType = returnTypeParser.getType();
					return new SelectRMI(sqlId, targetRetType, paramsHolder, true);
				}
			}
		} else if (action instanceof Update) {
			return new UpdateRMI(sqlId, paramsHolder);
		} else if (action instanceof BatchUpdate) {
			return new BatchUpdateRMI(sqlId, paramsHolder);
		} else {
			throw new UnsupportedOperationException();
		}

	}


	/**
	 * 找到扩展的注解解释器,包含
	 * 
    *
  • SpringData
  • *
  • SqlProvider
  • *
  • SqlTemplateProvider
  • *
* @return */ protected MapperExtBuilder findExtBuilder() { Annotation[] ans = method.getAnnotations(); for (Annotation an : ans) { Builder builder = an.annotationType().getAnnotation(Builder.class); if (builder == null) { continue; } Class c = builder.value(); Object o = BeanKit.newSingleInstance(c); if (!(o instanceof MapperExtBuilder)) { throw new IllegalStateException("期望 " + MapperExtBuilder.class + " 但是 " + c); } return (MapperExtBuilder) o; } return null; } protected MapperInvoke parseSqlTemplateMethod(Template sqlAnnotation) { String sqlTemplate = sqlAnnotation.value(); checkSqlLength(sqlTemplate); Annotation action = getSqlType(method); //返回值说明 ReturnTypeParser returnTypeParser = new ReturnTypeParser(method, defaultRetType); //参数说明 ParameterParser parameterParser = new ParameterParser(method); MethodParamsHolder paramsHolder = parameterParser.getHolder(); if (action == null || action instanceof Select) { if (paramsHolder.hasPageRequest()) { Class targetRetType = returnTypeParser.getPageResultType(); if (returnTypeParser.isPageResult()) { return new PageTemplateMI(sqlTemplate, targetRetType, true, paramsHolder); } else { return new PageTemplateMI(sqlTemplate, targetRetType, false, paramsHolder); } } else { if (returnTypeParser.isCollection()) { Class targetRetType = returnTypeParser.getCollectionType(); return new SelectTemplateMI(sqlTemplate, targetRetType, paramsHolder, false); } else { Class targetRetType = returnTypeParser.getType(); return new SelectTemplateMI(sqlTemplate, targetRetType, paramsHolder, true); } } } else if (action instanceof Update) { return new UpdateTemplateMI(sqlTemplate, paramsHolder); } else if(action instanceof BatchUpdate){ return new BatchUpdateTemplateMI(sqlTemplate, paramsHolder); } else { throw new UnsupportedOperationException("不支持 " + action); } } protected MapperInvoke parseStreamMethod() { Sql sqlAnnotation = this.method.getAnnotation(Sql.class); Class targetType = getStreamType(); ParameterParser parameterParser = new ParameterParser(method); MethodParamsHolder paramsHolder = parameterParser.getHolder(); if (sqlAnnotation != null) { StreamSqlReadyMI sqlReadyMI = new StreamSqlReadyMI(sqlAnnotation.value(), targetType); return sqlReadyMI; } Template templateAnnotation = this.method.getAnnotation(Template.class); if (templateAnnotation != null) { String sqlTemplate = templateAnnotation.value(); StreamTemplateSqlMI streamTemplateSqlMI = new StreamTemplateSqlMI(sqlTemplate, targetType, paramsHolder); return streamTemplateSqlMI; } String namespace = getNamespace(); String id = method.getName(); SqlId sqlId = SqlId.of(namespace, id); StreamSqlIdMI sqlIdMI = new StreamSqlIdMI(sqlId, targetType, paramsHolder); return sqlIdMI; } protected Class getStreamType() { Type t = method.getGenericReturnType(); if (!(t instanceof ParameterizedType)) { return defaultRetType; } Class type = BeanKit.getParameterTypeClass(method.getGenericReturnType()); return type != null ? type : this.defaultRetType; } protected MapperInvoke parseSqlMethod(Sql sqlAnnotation) { String jdbcSql = sqlAnnotation.value(); checkSqlLength(jdbcSql); Annotation action = getSqlType(method); ReturnTypeParser returnTypeParser = new ReturnTypeParser(method, defaultRetType); //参数说明 ParameterParser parameterParser = new ParameterParser(method); MethodParamsHolder paramsHolder = parameterParser.getHolder(); if (action == null || action instanceof Select) { if (paramsHolder.hasPageRequest()) { if (returnTypeParser.isPageResult()) { Class targetRetType = returnTypeParser.getPageResultType(); return new PageSqlReadyMI(jdbcSql, targetRetType, true, paramsHolder); } else { Class targetRetType = returnTypeParser.getPageResultType(); return new PageSqlReadyMI(jdbcSql, targetRetType, false, paramsHolder); } } else { if (returnTypeParser.isCollection()) { Class targetRetType = returnTypeParser.getCollectionType(); return new SelectSqlReadyMI(jdbcSql, targetRetType, false); } else { return new SelectSqlReadyMI(jdbcSql, returnTypeParser.target, true); } } } else if (action instanceof Update) { return new UpdateSqlReadyMI(jdbcSql); } else if (action instanceof BatchUpdate) { return new BatchSqlReadyMI(jdbcSql); } else { throw new UnsupportedOperationException(); } } public static Annotation getSqlType(Method method) { Select select = method.getAnnotation(Select.class); if (select != null) { return select; } Update update = method.getAnnotation(Update.class); if (update != null) { return update; } BatchUpdate batchUpdate = method.getAnnotation(BatchUpdate.class); return batchUpdate; } protected Class getMappingEntity() { return method.getReturnType(); } protected void checkSqlLength(String sql) { if (preferredSqlLen == -1) { return; } if (sql.length() > preferredSqlLen) { throw new BeetlSQLException(BeetlSQLException.MAPPER_SQL_LIMIT, "期望Mapper方法 " + method + " 的SQL最大长度是 " + preferredSqlLen + " 实际是 " + sql.length()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy