最新的稳定版本请使用 Spring Data Neo4j 7.3.1Spring中文文档

最新的稳定版本请使用 Spring Data Neo4j 7.3.1Spring中文文档

使用内部 Neo4j id

为域类提供唯一标识符的最简单方法是将 和 组合在类型为 or 的字段上(最好是对象,而不是标量,因为 literal 是更好的指示实例是否为新实例):@Id@GeneratedValueStringLonglongnullSpring中文文档

例 1.具有内部 Neo4j id 的可变 MovieEntity
@Node("Movie")
public class MovieEntity {

	@Id @GeneratedValue
	private Long id;

	private String name;

	public MovieEntity(String name) {
		this.name = name;
	}
}

无需为字段提供 setter,SDN 将使用反射来分配字段,但如果有 setter,则使用 setter。 如果要使用内部生成的 id 创建一个不可变的实体,则必须提供一个 witherSpring中文文档

例 2.具有内部 Neo4j id 的不可变 MovieEntity
@Node("Movie")
public class MovieEntity {

	@Id @GeneratedValue
	private final Long id; (1)

	private String name;

	public MovieEntity(String name) { (2)
		this(null, name);
	}

	private MovieEntity(Long id, String name) { (3)
		this.id = id;
		this.name = name;
	}

	public MovieEntity withId(Long id) { (4)
		if (this.id.equals(id)) {
			return this;
		} else {
			return new MovieEntity(id, this.title);
		}
	}
}
1 指示生成值的不可变最终 id 字段
2 公共构造函数,由应用程序和 Spring Data 使用
3 内部使用的构造函数
4 这就是 -attribute 的所谓凋零。 它创建一个新实体并相应地设置字段,而不修改原始实体,从而使其不可变。id

如果你想拥有Spring中文文档

  • 优点:很明显,id 属性是代理业务密钥,使用它不需要进一步的努力或配置。Spring中文文档

  • 缺点:它与 Neo4js 内部数据库 ID 绑定,它不是我们的应用程序实体仅在数据库生命周期内唯一的。Spring中文文档

  • 缺点:创建不可变实体需要付出更多努力Spring中文文档

1 指示生成值的不可变最终 id 字段
2 公共构造函数,由应用程序和 Spring Data 使用
3 内部使用的构造函数
4 这就是 -attribute 的所谓凋零。 它创建一个新实体并相应地设置字段,而不修改原始实体,从而使其不可变。id

使用外部提供的代理项密钥

注释可以将类实现作为参数。 SDN提供(默认)和开箱即用。 后者为每个实体生成新的 UUID,并将它们返回为 。 使用该实体的应用程序实体如下所示:@GeneratedValueorg.springframework.data.neo4j.core.schema.IdGeneratorInternalIdGeneratorUUIDStringGeneratorjava.lang.StringSpring中文文档

例 3.具有外部生成的代理项密钥的可变 MovieEntity
@Node("Movie")
public class MovieEntity {

	@Id @GeneratedValue(UUIDStringGenerator.class)
	private String id;

	private String name;
}

我们必须讨论关于优点和缺点的两件不同的事情。 任务本身和 UUID-Strategy。 通用唯一标识符在实际用途中是唯一的。 引用维基百科: “因此,任何人都可以创建一个UUID,并使用它来识别某些东西,几乎可以肯定,该标识符不会重复已经或将要创建的标识符,以识别其他东西。我们的策略使用 Java 内部 UUID 机制,采用加密能力强的伪随机数生成器。 在大多数情况下,这应该可以正常工作,但您的里程可能会有所不同。Spring中文文档

这样就剩下任务本身了:Spring中文文档

  • 优点:应用程序处于完全控制状态,可以生成一个唯一的密钥,该密钥对于应用程序的目的来说足够唯一。 生成的值将是稳定的,以后无需更改。Spring中文文档

  • 缺点:生成的策略应用于事物的应用端。 在那些日子里,大多数应用程序将部署在多个实例中,以便很好地扩展。 如果您的策略容易生成重复项,则插入将失败,因为将违反主键的唯一性属性。 因此,虽然在这种情况下,您不必考虑唯一的业务密钥,但您必须更多地考虑要生成的内容。Spring中文文档

您有多种选择来推出自己的 ID 生成器。 一个是实现生成器的 POJO:Spring中文文档

例 4.朴素序列生成器
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.data.neo4j.core.schema.IdGenerator;
import org.springframework.util.StringUtils;

public class TestSequenceGenerator implements IdGenerator<String> {

	private final AtomicInteger sequence = new AtomicInteger(0);

	@Override
	public String generateId(String primaryLabel, Object entity) {
		return StringUtils.uncapitalize(primaryLabel) +
			"-" + sequence.incrementAndGet();
	}
}

另一种选择是提供额外的 Spring Bean,如下所示:Spring中文文档

例 5.基于 Neo4jClient 的 ID 生成器
@Component
class MyIdGenerator implements IdGenerator<String> {

	private final Neo4jClient neo4jClient;

	public MyIdGenerator(Neo4jClient neo4jClient) {
		this.neo4jClient = neo4jClient;
	}

	@Override
	public String generateId(String primaryLabel, Object entity) {
		return neo4jClient.query("YOUR CYPHER QUERY FOR THE NEXT ID") (1)
			.fetchAs(String.class).one().get();
	}
}
1 准确使用所需的查询或逻辑。

上面的生成器将被配置为一个 bean 引用,如下所示:Spring中文文档

例 6.使用 Spring Bean 作为 Id 生成器的可变 MovieEntity
@Node("Movie")
public class MovieEntity {

	@Id @GeneratedValue(generatorRef = "myIdGenerator")
	private String id;

	private String name;
}
1 准确使用所需的查询或逻辑。

使用业务密钥

我们一直在完整示例和 PersonEntity 中使用业务密钥。 此人的姓名是在施工时分配的,无论是由您的应用程序还是通过 Spring Data 加载时。MovieEntitySpring中文文档

这只有在找到一个稳定的、唯一的业务密钥时才有可能,但可以创建出色的不可变域对象。Spring中文文档

  • 优点:使用业务键或自然键作为主键是很自然的。 有问题的实体被清楚地识别出来,并且在进一步建模您的域时,大多数时候感觉都恰到好处。Spring中文文档

  • 缺点:一旦您意识到您找到的密钥并不像您想象的那么稳定,作为主密钥的业务密钥将很难更新。 通常事实证明,即使另有承诺,它也可以改变。 除此之外,很难找到真正唯一的标识符。Spring中文文档

请记住,在Spring Data Neo4j处理业务密钥之前,始终在域实体上设置业务密钥。 这意味着它无法确定该实体是否为新实体(它始终假定该实体是新的), 除非还提供了@Version字段Spring中文文档