top.lingkang.mm.orm.BaseMapperManage 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.orm;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.lingkang.mm.annotation.Id;
import top.lingkang.mm.constant.IdType;
import top.lingkang.mm.error.MagicException;
import top.lingkang.mm.gen.DefaultIdGenerate;
import top.lingkang.mm.gen.IdGenerate;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author lingkang
* Created by 2024/3/4
*/
class BaseMapperManage {
private static final Logger log = LoggerFactory.getLogger(BaseMapperManage.class);
public Configuration configuration;
public SqlSession sqlSession;
public IdGenerate idGenerate = new DefaultIdGenerate();
public BaseMapperManage(Configuration configuration, SqlSession sqlSession) {
Assert.notNull(sqlSession, "sqlSession 不能为空");
if (sqlSession instanceof DefaultSqlSession)
throw new MagicException("创建 BaseMapperManage 的 sqlSession 不能是: " + sqlSession.getClass().getName());
this.configuration = configuration;
this.sqlSession = sqlSession;
template = IoUtil.read(
getClass().getClassLoader().getResourceAsStream("MagicTemplate.xml"),
StandardCharsets.UTF_8);
// 加载lang
configuration.addMapper(MagicCreateLangMapper.class);
langMapper = configuration.getMapper(MagicCreateLangMapper.class, sqlSession);
}
private String template;
public MagicCreateLangMapper langMapper;
private Map, MagicEntity> cache = new HashMap<>();
public boolean isLoad(Class> clazz) {
return cache.containsKey(clazz);
}
public MagicEntity getMagicEntity(Class> clazz) {
MagicEntity entity = cache.get(clazz);
if (entity != null)
return entity;
entity = MagicEntityUtils.getMagicEntity(configuration, clazz);
// 缓存
cache.put(clazz, entity);
// load template
loadTemplate(entity);
return entity;
}
protected void loadTemplate(MagicEntity entity) {
int idIndex = entity.getIdIndex();
String temp = template
// select
.replace("index_", entity.getClazz().getName())
.replace("table_", entity.getTableName())
.replace("columns_", MagicEntityUtils.getColumns(entity.getColumnName(), null))
.replace("entityType_", entity.getClazz().getName())
// insert
.replace("id_", idIndex == -1 ? "_" : entity.getColumnName().get(idIndex))
.replace("values_", getInsertValues(entity))
.replace("sequence_values", getInsertValuesSequence(entity))
.replace("columnsE_", MagicEntityUtils.getInsertPrefixValues(entity, "e"))
// update
.replace("setColumns_", MagicEntityUtils.getSetColumns(entity, null));
// log.debug(temp);
InputStream in = IoUtil.toStream(temp, StandardCharsets.UTF_8);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(in, configuration, entity.getClazz().getName(),
configuration.getSqlFragments());
mapperParser.parse();
log.debug("{} --> {}", entity.getClazz().getName(), temp);
}
private String getInsertValues(MagicEntity entity) {
List col = entity.getColumnName();
StringBuilder res = new StringBuilder();
for (int i = 0; i < col.size(); i++) {
res.append("#{").append(col.get(i)).append("}");
if (i < col.size() - 1)
res.append(",");
}
return res.toString();
}
private String getInsertValuesSequence(MagicEntity entity) {
boolean isSequence = false;
if (entity.getIdAnn() != null && entity.getIdAnn().value() == IdType.AUTO && StrUtil.isNotEmpty(entity.getIdAnn().sequence())) {
isSequence = true;
}
List col = entity.getColumnName();
StringBuilder res = new StringBuilder();
for (int i = 0; i < col.size(); i++) {
if (isSequence && i == entity.getIdIndex()) {
res.append("nextval('").append(entity.getIdAnn().sequence()).append("')");
} else
res.append("#{").append(col.get(i)).append("}");
if (i < col.size() - 1)
res.append(",");
}
return res.toString();
}
// --------------------------------------------------------------------------------------
public Map getUpdateNotNullParams(Object obj, MagicEntity entity) {
Map param = new HashMap<>();
StringBuilder columns = new StringBuilder();
for (int i = 0; i < entity.getColumnName().size(); i++) {
try {
Field field = entity.getFields().get(i);
field.setAccessible(true);
if (field.get(obj) != null) {
columns.append(entity.getColumnName().get(i)).append("=#{e.")
.append(entity.getFields().get(i).getName()).append("}, ");
} else if (i == entity.getIdIndex())
throw new MagicException("更新对象的 " + field.getName() + " 不能为空值: " + obj);
} catch (Exception e) {
throw new MagicException(e);
}
}
if (columns.length() == 0)
throw new MagicException("不能更新全空值:" + obj);
param.put("columns", columns.substring(0, columns.length() - 2));
param.put("e", obj);
return param;
}
public String getSqlId(Class> clazz, String action) {
MagicEntity entity = getMagicEntity(clazz);
return getSqlId(entity, action);
}
public String getSqlId(MagicEntity entity, String action) {
return "magic_" + entity.getClazz().getName() + "." + action;
}
public String getQtId(String id) {
return "magicQuery." + id;
}
public void checkIdSet(MagicEntity entity, Object obj, IdGenerate idGenerate) {
Id id = entity.getIdAnn();
if (id != null) {
if (id.value() == IdType.ASSIGN) {
String idName = entity.getFields().get(entity.getIdIndex()).getName();
try {
Field field = entity.getClazz().getDeclaredField(idName);
field.setAccessible(true);
Object oId = field.get(obj);
if (oId != null)
return;
// 自动生成 id
Object genId = idGenerate.nextId(id.assignParam());
if (field.getType() != genId.getClass()) {
throw new MagicException("IdGenerate 自动生成 id 类型: " + genId.getClass().getName() +
" 与实体类 id 类型不一致: " + field.getType().getName() +
" 实体类: " + entity.getClazz().getName());
}
field.setAccessible(true);
field.set(obj, genId);
} catch (Exception e) {
throw new MagicException(e);
}
}
}
}
protected Object getIdValue(Object obj, Class> clazz, String name) {
try {
String metName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
Method method = clazz.getDeclaredMethod(metName);
return method.invoke(obj);
} catch (Exception e) {
}
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (Exception e) {
}
return null;
}
// get 、 set
public IdGenerate getIdGenerate() {
return idGenerate;
}
public void setIdGenerate(IdGenerate idGenerate) {
this.idGenerate = idGenerate;
}
}