此版本仍在开发中,目前尚不被视为稳定版本。如需最新稳定版本,请使用 Spring Data Neo4j 8.0.4spring-doc.cadn.net.cn

唯一ID的处理与分配

使用内部 Neo4j ID

为您的领域类赋予唯一标识符最简单的方法是在类型为 StringLong 的字段上组合使用 @Id@GeneratedValue(优选对象类型,而非标量类型 long,因为字面量 null 更能明确指示实例是新建还是已存在):spring-doc.cadn.net.cn

示例 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方法,Spring Data Neo4j(SDN)将使用反射来赋值该字段,但如果存在setter方法,则会优先使用setter方法。如果希望创建一个具有内部生成ID的不可变实体,则必须提供一个wither方法。spring-doc.cadn.net.cn

示例 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 表示生成值的不可变 final id 字段
2 Public 构造函数,供应用程序和 Spring 数据使用
3 内部使用的构造函数
4 这是一个所谓的wither方法,它为id属性提供支持。它会创建一个新的实体,并按照要求设置该字段,而不修改原始实体,从而使其不可变。

您要么必须为 id 属性提供 setter,要么像wither这样的东西,如果您想要...spring-doc.cadn.net.cn

  • 优势: 显然,id 属性是业务主键的代理键, 使用它无需进一步的努力或配置。spring-doc.cadn.net.cn

  • 缺点:它与 Neo4j 的内部数据库 id 耦合,这仅在整个数据库生命周期内对我们的应用程序实体唯一。spring-doc.cadn.net.cn

  • 缺点:创建不可变实体需要更多的努力spring-doc.cadn.net.cn

使用外部提供的替代键

注解 @GeneratedValue 可以接受一个实现 org.springframework.data.neo4j.core.schema.IdGenerator 的类作为参数。 SDN 提供了 InternalIdGenerator (默认)和 UUIDStringGenerator 开箱即用的实现。 后者会为每个实体生成新的 UUID,并将其作为 java.lang.String 返回。 使用该功能的应用实体如下所示:spring-doc.cadn.net.cn

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

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

	private String name;
}

我们需要讨论关于优势和劣势的两个单独的事情。分配本身和UUID-Strategy。通用唯一标识符旨在在实际目的上是唯一的。引用维基百科:“因此,任何人都可以创建一个UUID,并使用它来几乎肯定地对某事物进行编号,该编号不会重复已经创建或将来创建的其他标识符。”我们的策略使用Java内部UUID机制,采用加密强伪随机数生成器。在大多数情况下,这应该没问题,但你的里程可能会有所不同。spring-doc.cadn.net.cn

这就留下了作业本身:spring-doc.cadn.net.cn

  • 优势:应用程序完全受控,可以生成一个唯一的键,该键仅适合应用程序目的。生成的值将是稳定的,以后不需要更改。spring-doc.cadn.net.cn

  • 失利之处:所生成的策略将会运用到事物的使用端层面。 在那些日子,大多数应用都将在多于一个实例上进行部署,以便更好地扩展。 如果你的策略容易产生重复项,那么插入操作就会失败,因为主键的唯一性属性会被违反。 所以,在这种情况下,虽然你不必思考独特的业务键,但你必须考虑要生成什么。spring-doc.cadn.net.cn

你有几种选项可以推出你自己的生成器。一种是实现一个生成器的 POJO:spring-doc.cadn.net.cn

示例 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-doc.cadn.net.cn

示例 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-doc.cadn.net.cn

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

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

	private String name;
}

使用业务密钥

我们已经在完整示例的MovieEntityPersonEntity中使用了业务密钥。
名称是在构造时分配给该人的,无论是由您的应用程序还是通过Spring Data加载。spring-doc.cadn.net.cn

只有在你找到一个稳定、唯一的业务键时,这才可能实现,但这样可以创建出非常不可变的领域对象。spring-doc.cadn.net.cn

  • 优势:使用业务键或自然键作为主键是自然的。实体被明确标识,并且在大多数情况下,在进一步建模您的域时感觉最正确。spring-doc.cadn.net.cn

  • 缺点:业务密钥作为主密钥一旦发现不是像你想象的那样稳定,就很难更新。 <br/> 通常会发现它可能会更改,即使承诺并非如此。 <br/> 除了这个之外,找到真正对于一个事物唯一的标识符是很困难的。spring-doc.cadn.net.cn

请注意,在域实体上 always 设置业务键之前,Spring Data Neo4j 处理它时,无法判断该实体是否为新实体(它总是假设该实体是新的),除非也提供了一个 @Version 字段。spring-doc.cadn.net.cn