对于最新稳定版本,请使用Spring Data Neo4j 8.0.0spring-doc.cadn.net.cn

唯一ID的处理与配置

使用内部的Neo4j id

给你的域类赋予唯一标识符最简单的方法是组合以下方式:@Id@GeneratedValue在 的类型域上字符串(最好是对象,而不是标量,字面意思是判断实例是否全新的最佳指标):spring-doc.cadn.net.cn

例子1。带有内部 Neo4j id 的可变电影实体
@Node("Movie")
public class MovieEntity {

	@Id @GeneratedValue
	private Long id;

	private String name;

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

你不需要为场地提供二传手,SDN会用反射来分配场地,但如果有二传手,也要用。 如果你想创建一个带有内部生成id的不可变实体,你必须提供一个凋零spring-doc.cadn.net.cn

例子2。带有内部 Neo4j id 的不可变电影实体
@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 这就是所谓的枯萎身份证-属性。 它创建一个新实体并相应设置字段,而不修改原实体,从而使其不可变。

你要么提供ID属性的设定器,要么像wither这样的东西,如果你想要的话spring-doc.cadn.net.cn

  • 优点:很明显,id 属性是代理业务密钥,使用它无需额外努力或配置。spring-doc.cadn.net.cn

  • 缺点:它与 Neo4js 内部数据库 ID 绑定,而该 ID 仅在数据库生命周期内对我们的应用实体独有。spring-doc.cadn.net.cn

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

使用外部提供的代理密钥

@GeneratedValue注释可以取一个实现的类org.springframework.data.neo4j.core.schema.IdGenerator作为参数。SDN提供内部生成器(默认值)和UUIDStringGenerator开箱即用。后者为每个实体生成新的UUID,并返回为java.lang.字符串. 使用该应用实体的应用实体会是这样的:spring-doc.cadn.net.cn

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

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

	private String name;
}

我们必须讨论两点关于优缺点的区别。分配本身和UUID策略。通用唯一标识符应当是唯一性的,以便实际作。引用维基百科:“因此,任何人都可以创建UUID,并用它几乎确定标识符不会重复已创建或将被创建的标识符,以识别其他东西。”我们的策略采用Java内部UUID机制,采用加密学强的伪随机数生成器。大多数情况下这应该没问题,但情况可能不同。spring-doc.cadn.net.cn

剩下的任务本身是:spring-doc.cadn.net.cn

  • 优势:应用完全控制,可以生成一个对应用目的来说恰到好处的唯一密钥。生成的值是稳定的,之后无需更改。spring-doc.cadn.net.cn

  • 缺点:生成的策略主要应用于应用端。在那个时代,大多数应用会在多个实例中部署,以实现良好的扩展性。如果你的策略容易产生重复,插入就会失败,因为主键的唯一性属性会被破坏。所以虽然在这种情况下你不必考虑唯一业务密钥,但你必须更多地思考要生成什么。spring-doc.cadn.net.cn

你有几种方式可以推出自己的ID生成器。其中一种是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-doc.cadn.net.cn

示例5。基于Neo4j客户端的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 使用你所需的查询或逻辑。

上面的生成器可以配置为豆子参考,如下: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;
}

使用商业密钥

我们在完整示例中使用了商业密钥电影实体PersonEntity. 该人的名字是在施工时分配的,既是你的应用程序,也是通过Spring Data加载时。spring-doc.cadn.net.cn

这只有在你找到稳定、唯一的业务密钥时才可能,但它们能很好地生成不可变域对象。spring-doc.cadn.net.cn

  • 优点:使用业务键或自然键作为主键是自然的。所涉及的实体被明确标识,在进一步建模你的领域时,大多数时候感觉恰到好处。spring-doc.cadn.net.cn

  • 缺点:一旦你意识到你找到的密钥并不像想象中那么稳定,将以业务密钥作为主键更新会很困难。通常它会改变,即使之前承诺过。除此之外,找到真正唯一的唯一标识符很难。spring-doc.cadn.net.cn

请记住,在Spring Data Neo4j处理业务密钥之前,域名实体上总是设置了业务密钥。这意味着它无法判断该实体是否是新的(它总是假设该实体是新的),除非还有@Version提供。spring-doc.cadn.net.cn