java api操作
java api操作neo4j框架类似于创建jdbc连接(图数据也是数据库嘛)
public static void main(String[] args) {
//获取neo4j的驱动
Driver driver = GraphDatabase.driver("bolt://172.16.2.207:7687", AuthTokens.basic("neo4j", "neo4j123"));
Session session = null;
Transaction transaction = null;
try {
//获取会话 connection
session = driver.session();
//开启事务
transaction = session.beginTransaction();
//创建Statement
Statement query = new Statement(
"CREATE (a:Greeting) SET a.message = $message RETURN a.message + ', from node ' + id(a)",
Values.parameters("message", "testDriver"));
StatementResult result = transaction.run(query);
//提交事务
transaction.success();
String greeting = result.single().get(0).asString();
System.out.println(greeting);
}catch (Exception e){
//事务回滚
transaction.rollbackAsync();
}
finally {
//关闭相关资源
if(session.isOpen()){
session.close();
}
if(transaction.isOpen()){
transaction.close();
}
driver.close();
}
}
springBoot整合neo4j
相关配置
依赖
springBoot版本:2.1.5.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
配置
# neo4j配置
spring:
data:
Neo4j:
uri: bolt://172.16.2.207:7687
username: neo4j
password: neo4j123
例子
neo4j数据库使用类似于spring-data的JPA,设置实体(Entity)、Dao层(Repository)
设置实体
//任务对象
@Data
@NodeEntity(label = "Person")
public class Person {
@Id
@GeneratedValue
private Long id;
@Property(name = "name")
private String name;
@Property(name = "title")
private String title;
}
//关系
@Data
@RelationshipEntity
public class Relation {
@Id
@GeneratedValue
private Long id;
@Property(name = "name")
private String name;
/**
* 关系方向 StartNode -指向-> EndNode
*/
@StartNode
private Person from;
@EndNode
private Person to;
}
- @NodeEntity:标明是一个节点实体
- @RelationshipEntity:标明是一个关系实体
- @Id:实体主键
- @Property:实体属性
- @GeneratedValue:实体属性值自增
- @StartNode:开始节点(可以理解为父节点)
- @EndNode:结束节点(可以理解为子节点)
dao层
dao层可以继承org.springframework.data.neo4j.repository.Neo4jRepository接口,这个接口有基础的curd相关接口,对于其他复杂sql我们可以使用@Query 编写一些复杂的语句
@Repository
public interface PersonRepository extends Neo4jRepository<Person,Long> {
@Query("MATCH p=(n:Person) RETURN p")
List<Person> selectAll();
@Query("MATCH(p:Student{name:{name}}) return p")
Person findByName(String name);
@Query(
"MERGE (p:Person { name:{0}})"+
"SET p.title = {1}"+
"RETURN p")
Person merge(String name,String title);
}
service服务层
public class PersonServiceImpl implements PersonService {
@Resource
private PersonRepository personRepository;
@Override
public boolean save(Person person) {
boolean susFlag = true;
try{
personRepository.save(person);
}catch (Exception e){
log.error("保存person数据失败,异常信息:",e);
susFlag = false;
}
return susFlag;
}
@Override
public List<Person> selectAll() {
return personRepository.selectAll();
}
@Override
public Person findByName(String name) {
return personRepository.findByName(name);
}
}
单元测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Neo4jApplication.class)
@WebAppConfiguration
@Slf4j
public class PersonTest {
@Resource
private PersonService personService;
@Test
public void savePersonTest(){
Person person = new Person();
person.setName("小猪妖");
person.setTitle("大王待我很不错");
personService.save(person);
}
@Test
public void queryOne(){
Person person = personService.findByName("小猪妖");
log.info("查询出来的学生信息:{}", JsonUtil.obj2str(person));
}
@Test
public void queryList(){
List<Person> personList = personService.selectAll();
log.info("查询出来的学生信息:{}", JsonUtil.obj2str(personList));
}
}
springBoot整合原理
通过spring自动装配,会加载spring-boot-autoconfig下的spring.factories中的自动装配类,其中自动装配类有很多,与neo4j有关自动装配类有两个Neo4jDataAutoConfiguration、Neo4jRepositoriesAutoConfiguration。
自动装配类 | 描述 |
---|---|
Neo4jDataAutoConfiguration | 配置与neo4j有关的SqlSessionFactory、事务管理TransactionManager |
Neo4jRepositoriesAutoConfiguration | 类似于spring JPA的支持 |
SqlSessionFactory | 是创建SqlSession的工厂类 |
SqlSession | neo4j执行一次图数据库操作(读写)的会话 |
TransactionManager | neo4j的事务管理,同mysql数据库一样也支持开启事务、提交和回滚 |
neo4j事务
neo4j框架的默认隔离级别为–>读已提交:每次事务只能看到已经提交的数据。
默认neo4j每次cypher语句都会开始事务,对于复杂业务多个cypher可以借助spring的事务管理器去控制事务(硬编码的形式也可)
配置事务管理器
@Configuration
@EnableTransactionManagement
@EnableNeo4jRepositories(basePackages = {"com.xiu.study.neo4j.repository"})
@EntityScan(basePackages = {"com.xiu.study.neo4j.domain"} )
@DependsOn("sessionFactory")
public class TransactionAspect {
/**
* 定义neo4j事务管理器
* @param sessionFactory
* @return neo4j事务管理器
*/
@Bean("neo4jTransactionManager")
public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) {
return new Neo4jTransactionManager(sessionFactory);
}
}
那么只需要在需要添加事务的服务方式上使用Spring的@Transactional()即可。
neo4j事务与mysql事务冲突处理
当项目中同时需要使用mysql框架和neo4j框架同时因为使用spring的事务管理无法支持多个数据源的事务处理,默认生效的是mysql事务,所有我们需要显示的配置多个事务管理器放入spring容器,在使用时候需要显示的指明使用哪种类型的事务管理器去管理事务。示例如下:
@Configuration
@EnableTransactionManagement
@EnableNeo4jRepositories(basePackages = {"com.xiu.study.neo4j.repository"})
@EntityScan(basePackages = {"com.xiu.study.neo4j.domain"} )
@DependsOn("sessionFactory")
public class TransactionAspect {
/**
* 定义mysql事务管理器,必须有transactionManager作为默认事务管理器
*/
@Bean("transactionManager")
@Primary
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 定义neo4j事务管理器
*/
@Bean("neo4jTransactionManager")
public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) {
return new Neo4jTransactionManager(sessionFactory);
}
}
使用neo4j @Transactional注解中显示的指定使用 neo4jTransactionManager 事务管理器。
@Transactional(value="neo4jTransactionManager",rollbackFor = Exception.class)
@Override
public boolean save(Person person) {
boolean susFlag = true;
personRepository.save(person);
//模拟错误,查看事务回滚情况
int i = 1/0;
person.setName("乌鸦");
personRepository.save(person);
return susFlag;
}