top.lingkang.mm.MagicConfiguration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mybatis-magic Show documentation
Show all versions of mybatis-magic Show documentation
mybatis能力扩展框架,兼顾mybatis的mapper.xml编写操作数据库。
The newest version!
package top.lingkang.mm;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.lingkang.mm.error.MagicException;
import top.lingkang.mm.gen.DefaultIdGenerate;
import top.lingkang.mm.gen.IdGenerate;
import top.lingkang.mm.override.MagicReflectorFactory;
import top.lingkang.mm.page.MagicPageInterceptor;
import top.lingkang.mm.transaction.MagicTransactionFactory;
import top.lingkang.mm.utils.MagicUtils;
import javax.sql.DataSource;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* mybatis-magic 主体配置,spring体系中不使用此配置
*
* @author lingkang
* Created by 2024/3/3
*/
public class MagicConfiguration extends Configuration {
private static final Logger log = LoggerFactory.getLogger(MagicConfiguration.class);
private List scanMapperXml = new ArrayList<>();
private DataSource dataSource;
/**
* 默认id生成算法,至少要保持 id 列长度为 16 位字符 或使用 bigint(16) 以上
* 默认id算法:{@link top.lingkang.mm.gen.DefaultIdGenerate}
*/
public static IdGenerate idGenerate = new DefaultIdGenerate();
private final List amxCache = new ArrayList<>();
public MagicConfiguration() {
}
public MagicConfiguration(DataSource dataSource) {
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
public MagicConfiguration setDataSource(DataSource dataSource) {
if (dataSource == null)
throw new MagicException("dataSource 不能为空!");
this.dataSource = dataSource;
return this;
}
/**
* 添加 mapper xml映射文件。可以是绝对路径的xml、也能是相对路径的xml(ClassPath)
* 也可以是相对路径的目录: mapper(位于:src/main/resources/mapper)
* 也可以是绝对目录: C:\Users\Administrator\Desktop\mapperXmlFiles
* 建议指明xml:
*
* {@code
* // 文件加载 resources/mapper/UserMapper.xml
* configuration.addMapperXml("mapper/UserMapper.xml");
* }
*
*
* @param mapperXml 相对资源路径下
* @return
*/
public MagicConfiguration addMapperXml(String... mapperXml) {
if (mapperXml == null)
throw new MagicException("addMapperXml 不能添加空值");
for (final String xml : mapperXml) {
if (amxCache.contains(xml))// 重复扫描时跳过
continue;
if (xml.endsWith(".xml") && !xml.endsWith("*.xml")) {
InputStream stream = ResourceUtil.getStream(xml);
log.debug("加载 mapper xml: {}", xml);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(stream, this, xml,
getSqlFragments());
try {
mapperParser.parse();
} catch (Exception e) {
if (e.getMessage().contains("already contains key"))
log.error("存在重复的接口方法,它可能与 BaseMapper 中的接口名称冲突");
throw e;
}
IoUtil.close(stream);
} else {
String targetXml = null;
URL url = getClass().getClassLoader().getResource("");
if (url == null) {
if (xml.endsWith("*")) {
targetXml = xml + ".xml";
} else if (xml.endsWith("/")) {
targetXml = xml + "*.xml";
} else {
targetXml = xml + "/*.xml";
}
List list = MagicUtils.scanResource(targetXml);
for (String file : list) {
if (!file.endsWith(".xml"))
continue;
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(file);
log.debug("加载 mapper xml: {}", file);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, this, file,
getSqlFragments());
try {
mapperParser.parse();
} catch (Exception e) {
if (e.getMessage().contains("already contains key"))
log.error("存在重复的接口方法,它可能与 BaseMapper 冲突");
throw e;
}
IoUtil.close(inputStream);
}
} else {
if (xml.endsWith("**")) {
targetXml = xml.substring(0, xml.length() - 2);
} else if (xml.endsWith("**.xml")) {
targetXml = xml.substring(0, xml.length() - 6);
} else if (xml.endsWith("*.xml")) {
targetXml = xml.substring(0, xml.length() - 5);
} else
targetXml = xml;
List list = FileUtil.loopFiles(targetXml);
for (File f : list) {
if (!f.getName().endsWith(".xml"))
continue;
InputStream inputStream = FileUtil.getInputStream(f);
log.debug("加载 mapper xml: {}", f.getPath());
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, this, f.getPath(),
getSqlFragments());
try {
mapperParser.parse();
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().contains("already contains key"))
log.error("存在重复的接口方法,它可能与 BaseMapper 冲突");
throw e;
}
IoUtil.close(inputStream);
}
}
}
amxCache.add(xml);
}
scanMapperXml.addAll(Arrays.asList(mapperXml));
return this;
}
public List getScanMapperXml() {
return scanMapperXml;
}
public IdGenerate getIdGenerate() {
return idGenerate;
}
public MagicConfiguration setIdGenerate(IdGenerate idGenerate) {
this.idGenerate = idGenerate;
return this;
}
public SqlSessionFactory build() {
Environment environment = new Environment("magic", new MagicTransactionFactory(), dataSource);
setEnvironment(environment);
// 反射工厂,将下划线转驼峰
setReflectorFactory(new MagicReflectorFactory());
// 分页拦截
addInterceptor(new MagicPageInterceptor());
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(this);
// 代理会话工厂
SqlSessionFactory sessionFactory = (SqlSessionFactory) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class[]{SqlSessionFactory.class},
new SqlSessionFactoryProxy(sqlSessionFactory)
);
return sessionFactory;
}
}