提到spring boot整合Neo4j,一般都会提到spring-data-neo4j,使用类似于jpa的方式,使用entity去maintain,但是如果想要添加动态关系或者动态的node,就算是@Query也是不够用了
使用OGM
其实这个包也被spring-data-neo4j引入了,所以不必要单独引入
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.neo4j.ogm.model.Result;
@Service
public class NodeService {
private final Logger log = LoggerFactory.getLogger(NodeService.class);
@Autowired
private SessionFactory sessionFactory;
public Result searchPath(SearchPathDTO searchPathDTO) {
String cypher = "MATCH (n:" + searchPathDTO.getFromNode() + "{" + searchPathDTO.getProperity() + ":'"
+ searchPathDTO.getValue() + "'}) "
+ "CALL apoc.path.subgraphAll(n,{relationshipFilter: '<|>',minLevel: 0,maxLevel: -1}) "
+ "YIELD nodes,relationships RETURN nodes, relationships";
Session session = sessionFactory.openSession();
return session.query(cypher, new HashMap<>(), false);
}
}
这样以来,就可以动态拼接cypher,更加灵活,可以实现更加复杂的查询了.
优化
这样获取session会有一个问题,就是在使用事务的时候无法统一管理.
优化之后写一个公共Util类,获取session的时候调用这个类,把sessionFactory传进来就可以了
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.neo4j.transaction.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
public class TransactionUtils {
private static final Logger log = LoggerFactory.getLogger(TransactionUtils.class);
private TransactionUtils() {
}
public static Session getSession(SessionFactory sessionFactory) {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder == null) {
log.error("Can not get seesion from spring neo4j sessionHolder, the previously created transaction will be invalidated.");
Session session = sessionFactory.openSession();
return session;
}
return sessionHolder.getSession();
}
}