项目中使用了neo4j数据库,neo4j是什么就不用介绍了吧,图形数据库的王者,如果不了解的话还是先去了解一下吧,他的cypher已经成为图形数据库的事实上的标准了。
本次主要记一下我自己使用过程中用到的东西或者是坑,已经从SDN4.x迁移到5.1发现的问题,大部分其实都是从文档中得到的,所以有能力最好还是看文档,看文档也不要一字一句的从头到尾看,这种看法,很有可能让你刚翻译完目录就失去了看正文的动力,最好是带着问题看,看一下本次文档的更新是什么,或者从入门看起,spring的文档都是非常详尽的,一般你的问题都是可以在文档中找到解决办法的。这里贴上SDN的文档,方便大家。SDN文档点击这里。neo4j开发者文档点击这里
好了,开始正文,本文不定时更新,看我工作中遇到什么问题就写到哪(我文章里一般只写了我用到的部分的变化以及坑,还还有的变化以及坑需要各位自己去发掘!)。
其中一个最大的坑就是:使用spring boot的时候,除非是你自己开发的依赖包,否则不要指定你的依赖的版本啊,不然你升级的时候会被各种各样的冲突烦死,到处充斥着classnotfound,methodnotfound的异常,真的是神烦啊!spring boot的一个吸引人的地方就是为你搞定了所有的依赖冲突,你只需要使用就可以了呀!
Optional<T>
.Optional是jdk8中引入的一个很好用的类,免去了我们一系列的空指针判断的逻辑,美化我们的代码。
分页自定义查询不再接受没有countQuery属性的查询。(不过我项目中也不用这东西,neo4j需要分页的查询我目前还没遇到,我司目前还是以mysql为主,neo4j只在用户分析进行了使用,不过在国外的一些公司,已经全面转为neo4j)
实体相关我们当然是介绍实体的注解@NodeEntity呀!
使用@NodeEntity标注的类,如果不指定@NodeEntity的label字段,那么就会默认使用类名作为label,否则使用label的值作为label。
@NodeEntity//这个类在保存的时候label就会被设置成(:User)
public class User{
String name;
String uid;
}
@NodeEntity(label ="newUser")//这个类在保存的时候label就会被设置成(:newUser)
public class User{
String name;
String uid;
}
如果一个类A继承了另一个B,那么SDN在保存的时候就会将其父类的名称也加到他的label上,由于neo4j中并没有数据库的概念,也不可能为一个业务设置一个数据库,所有最好设置一个domain对象,用来作为数据库的概念,不同业务线可以有不同的域对象,便于查询,减少互相 的影响,加快查询。
@NodeEntity//这个类在保存的时候label就会被设置成(:User:BaseDoMain)
public class User extends InvestBaseDoMain{
String name;
String uid;
}
public class BaseDoMain{
}
节点属性注解,注解在field上的,这个注解并不是必须的,实体中的属性都会被持久化到库中,在库中的属性名称就是field名称。 @Property有一个name字段,这个字段的作用是指定实体中的field映射到库中的属性名称。
@NodeEntity
public class User extends InvestBaseDoMain{
//库中的属性名称就是name
String name;
String uid;
@Property(name = "insert_Time")//库中的属性字段名称就是insert_Time
private Date insertTime;
}
这个注解在5.x中已经被废弃,之前用作承载neo4j节点的唯一识别属性id,但是neo4j中这个id是有一定问题的:这个id是会复用的,例如线程T1取了一个节点A的数据进行长时间的处理,但是这期间另一个线程T2删除了这个节点,neo4j会回收这个id,并将id分配给另一个节点B,如果线上T1这时候根据@GraphId的字段去更新数据就会造成数据更新错误(这里更新包括delete),所以在之前的版本中SDN就不建议你使用这个列去做唯一约束,希望你的对象中使用自定义的唯一约束的field,在5.x中废弃了这个注解,但是为了向后兼容,保留了他,但是之后的某个版本会删除,所以大家不要用这个注解。
@Id就是用来取代@GraphId的
@Id注解的field必须是Long类型的
如果只使用了@Id注解,那么需要在程序中指定这个字段的值,当前SDN一定会贴心的给你准备好默认的id生成器,将@Id注解的属性上加上@GeneratedValue就可以SDN自动生成id,在将实体保存到neo4j时会自动分配此ID,你的代码中永远不应为其分配值。@GeneratedValue默认使用InternalIdStrategy生成id,如果你的项目是分布式的,你也可以实现IdStrategy接口,自定义发号器
SDN在这个版本中提供了乐观锁实现,我们只需要在一个Long类型的属性上加这个注解就可以实现乐观锁,十分方便,对业务代码几乎没有任何侵入,一个实体中只能有一个@version的字段!
乐观锁字段变化过程如下: