#1971 建表clear

parent effd2851
......@@ -12,7 +12,7 @@
<parent>
<groupId>logwire</groupId>
<artifactId>logwire-parent</artifactId>
<version>1.5.0</version>
<version>1.6.0</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......@@ -30,7 +30,7 @@
<dependency>
<groupId>logwire</groupId>
<artifactId>logwire-web</artifactId>
<version>${logwire-libs.version}</version>
<version>${logwire-web.version}</version>
</dependency>
</dependencies>
......
......@@ -3,10 +3,13 @@ package logwire.web.bo.field.parse;
import logwire.core.bo.annotation.Choice;
import logwire.core.bo.annotation.ForeignKey;
import logwire.core.bo.field.BizArray;
import logwire.core.bo.field.BizMany;
import logwire.core.bo.field.BizOne;
import logwire.core.exceptions.ApplicationException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
public abstract class FieldParserUtil {
......@@ -18,10 +21,9 @@ public abstract class FieldParserUtil {
* 获取解析注解的 parser
*
* @param field
* @param annotations
* @return
*/
public static FieldParser getParser(java.lang.reflect.Field field) {
public static FieldParser getParser(Field field) {
if (field.getAnnotation(Choice.class) != null) {
if (field.getType().equals(String.class)) {
return ChoiceFieldParser.getInstance();
......@@ -32,10 +34,10 @@ public abstract class FieldParserUtil {
}
} else if (field.getAnnotation(ForeignKey.class) != null) {
//弱关联
if (field.getType().equals(BizOne.class)) {
if (field.getType().equals(BizOne.class)||field.getType().equals(BizMany.class)) {
return ForeignKeyFieldParser.getInstance();
} else {
throw new ApplicationException("@ForeignKey 只能用与 BizOne 类型");
throw new ApplicationException("@ForeignKey 只能用与 BizOne/BizMany 类型");
}
}
......@@ -57,11 +59,11 @@ public abstract class FieldParserUtil {
return DateTimeFieldParser.getInstance();
} else if (clazz.equals(Boolean.class) || clazz.equals(boolean.class)) {
return BooleanFieldParser.getInstance();
} else if (clazz.equals(Double.class) || clazz.equals(double.class) || clazz.equals(float.class)) {
} else if (clazz.equals(Double.class) || clazz.equals(double.class) || clazz.equals(float.class)||clazz.equals(Float.class)||clazz.equals(BigDecimal.class)) {
return DecimalFieldParser.getInstance();
} else if (clazz.equals(BizArray.class)) {
return BizArrayFieldParser.getInstance();
} else if (clazz.equals(BizOne.class)) {
} else if (clazz.equals(BizOne.class)||clazz.equals(BizMany.class)) {
return ForeignKeyFieldParser.getInstance();
}
throw new ApplicationException("该字段类型无法识别");
......
......@@ -41,10 +41,10 @@ public class BoActionListener implements ActionListener {
@Override
public void afterAction(ActionContext actionContext, String queryName) {
Session session = SessionHolder.getSession();
/*Session session = SessionHolder.getSession();
if (session != null) {
session.commit(queryService);
}
}*/
}
}
......@@ -11,10 +11,12 @@ import logwire.core.meta.model.fields.*;
import logwire.core.meta.query.IQuery;
import logwire.core.resource.BeanLoader;
import logwire.core.resource.loader.JavaModelBeanLoader;
import logwire.core.support.Util;
import logwire.core.tenant.TenantClassLoader;
import logwire.core.tenant.TenantProject;
import logwire.web.bo.field.parse.FieldParser;
import logwire.web.bo.field.parse.FieldParserUtil;
import org.elasticsearch.common.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
......@@ -66,43 +68,58 @@ public class BoModelBeanLoader extends BeanLoader<IQuery, TenantProject> impleme
List<BeanDefinition> bizModelList = isBizModel.get(true);
for (BeanDefinition beanDefinition : bizModelList) {
Class<?> clazz = classLoader.loadClass(beanDefinition.getBeanClassName());
//获取类名和注解里的label
String className = Util.toLowerCaseFirst(clazz.getSimpleName());
String label = clazz.getAnnotation(BizModel.class).label();
//独立model
Model model = new Model();
model.setName(clazz.getSimpleName());
model.setVerboseName(clazz.getAnnotation(BizModel.class).label());
Model model = initChildModel();
setName(className,model,label);
model.setVerboseName(label);
model.setVerboseNameCode(className);
model.setIncludeAuditFields(true);
model.setIncludeVersionField(true);
model.setIncludeDomainField(true);
initField(clazz, model, consumer);
consumer.accept(model);
}
}
private void initField(Class<?> clazz, Model model, Consumer consumer) {
/**
* 初始化model的字段
* @param clazz 类
* @param model model
* @param consumer
*/
private void initField(Class<?> clazz, Model model, Consumer<IQuery> consumer) {
Field[] fields = clazz.getDeclaredFields();
setPrimaryKey(model);
//当一个表有多个大文本字段,只需要建一次表,将多个大文本字段的值放在一张表中
Boolean isFirstText = true;
//遍历所有字段
for (Field f : fields) {
if (f.getAnnotation(Column.class) != null) {
//带有Column注解的字段
FieldParser parser = FieldParserUtil.getParser(f);
logwire.core.meta.model.fields.Field field = parser.parse(f.getName(), f);
model.addField(field);
} else if (f.getAnnotation(Text.class) != null) {
// 带有Text注解的字段 大文本属性会创建一张子表(Model),子表名为:BO表名_属性名,一个BO有多个大字段时,使用同一张表
} else if (f.getAnnotation(Text.class) != null&&isFirstText) {
// 带有Text注解的字段 大文本属性会创建一张子表(Model)
// 子表名为:BO表名_text,一个BO有多个大字段时,使用同一张表
if (f.getType() != BizText.class) {
throw new ApplicationException("@Text 字段类型必须为BizText");
}
newTextModel(model, f, consumer);
isFirstText = false;
} else if (f.getAnnotation(Array.class) != null) {
// 带有Text注解的字段 大文本属性会创建一张子表(Model),子表名为:BO表名_属性名,一个BO有多个大字段时,使用同一张表
// 带有Array注解的字段 字段类型必须是BizArray<X>, X可以是String/Double/Boolean/Long/Integer/BigDecimal/OffsetDateTime。
// 数组属性会创建一张子表(Model),子表名为:BO表名_属性名;包含的字段:
if (f.getType() != BizArray.class) {
throw new ApplicationException("@Array 字段类型必须为BizArray");
}
newArrayModel(model, f, consumer);
} else if (f.getAnnotation(Many.class) != null) {
// 带有Text注解的字段 大文本属性会创建一张子表(Model),子表名为:BO表名_属性名,一个BO有多个大字段时,使用同一张表
// 带有Many或SlaveMany注解的字段 字段类型必须是BizMany<X>, X为BO类型,未指定时可在注解中指定。
// 主多对多定义会创建一张子表(Model),子表名为:BO表名_TXT;包含的字段:
if (f.getType() != BizMany.class) {
throw new ApplicationException("@Many 字段类型必须为BizMany");
}
......@@ -120,20 +137,23 @@ public class BoModelBeanLoader extends BeanLoader<IQuery, TenantProject> impleme
* @param f
* @param consumer
*/
private void newArrayModel(Model model, Field f, Consumer consumer) {
private void newArrayModel(Model model, Field f, Consumer<IQuery> consumer) {
Array array = f.getAnnotation(Array.class);
Model arrayModel = new Model();
//新建数组字段表
Model arrayModel = initChildModel();
arrayModel.setName(model.getName() + "_" + f.getName());
arrayModel.setVerboseName(array.label());
ForeignKeyField ownerId = new ForeignKeyField("owner_id", model.getName());
ownerId.setPrimaryKey(true);
arrayModel.addField(ownerId);
arrayModel.addField(new IntegerField("idx"));
//通过泛型找到字段类型
Type actualTypeArguments = ((ParameterizedType) f.getGenericType()).getActualTypeArguments()[0];
FieldParser parser = FieldParserUtil.getParserByFieldType(actualTypeArguments);
logwire.core.meta.model.fields.Field valueField = parser.parse("value", f);
model.addField(valueField);
consumer.accept(model);
arrayModel.addField(valueField);
consumer.accept(arrayModel);
}
/**
......@@ -146,17 +166,19 @@ public class BoModelBeanLoader extends BeanLoader<IQuery, TenantProject> impleme
* @param f
* @param consumer
*/
private void newTextModel(Model model, Field f, Consumer consumer) {
private void newTextModel(Model model, Field f, Consumer<IQuery> consumer) {
Text text = f.getAnnotation(Text.class);
Model textModel = new Model();
textModel.setName(model.getName() + "_text");
//新建大文本字段表
Model textModel = initChildModel();
textModel.setName(model.getName()+ "_text");
textModel.setVerboseName(text.label());
ForeignKeyField ownerId = new ForeignKeyField("owner_id", model.getName());
ownerId.setPrimaryKey(true);
textModel.addField(ownerId);
textModel.addField(new StringField("field_name", 50));
textModel.addField(new TextField("value"));
consumer.accept(model);
consumer.accept(textModel);
}
/**
......@@ -169,15 +191,45 @@ public class BoModelBeanLoader extends BeanLoader<IQuery, TenantProject> impleme
* @param f
* @param consumer
*/
private void newManyModel(Model model, Field f, Consumer consumer) {
private void newManyModel(Model model, Field f, Consumer<IQuery> consumer) {
Many many = f.getAnnotation(Many.class);
Model manyModel = new Model();
manyModel.setName(model.getName() + "_" + f.getName());
//新建多对多关系表
Model manyModel = initChildModel();
manyModel.setName(model.getName() + "_TXT");
manyModel.setVerboseName(many.label());
manyModel.addField(new AutoField());
manyModel.addField(new ForeignKeyField("master_id", model.getName()));
manyModel.addField(new ForeignKeyField("slave_id", many.referBoName()));
consumer.accept(model);
consumer.accept(manyModel);
}
private Model initChildModel(){
Model childModel = new Model();
setPrimaryKey(childModel);
childModel.setIncludeAuditFields(false);
childModel.setIncludeVersionField(false);
childModel.setIncludeDomainField(false);
return childModel;
}
/**
* bo默认主键id为雪花id
* @param model
*/
private void setPrimaryKey(Model model){
BigIntegerField id = new BigIntegerField("id");
id.setPrimaryKey(true);
model.addField(id);
}
private void setName(String className, Model model, String label) {
if (!Strings.isNullOrEmpty(label)) {
model.setName(label);
} else {
model.setName(className);
}
}
@Override
......
......@@ -23,38 +23,46 @@ import java.util.Set;
*/
public class Session {
/*
private ActionContext actionContext;
public Session(ActionContext actionContext) {
this.actionContext = actionContext;
}
/**
*/
/**
* 业务对象的缓存
* 第一层 map 的 key 为 model 名称
* 第二层 map 的 key 为 主键值
*/
*//*
private Map<String, Map<String, BizObject>> cache = Maps.newHashMap();
/**
*/
/**
* 业务对象主键值的缓存
* 第一层 map 的 key 为 model 名称
* 第二层 map 的 key 为 model 某个字段的名称
* 第三层 map 的 key 为 model 某个字段的值, value 为 model 主键的值
*/
*//*
private Map<String, Map<String, Map<String, Set<Object>>>> pkCache = Maps.newHashMap();
/**
*/
/**
* 保存业务对象之间的关系
* 第一层 map 的 key 为 明细表的 model 名称
* 第二层 map 的 key 为 明细表的主键值
* 第三层 map 的 value 为明细表对应的主表对应的业务对象
* <p>
* 保存时需要,先保存主表,再保存明细表
*/
*//*
private Map<String, Map<String, Set<BizObject>>> itemHeaderRelations = Maps.newHashMap();
/**
*/
/**
* 保存业务对象之间的关系
* 第一层 map 的 key 为 item 关系的主表对应的 model 名称
* 第二层 map 的 key 为 主键值
......@@ -62,10 +70,12 @@ public class Session {
* <p>
* 删除时
* item 关系时,先删除明细表,再删除主表
*/
*//*
private Map<String, Map<String, Set<BizObject>>> headerItemRelations = Maps.newHashMap();
/**
*/
/**
* 保存业务对象之间的关系
* 第一层 map 的 key 为 join 关系的被 join 表
* 第二层 map 的 key 为 主键值
......@@ -73,40 +83,51 @@ public class Session {
* <p>
* 删除时
* join 关系时,先删除主表,再删除被关联 JOIN 的表
*/
*//*
private Map<String, Map<String, Set<BizObject>>> joinOrExtendRelations = Maps.newHashMap();
/**
*/
/**
* 组合对象和业务对象的映射关系
* key 为 compositeObject.hashCode()
*/
*//*
private Map<Integer, BizObject> compositeBizObjectMapping = Maps.newHashMap();
/**
*/
/**
* 组合对象和业务对象中的组合对象类中属性名称的映射关系
* key 为 compositeObject.hashCode()
*/
*//*
private Map<Integer, String> compositeBizObjectFieldMapping = Maps.newHashMap();
/**
*/
/**
* 业务对象数据的存放
*/
*//*
private Map<Integer, OperableAgent> operableAgentMap = Maps.newHashMap();
/**
*/
/**
* 待持久化的业务对象
*/
*//*
private List<BizObject> bizObjects = Lists.newArrayList();
public ActionContext getActionContext() {
return actionContext;
}
/**
*/
/**
* 将业务对象存入上下文中
*
* @param t 业务对象
*/
*//*
public void add(BizObject t) {
if (t == null) {
return;
......@@ -125,9 +146,11 @@ public class Session {
}
private class PersistedRecorder {
/**
*/
/**
* 暂存已执行持久化操作的业务对象标记
*/
*//*
private Map<Integer, Boolean> record = Maps.newHashMap();
public void accept(BizObject t) {
......@@ -139,9 +162,11 @@ public class Session {
}
}
/**
*/
/**
* 持久化
*/
*//*
public void commit(QueryService queryService) {
if (this.bizObjects.isEmpty()) {
return;
......@@ -340,14 +365,16 @@ public class Session {
set.add(value);
}
/**
*/
/**
* 缓存根据某个字段作为查询条件加载得到的若干业务对象
* 此处只缓存业务对象中的主键值
* 因为 Session 是线程安全的,所以此处内部不考虑并发问题
*
* @param t
* @param fieldName
*/
*//*
public void cache(BizObject t, String fieldName) {
Object pkValue = t.getId();
if (pkValue == null) {
......@@ -382,12 +409,14 @@ public class Session {
operableAgentMap.put(agent.getTarget().hashCode(), agent);
}
/**
*/
/**
* 缓存业务对象
* 因为 Session 是线程安全的,所以此处内部不考虑并发问题
*
* @param t
*/
*//*
public void cache(BizObject t) {
if (t == null) {
return;
......@@ -424,13 +453,15 @@ public class Session {
return BizObjectStatus.NEW.equals(t.getBizObjectStatus());
}
/**
*/
/**
* 从上下文中获取之前加载过的业务对象
*
* @param modelName
* @param pkValue
* @return
*/
*//*
public <T extends BizObject> T get(String modelName, Object pkValue) {
if (modelName == null || pkValue == null) {
return null;
......@@ -442,14 +473,16 @@ public class Session {
return (T) map.get(pkValue.toString());
}
/**
*/
/**
* 从上下文中获取之前加载过的业务对象
*
* @param modelName
* @param fieldName
* @param fieldValue
* @return
*/
*//*
public <T extends BizObject> List<T> get(String modelName, String fieldName, Object fieldValue) {
if (modelName == null || fieldName == null || fieldValue == null) {
return null;
......@@ -479,5 +512,6 @@ public class Session {
public <T extends Operable, R extends OperableAgent> R getOperableAgent(T operable) {
return (R) operableAgentMap.get(operable.hashCode());
}
*/
}
......@@ -27,8 +27,8 @@ public abstract class SessionHolder {
public static Session openSession(ActionContext context) {
Session session = sessionThreadLocal.get();
if (session == null) {
session = new Session(context);
sessionThreadLocal.set(session);
/*session = new Session(context);
sessionThreadLocal.set(session);*/
}
return session;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment