com.github.nomou.mybatis.binding.SmartMapperRegistry Maven / Gradle / Ivy
package com.github.nomou.mybatis.binding;
import com.github.nomou.mybatis.builder.AutoDetectMapperBuilder;
import freework.reflect.Reflect;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* 此类存在的目的是为了修改Mapper添加过程的处理方式.
*
* 添加当method没有在xml中配置也没有使用annotation标注时的处理.
*
* @author vacoor
* @see MapperRegistry
*/
public class SmartMapperRegistry extends MapperRegistry {
/**
* Mybatis配置.
*/
private final Configuration configuration;
/**
* 替换前的{@link MapperRegistry}.
*/
private final MapperRegistry originalRegistry;
/**
* 父类中用于防止重复处理的mapper缓存.
*/
private final Map, MapperProxyFactory>> theKnownMappers;
private final DatabaseMetaData databaseMetadata;
/**
* 使用给定的配置创建{@link SmartMapperRegistry} 实例.
*
* @param configuration mybatis配置
*/
private SmartMapperRegistry(final Configuration configuration) {
super(configuration);
this.configuration = configuration;
this.originalRegistry = configuration.getMapperRegistry();
this.theKnownMappers = Reflect.wrap(this).get("knownMappers").get();
this.databaseMetadata = getDatabaseMetadata(configuration);
// databaseMetadata.getDatabaseProductName();
// databaseMetadata.getIdentifierQuoteString();
// 处理已经加载过的Mapper.
final Map, ?> alreadyAddMappers = Reflect.wrap(originalRegistry).get("knownMappers").get();
for (final Class> knownMapper : alreadyAddMappers.keySet()) {
AutoDetectMapperBuilder.parse(knownMapper, configuration);
}
}
private final DatabaseMetaData getDatabaseMetadata(final Configuration configuration) {
final DataSource dataSource = configuration.getEnvironment().getDataSource();
Connection conn = null;
try {
conn = dataSource.getConnection();
return conn.getMetaData();
} catch (final SQLException e) {
throw new IllegalStateException(e);
} finally {
if (null != conn) {
try {
conn.close();
} catch (final SQLException ignore) {
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void addMapper(final Class type) {
// FIXED annotation isInterface = true.
if (type.isInterface() && !type.isAnnotation()) {
if (hasMapper(type)) {
throw new BindingException(String.format("Type %s is already known to the MapperRegistry.", type));
}
boolean loadCompleted = false;
try {
theKnownMappers.put(type, new MapperProxyFactory(type));
/*-
* 替换原来的 MapperAnnotationBuilder#parse, 以便在找不到实现时动态创建实现.
* XXX: 考虑是否要延迟创建statement 实现,see: Configuration.getMappedStatement(java.lang.String, boolean)
*/
AutoDetectMapperBuilder.parse(type, configuration);
loadCompleted = true;
} finally {
if (!loadCompleted) {
theKnownMappers.remove(type);
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasMapper(Class type) {
return originalRegistry.hasMapper(type) || super.hasMapper(type);
}
/**
* {@inheritDoc}
*/
@Override
public T getMapper(Class type, SqlSession sqlSession) {
return originalRegistry.hasMapper(type) ? originalRegistry.getMapper(type, sqlSession) : super.getMapper(type, sqlSession);
}
/**
* {@inheritDoc}
*/
@Override
public Collection> getMappers() {
final Collection> origMappers = originalRegistry.getMappers();
final Collection> mappers = super.getMappers();
if (origMappers.isEmpty()) {
return mappers;
} else if (mappers.isEmpty()) {
return origMappers;
}
final Set> set = new HashSet>(origMappers);
set.addAll(mappers);
return Collections.unmodifiableSet(set);
}
/**
* 如果{@link Configuration#mapperRegistry}不是{@link SmartMapperRegistry}类型, 则替换.
*
* @param configuration mybatis 配置对象
* @return 传入的mybatis配置对象
*/
public static Configuration injectIfNecessary(final Configuration configuration) {
final MapperRegistry mapperRegistry = configuration.getMapperRegistry();
if (!(mapperRegistry instanceof SmartMapperRegistry)) {
Reflect.wrap(configuration).set("mapperRegistry", new SmartMapperRegistry(configuration));
}
return configuration;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy