Skip to content

Commit

Permalink
feat: support adding ID attributes of start and end nodes in edge ent…
Browse files Browse the repository at this point in the history
…ities.
  • Loading branch information
CorvusYe committed Jul 19, 2024
1 parent d5ea928 commit 9cfac27
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 14 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ This source code is licensed under Apache 2.0 License.

- nebula-java: 3.6.0 -> 3.8.3
- org.hibernate:hibernate-core was excluded.
> If you need to use hibernate-core, please add the dependency by yourself.
> If you need to use hibernate-core, please add the dependency by yourself.
## Bugfix

Expand All @@ -48,6 +48,8 @@ This source code is licensed under Apache 2.0 License.
- feat: support ssl and http2 config in yml.
> http2 属于企业版的数据库才支持,但我没有测试环境,所以不确定是否可用。
> http2 is supported by the enterprise version of the database, but I don't have a test environment, so I'm not sure if it works.
- feat: support adding ID attributes of start and end nodes in edge entities.
> 通过 @DstId, @SrcId 进行注解,可以将属性标记成特殊的属性,用于查询时可以填充的起始点和终点的id值。
- example:

Expand Down
12 changes: 12 additions & 0 deletions ngbatis-demo/src/main/java/ye/weicheng/ngbatis/demo/pojo/Like.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
//
// This source code is licensed under Apache 2.0 License.

import javax.persistence.Id;
import javax.persistence.Table;
import org.nebula.contrib.ngbatis.annotations.DstId;
import org.nebula.contrib.ngbatis.annotations.SrcId;

/**
* <p>关系实体类示例。</p>
Expand All @@ -15,6 +18,15 @@
@Table(name = "like")
public class Like {

@Id // 可选,如果两个节点之间同一类型边的唯一性由源节点id和目标节点id共同决定,可以不加当前属性
private Long rank;

@SrcId // 可选,如果不需要获取关系的源节点id,可以不加当前属性
private String srcId;

@DstId // 可选,如果不需要获取关系的目标节点id,可以不加当前属性
private String dstId;

private Double likeness;

public Double getLikeness() {
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/nebula/contrib/ngbatis/annotations/DstId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.nebula.contrib.ngbatis.annotations;

// Copyright (c) 2024 All project authors. All rights reserved.
//
// This source code is licensed under Apache 2.0 License.

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* 用于标记目标ID的注解。
*
* @author yeweicheng
* @since 2024-07-18 17:27
* <br>Now is history!
*/
@Target(ElementType.FIELD)
@Retention(RUNTIME)
public @interface DstId {

}
24 changes: 24 additions & 0 deletions src/main/java/org/nebula/contrib/ngbatis/annotations/SrcId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.nebula.contrib.ngbatis.annotations;

// Copyright (c) 2024 All project authors. All rights reserved.
//
// This source code is licensed under Apache 2.0 License.

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* 用于标记源ID的注解。
*
* @author yeweicheng
* @since 2024-07-18 17:24
* <br>Now is history!
*/
@Target(ElementType.FIELD)
@Retention(RUNTIME)
public @interface SrcId {

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.nebula.contrib.ngbatis.annotations.DstId;
import org.nebula.contrib.ngbatis.annotations.SrcId;
import org.nebula.contrib.ngbatis.utils.ReflectUtil;

/**
Expand Down Expand Up @@ -51,6 +53,11 @@ public Object call(Object entity, String prefix, Boolean excludePk, Boolean sele
if (pkField != null && pkField.equals(field)) {
continue;
}

boolean isVidField = field.isAnnotationPresent(SrcId.class) || field.isAnnotationPresent(DstId.class);
if (excludePk && isVidField) {
continue;
}
fieldList.add(field);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ public static Object invoke(MethodModel methodModel, Object... args) {
* @return 结果值
*/
public static Object invoke(ClassModel classModel, MethodModel methodModel, Object... args) {
Method method = methodModel.getMethod();
ResultSet query = null;
// 参数格式转换
final long step0 = System.currentTimeMillis();
Expand Down
39 changes: 28 additions & 11 deletions src/main/java/org/nebula/contrib/ngbatis/utils/ReflectUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import static org.springframework.util.ObjectUtils.nullSafeEquals;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -413,25 +414,41 @@ public static Field getPkField(Field[] fields, Class<?> type) {
* @return 主键属性
*/
public static Field getPkField(Field[] fields, Class<?> type, boolean canNotNull) {
Field pkField = null;
Field typePkField = null;
return getAnnoField(fields, type, canNotNull, Id.class);
}

public static Field getAnnoField(Class<?> type, Class<? extends Annotation> anno) {
Field[] allColumnFields = getAllColumnFields(type);
return getAnnoField(allColumnFields, type, false, anno);
}

public static Field getAnnoField(
Field[] fields, Class<?> type, boolean canNotNull,
Class<? extends Annotation> anno) {
Field markedField = null;
Field typeMarkedField = null;
for (Field field : fields) {
if (field.isAnnotationPresent(Id.class)) {
pkField = field;
if (field.isAnnotationPresent(anno)) {
markedField = field;
if (field.getDeclaringClass().equals(type)) {
typePkField = field;
typeMarkedField = field;
}
}
}
// 多标签时,以运行时类中的 @Id 注解为准
if (typePkField != null) {
pkField = typePkField;
// 多标签时,以运行时类中的注解为准,如 @Id
if (typeMarkedField != null) {
markedField = typeMarkedField;
}
if (canNotNull && pkField == null) {
if (canNotNull && markedField == null) {
throw new ParseException(
String.format("%s 必须有一个属性用 @Id 注解。(javax.persistence.Id)", type));
String.format(
"%s 必须有一个属性用 @%s 注解。(%s)",
type,
anno.getSimpleName(),
anno.getName()
));
}
return pkField;
return markedField;
}

public static Class<?> typeArg(Object o, Class<?> parent, int i) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.nebula.contrib.ngbatis.annotations.DstId;
import org.nebula.contrib.ngbatis.annotations.SrcId;
import org.nebula.contrib.ngbatis.exception.ResultHandleException;
import org.nebula.contrib.ngbatis.models.MapperContext;
import org.nebula.contrib.ngbatis.proxy.MapperProxy;
Expand Down Expand Up @@ -307,7 +309,7 @@ public static <T> T relationshipToResultType(Relationship r, Class<T> resultType
for (Map.Entry<String, ValueWrapper> entry : properties.entrySet()) {
ReflectUtil.setValue(t, entry.getKey(), ResultSetUtil.getValue(entry.getValue()));
}
setRanking(t, resultType, r);
setEdgeExtraAttrs(t, resultType, r);
} catch (UnsupportedEncodingException | InstantiationException
| NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
Expand Down Expand Up @@ -366,6 +368,7 @@ public static void setId(Object obj, Class<?> resultType, Node v)
* @throws IllegalAccessException 当 ranking 值的类型,与
* e 中的 ranking 值的类型不匹配时报错,当属性被 final 修饰时报错
*/
@Deprecated
public static void setRanking(Object obj, Class<?> resultType, Relationship e)
throws IllegalAccessException {
Field pkField = getPkField(resultType, false);
Expand All @@ -377,6 +380,31 @@ public static void setRanking(Object obj, Class<?> resultType, Relationship e)
setRanking(obj, resultType.getSuperclass(), e);
}
}

public static void setEdgeExtraAttrs(Object t, Class<?> resultType, Relationship e)
throws IllegalAccessException {
Field pkField = getPkField(resultType, false);
if (pkField != null) {
long ranking = e.ranking();
ReflectUtil.setValue(t, pkField, ranking);
}

Field srcIdField = ReflectUtil.getAnnoField(resultType, SrcId.class);
if (srcIdField != null) {
Object srcId = ResultSetUtil.getValue(e.srcId());
ReflectUtil.setValue(t, srcIdField, srcId);
}

Field dstIdField = ReflectUtil.getAnnoField(resultType, DstId.class);
if (dstIdField != null) {
Object dstId = ResultSetUtil.getValue(e.dstId());
ReflectUtil.setValue(t, dstIdField, dstId);
}

if (resultType.getSuperclass() != null) {
setEdgeExtraAttrs(t, resultType.getSuperclass(), e);
}
}

/**
* Set java entity attributes from Node's properties.
Expand Down

0 comments on commit 9cfac27

Please sign in to comment.