titan.lightbatis.mybatis.MapperBuilder Maven / Gradle / Ivy
/**
*
*/
package titan.lightbatis.mybatis;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.builder.annotation.ProviderSqlSource;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import titan.lightbatis.configuration.MapperConfig;
import titan.lightbatis.exception.LightbatisException;
import titan.lightbatis.mapper.LightbatisMapper;
import titan.lightbatis.mybatis.provider.EmptyProvider;
import titan.lightbatis.mybatis.provider.MapperProvider;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static titan.lightbatis.utils.MapperUtils.getMapperClass;
/**
* 重新构建 SqlSource
* @author [email protected]
*
*/
@Slf4j
public class MapperBuilder {
/**
* 缓存skip结果
*/
private final Map msIdSkip = new ConcurrentHashMap();
/**
* 注册的接口
*/
private List> registerClass = new ArrayList>();
/**
* 注册的通用Mapper接口
*/
private Map, MapperProvider> registerMapper = new ConcurrentHashMap, MapperProvider>();
/**
* 缓存msid和MapperProvider
*/
private Map msIdCache = new ConcurrentHashMap();
private MapperConfig config = new MapperConfig();
/**
* 通过通用Mapper接口获取对应的 MapperProvider
*
* @param mapperClass
* @return
* @throws Exception
*/
private MapperProvider fromMapperClass(Class> mapperClass) {
Method[] methods = mapperClass.getDeclaredMethods();
Class> templateClass = null;
Class> tempClass = null;
Set methodSet = new HashSet();
//MapperProvider defaultProvider = new QueryMapperProvider(mapperClass, this);
for (Method method : methods) {
if (method.isAnnotationPresent(SelectProvider.class)) {
SelectProvider provider = method.getAnnotation(SelectProvider.class);
tempClass = provider.type();
methodSet.add(method.getName());
} else if (method.isAnnotationPresent(InsertProvider.class)) {
InsertProvider provider = method.getAnnotation(InsertProvider.class);
tempClass = provider.type();
methodSet.add(method.getName());
} else if (method.isAnnotationPresent(DeleteProvider.class)) {
DeleteProvider provider = method.getAnnotation(DeleteProvider.class);
tempClass = provider.type();
methodSet.add(method.getName());
} else if (method.isAnnotationPresent(UpdateProvider.class)) {
UpdateProvider provider = method.getAnnotation(UpdateProvider.class);
tempClass = provider.type();
methodSet.add(method.getName());
} else {
//defaultProvider.addMethodMap(method.getName(), method);
}
if (templateClass == null) {
templateClass = tempClass;
} else if (templateClass != tempClass) {
throw new LightbatisException("一个通用Mapper中只允许存在一个 MapperProvider 子类!");
}
}
if (templateClass == null || !MapperProvider.class.isAssignableFrom(templateClass)) {
templateClass = EmptyProvider.class;
}
MapperProvider mapperProvider = null;
try {
mapperProvider = (MapperProvider) templateClass.getConstructor(Class.class, MapperBuilder.class)
.newInstance(mapperClass, this);
} catch (Exception e) {
throw new LightbatisException("实例化 MapperProvider 对象失败:" + e.getMessage());
}
// 注册方法
for (String methodName : methodSet) {
try {
mapperProvider.addMethodMap(methodName, templateClass.getMethod(methodName, MappedStatement.class));
} catch (NoSuchMethodException e) {
throw new LightbatisException(templateClass.getCanonicalName() + " 中缺少 " + methodName + "方法!");
}
}
return mapperProvider;
}
/**
* 注册通用Mapper接口
*
* @param mapperClass
*/
public void registerMapper(Class> mapperClass) {
if (!registerMapper.containsKey(mapperClass)) {
registerClass.add(mapperClass);
registerMapper.put(mapperClass, fromMapperClass(mapperClass));
}
// 自动注册继承的接口
Class>[] interfaces = mapperClass.getInterfaces();
if (interfaces != null && interfaces.length > 0) {
for (Class> anInterface : interfaces) {
registerMapper(anInterface);
}
}
}
/**
* 注册通用Mapper接口
*
* @param mapperClass
*/
public void registerMapper(String mapperClass) {
try {
registerMapper(Class.forName(mapperClass));
} catch (ClassNotFoundException e) {
throw new LightbatisException("注册通用Mapper[" + mapperClass + "]失败,找不到该通用Mapper!");
}
}
/**
* 判断接口是否包含通用接口
*
* @param mapperInterface
* @return
*/
public boolean isExtendCommonMapper(Class> mapperInterface) {
for (Class> mapperClass : registerClass) {
if (mapperClass.isAssignableFrom(mapperInterface)) {
return true;
}
}
return false;
}
/**
* 重新设置SqlSource
*
* 执行该方法前必须使用isMapperMethod判断,否则msIdCache会空
*
* @param ms
*/
public void setSqlSource(MappedStatement ms) {
MapperProvider mapperProvider = msIdCache.get(ms.getId());
try {
if (mapperProvider != null) {
mapperProvider.setSqlSource(ms);
}
} catch (Exception e) {
throw new LightbatisException(e);
}
}
/**
* 配置属性
*
* @param properties
*/
public void setProperties(Properties properties) {
// config.setProperties(properties);
// 注册通用接口
String mapper = null;
if (properties != null) {
mapper = properties.getProperty("mappers");
}
if (StringUtils.isNotEmpty(mapper)) {
String[] mappers = mapper.split(",");
for (String mapperClass : mappers) {
if (mapperClass.length() > 0) {
registerMapper(mapperClass);
}
}
}
}
/**
* 如果当前注册的接口为空,自动注册默认接口
*/
public void ifEmptyRegisterDefaultInterface() {
if (registerClass.size() == 0) {
registerMapper(LightbatisMapper.class.getName());
}
}
public void processConfiguration(Configuration configuration) {
this.processConfiguration(configuration, null);
}
public void processConfiguration(Configuration configuration, Class> mapperInterface) {
String prefix;
if (mapperInterface != null) {
prefix = mapperInterface.getCanonicalName();
} else {
prefix = "";
}
for (Object object : new ArrayList