diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Aggregate.java b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Aggregate.java
index f293f608d8c31493f299997dced7428371eab033..3e513f3ffeb4a5d87131cd72ad627ccd17a63c18 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Aggregate.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Aggregate.java
@@ -26,31 +26,81 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+/**
+ * 聚合注解
+ * 作用:声明字段的类型为聚合
+ *
+ *
+ * 解释:聚合一般指多个实体组装后的集合
+ *
+ *
+ *
+ * 使用说明:
+ * 1、在使用上,聚合注解基本等效于实体注解
+ * 2、在不指定仓储的情况下,框架会自动为实体匹配仓储
+ *
+ *
+ *
+ * 例如:
+ *
{@code
+ * @Aggregate
+ * private List users;
+ *
+ * 等效于:
+ *
+ * @Entity(repository = UserRepository.class)
+ * private List users;
+ * }
+ *
+ *
+ * @author tao.chen
+ */
@Entity
@Inherited
@Documented
+@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Aggregate {
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
String name() default "";
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
Class> source() default Object.class;
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
Class> factory() default Object.class;
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
Class> repository() default Object.class;
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
int priority() default 0;
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
String sortBy() default "";
+ /**
+ * @see Entity
+ */
@AliasFor(annotation = Entity.class)
String order() default "";
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Binding.java b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Binding.java
index 1af274bea2755cbc1c5f04bd0e54832fa555eb04..ecf6f07b2bd4f0da8c7ce9575e4c2d0ca6e9f501 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Binding.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Binding.java
@@ -19,19 +19,83 @@ package com.gitee.dorive.api.annotation;
import java.lang.annotation.*;
+/**
+ * 绑定注解
+ * 作用:声明实体字段之间的绑定关系
+ *
+ *
+ * 绑定类型有三种,分别是:
+ * 1、强绑定(两个字段强相关时使用)
+ *
{@code
+ * @Binding(field = "field", bindExp = "./field")
+ * }
+ * 2、弱绑定(字段与上下文相关时使用)
+ * {@code
+ * @Binding(field = "field", processExp = "#ctx['field']")
+ * }
+ * 3、值绑定(字段与字面值相关时使用)
+ * {@code
+ * @Binding(value = "0", bindExp = "./field")
+ * }
+ *
+ *
+ *
+ * 当绑定的字段,还需要再进行深度解析时,请使用以下配置方式:
+ *
{@code
+ * @Binding(field = "field", bindExp = "./list", processExp = "#val.![field]", bindField = "field")
+ * }
+ *
+ *
+ * @author tao.chen
+ */
@Inherited
@Documented
+@Target(ElementType.FIELD)
@Repeatable(Bindings.class)
@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Binding {
- String field();
+ /**
+ * 字段名称
+ * 作用:声明当前实体绑定的字段
+ */
+ String field() default "";
+
+ /**
+ * 字面值
+ * 作用:值绑定时使用
+ */
+ String value() default "";
- String bindExp();
+ /**
+ * 绑定表达式
+ * 作用:声明上下文绑定的字段
+ * 说明:
+ * 1、./field是以当前实体为参考系的相对路径
+ * 2、/field是以聚合根为参考系的绝对路径
+ */
+ String bindExp() default "";
- String property() default "";
+ /**
+ * 加工表达式
+ * 作用:从上下文中获取信息,或加工绑定的字段
+ * 说明:表达式书写请参考SpEL
+ *
+ * @see org.springframework.expression
+ */
+ String processExp() default "";
+ /**
+ * 指定加工器
+ * 作用:声明字段加工的具体实现
+ * 说明:如果加工表达式不为空,默认实现为SpELProcessor
+ */
Class> processor() default Object.class;
+ /**
+ * 绑定的字段名称
+ * 作用:显式声明绑定的字段名称
+ */
+ String bindField() default "";
+
}
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Bindings.java b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Bindings.java
index 8e7d9394ed8668236117924b9d7100bfb33765a6..77f285447f8da1376beec5a23827e9a8e2f29463 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Bindings.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Bindings.java
@@ -21,10 +21,8 @@ import java.lang.annotation.*;
@Inherited
@Documented
+@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Bindings {
-
Binding[] value();
-
}
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Entity.java b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Entity.java
index 64073c48afe1afa08fce03aa94752b58034128f2..411f5ea068ca7cf1896ffaa2099cc5bb05d59341 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Entity.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Entity.java
@@ -19,24 +19,142 @@ package com.gitee.dorive.api.annotation;
import java.lang.annotation.*;
+/**
+ * 实体注解
+ * 作用:声明一个类或字段的类型为实体
+ *
+ *
+ * 解释:实体是一种数据结构的具体表现形式,具有以下特征:
+ * 1、描述了实体和其他实体之间的关系。(一对一、一对多、多对多)
+ * 2、描述了实体字段和持久化数据的映射关系。
+ * 3、包含方法,可通过方法重写进行拓展。
+ *
+ *
+ *
+ * 使用说明:
+ * 1、在类上声明的实体注解,代表该实体的默认配置
+ *
{@code
+ * @Entity(name = "user", source = UserMapper.class)
+ * public class User {
+ * ......
+ * }
+ * }
+ * 2、在字段上声明的实体注解,代表在当前实体内的配置
+ * {@code
+ * public class Dept {
+ * @Entity(name = "user1", source = UserMapper1.class)
+ * private List users;
+ * }
+ * }
+ * 3、一般情况下,使用默认配置即可
+ * {@code
+ * public class Dept {
+ * @Entity
+ * private List users;
+ * }
+ * }
+ *
+ *
+ *
+ * 补充说明:如果想要在关联查询时,查询实体内部的其他实体,请指定仓储
+ *
{@code
+ * @Entity(name = "user", source = UserMapper.class)
+ * public class User {
+ * @Entity
+ * private List roles;
+ * }
+ *
+ * @Entity(name = "dept", source = DeptMapper.class)
+ * public class Dept {
+ * @Entity(repository = UserRepository.class)
+ * private List users;
+ * }
+ * }
+ *
+ *
+ * @author tao.chen
+ */
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Entity {
+ /**
+ * 实体名称
+ * 作用:可作为选取器的匹配条件
+ */
String name() default "";
+ /**
+ * 数据来源
+ * 作用:声明持久化数据操作的具体实现
+ * 注意:目前仅支持mybatis-plus框架中BaseMapper的子类
+ */
Class> source() default Object.class;
+ /**
+ * 实体工厂
+ * 作用:声明实体构造的具体实现
+ * 解释:实体工厂通过映射关系,实现了实体与持久化数据之间的相互转换
+ * 多态的实现方式:
+ * 1、假设实体为User,子类分别为User1、User2
+ * 2、新建UserFactory继承于DefaultEntityFactory,并重写reconstitute方法
+ * {@code
+ * @Override
+ * public Object reconstitute(Context context, Object persistent) {
+ * User user = (User) super.reconstitute(context, persistent);
+ * if (user.getType() == 1) {
+ * return BeanUtil.copyProperties(user, User1.class);
+ *
+ * } else if (user.getType() == 2) {
+ * return BeanUtil.copyProperties(user, User2.class);
+ * }
+ * return user;
+ * }
+ * }
+ * 3、修改User的@Entity注解,指定实体工厂为UserFactory
+ * {@code
+ * @Entity(......, factory = UserFactory.class)
+ * public class User {
+ * ......
+ * }
+ * }
+ * 4、在UserRepository中引入子类的仓储
+ * {@code
+ * public class UserRepository extends MybatisPlusRepository {
+ * private final User1Repository user1Repository;
+ * private final User2Repository user2Repository;
+ * }
+ * }
+ */
Class> factory() default Object.class;
+ /**
+ * 指定仓储
+ * 作用:指定一个特定的仓储,代替source操作数据
+ * 注意:不能和source与factory同时使用,优先级更高
+ */
Class> repository() default Object.class;
+ /**
+ * 操作优先级
+ * 作用:可以改变插入、更新、删除的操作顺序
+ */
int priority() default 0;
+ /**
+ * 默认排序字段
+ * 作用:关联查询时,默认的排序字段
+ */
String sortBy() default "";
+ /**
+ * 默认排序方式
+ * 作用:关联查询时,默认的排序方式
+ *
+ * @see com.gitee.dorive.api.constant.Order
+ */
String order() default "";
}
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Field.java b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Field.java
index 1cf133973d39448fb8541751c98f80e5908d8f39..6de4af0c45c166f8160a1391feae3ebcf7bd2629 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Field.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/annotation/Field.java
@@ -35,8 +35,8 @@ public @interface Field {
@AliasFor("value")
String alias() default "";
- Class> converter() default Object.class;
-
String mapExp() default "";
+ Class> converter() default Object.class;
+
}
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/BindingDef.java b/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/BindingDef.java
index 4d8070efa9f8d90edfc79c03fed119b931a840ef..6538b8f856ce91581fc4041fc125ec962bf9ce84 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/BindingDef.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/BindingDef.java
@@ -37,9 +37,11 @@ import java.util.Set;
public class BindingDef {
private String field;
+ private String value;
private String bindExp;
- private String property;
+ private String processExp;
private Class> processor;
+ private String bindField;
public static List fromElement(AnnotatedElement element) {
Set bindingAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations(element, Binding.class);
diff --git a/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/FieldDef.java b/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/FieldDef.java
index b4b90f8ad5584297ccee86af74c670de8a2a8428..b7f22b4430f649c3de0e04e65c73ca73886439e8 100644
--- a/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/FieldDef.java
+++ b/dorive-api/src/main/java/com/gitee/dorive/api/entity/def/FieldDef.java
@@ -34,8 +34,8 @@ public class FieldDef {
private boolean isId;
private String alias;
- private Class> converter;
private String mapExp;
+ private Class> converter;
public static FieldDef fromElement(AnnotatedElement element) {
Map attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(element, Field.class);
diff --git a/dorive-core/pom.xml b/dorive-core/pom.xml
index 23a98eb08aea157168fcfbb8d7eee9a43bc8c09f..83b2940026bed4f9ec665be29c9d4d5ee6be4a33 100644
--- a/dorive-core/pom.xml
+++ b/dorive-core/pom.xml
@@ -6,7 +6,7 @@
com.gitee.digital-engine
dorive
- 3.4.3.3
+ 3.4.3.4
dorive-core
diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/binder/Binder.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/binder/Binder.java
index 116e6fcd0968d94e0651932f79e14b436b5e8e36..02ac3f006065d10757ff97b53a82059ef23b6b61 100644
--- a/dorive-core/src/main/java/com/gitee/dorive/core/api/binder/Binder.java
+++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/binder/Binder.java
@@ -17,17 +17,18 @@
package com.gitee.dorive.core.api.binder;
-import com.gitee.dorive.api.entity.def.BindingDef;
import com.gitee.dorive.core.api.context.Context;
-public interface Binder {
+public interface Binder extends Processor {
- BindingDef getBindingDef();
+ String getFieldName();
Object getFieldValue(Context context, Object entity);
void setFieldValue(Context context, Object entity, Object property);
+ String getBoundName();
+
Object getBoundValue(Context context, Object rootEntity);
void setBoundValue(Context context, Object rootEntity, Object property);
diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/context/Matcher.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/context/Matcher.java
index d71bd7c43bad0ac5aa74ec8802ca1635697aa4d9..c76dcdf8315dc19a3fdaee50660ad5387b9530ca 100644
--- a/dorive-core/src/main/java/com/gitee/dorive/core/api/context/Matcher.java
+++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/context/Matcher.java
@@ -19,6 +19,6 @@ package com.gitee.dorive.core.api.context;
public interface Matcher {
- boolean matches(Context context);
+ boolean matches(Options options);
}
diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/context/AbstractContext.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/context/AbstractContext.java
index d011dcab34e5fe0ba813c4e079f4d2d1eee15cfd..82f782a48ebb0c019070d5a25a132284cfe22a5a 100644
--- a/dorive-core/src/main/java/com/gitee/dorive/core/entity/context/AbstractContext.java
+++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/context/AbstractContext.java
@@ -20,7 +20,6 @@ package com.gitee.dorive.core.entity.context;
import com.gitee.dorive.core.api.context.Context;
import com.gitee.dorive.core.api.context.Options;
import lombok.Getter;
-import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.LinkedHashMap;
@@ -28,19 +27,23 @@ import java.util.Map;
@Getter
@Setter
-@NoArgsConstructor
-public abstract class AbstractContext implements Context {
+public abstract class AbstractContext extends LinkedHashMap implements Context {
protected Map, Object> options = new LinkedHashMap<>(4);
- protected Map attachments = new LinkedHashMap<>(8);
+
+ public AbstractContext() {
+ super(8);
+ }
public AbstractContext(Options options) {
+ this();
this.options.putAll(options.getOptions());
}
public AbstractContext(Context anotherContext) {
+ this();
this.options.putAll(anotherContext.getOptions());
- this.attachments.putAll(anotherContext.getAttachments());
+ putAll(anotherContext.getAttachments());
}
@Override
@@ -58,19 +61,24 @@ public abstract class AbstractContext implements Context {
options.remove(type);
}
+ @Override
+ public Map getAttachments() {
+ return this;
+ }
+
@Override
public void setAttachment(String name, Object value) {
- attachments.put(name, value);
+ put(name, value);
}
@Override
public Object getAttachment(String name) {
- return attachments.get(name);
+ return get(name);
}
@Override
public void removeAttachment(String name) {
- attachments.remove(name);
+ remove(name);
}
}
diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java
index c92bbb2db43c0f12218ae68f52d4d9d926bb131b..1b35bcd8e892023a4deb8b9e5ed93396c4304f68 100644
--- a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java
+++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java
@@ -17,6 +17,7 @@
package com.gitee.dorive.core.entity.executor;
+import com.gitee.dorive.core.entity.operation.Query;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -34,6 +35,17 @@ public class Result {
private E record;
private long count = 0L;
+ public static Result