使用Spring Data Neo4j(SDN)

10 篇文章 0 订阅
2 篇文章 0 订阅

使用 Spring Data Neo4j

maven 依赖

pom依赖中只要加入如下即可:

注意:SDN默认使用 Bolt Driver 连接的方式,若要使用 embedded driver 或 HTTP driver 需要加入相关依赖

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>{version}</version>
</dependency>

配置文件属性

在application.properties 中配置neo4j 的相关属性:

# NEO4J (Neo4jProperties)
spring.data.neo4j.auto-index=none # Auto index mode.
spring.data.neo4j.embedded.enabled=true # Whether to enable embedded mode if the embedded driver is available.
spring.data.neo4j.open-in-view=true # Register OpenSessionInViewInterceptor. Binds a Neo4j Session to the thread for the entire processing of the request.
spring.data.neo4j.password= # Login password of the server.
spring.data.neo4j.repositories.enabled=true # Whether to enable Neo4j repositories.
spring.data.neo4j.uri= # URI used by the driver. Auto-detected by default.
spring.data.neo4j.username= # Login user of the server.

属性文件配置的形式只有这几个属性可以设置,通过查看 org.springframework.boot.autoconfigure.data.neo4j.Neo4jProperties的源码可以知道:

@ConfigurationProperties(prefix = "spring.data.neo4j")
public class Neo4jProperties implements ApplicationContextAware {

	static final String EMBEDDED_DRIVER = "org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver";

	static final String HTTP_DRIVER = "org.neo4j.ogm.drivers.http.driver.HttpDriver";

	static final String DEFAULT_BOLT_URI = "bolt://localhost:7687";

	static final String BOLT_DRIVER = "org.neo4j.ogm.drivers.bolt.driver.BoltDriver";

	/**
	 * URI used by the driver. Auto-detected by default.
	 */
	private String uri;

	/**
	 * Login user of the server.
	 */
	private String username;

	/**
	 * Login password of the server.
	 */
	private String password;

	/**
	 * Auto index mode.
	 */
	private AutoIndexMode autoIndex = AutoIndexMode.NONE;

	/**
	 * Register OpenSessionInViewInterceptor. Binds a Neo4j Session to the thread for the
	 * entire processing of the request.",
	 */
	private Boolean openInView;

	private final Embedded embedded = new Embedded();

	private ClassLoader classLoader = Neo4jProperties.class.getClassLoader();

	@Override
	public void setApplicationContext(ApplicationContext ctx) throws BeansException {
		this.classLoader = ctx.getClassLoader();
	}

	/**
	 * Create a {@link Configuration} based on the state of this instance.
	 * @return a configuration
	 */
	public Configuration createConfiguration() {
		Builder builder = new Builder();
		configure(builder);
		return builder.build();
	}

	private void configure(Builder builder) {
		if (this.uri != null) {
			builder.uri(this.uri);
		}
		else {
			configureUriWithDefaults(builder);
		}
		if (this.username != null && this.password != null) {
			builder.credentials(this.username, this.password);
		}
		builder.autoIndex(this.getAutoIndex().getName());
	}

	private void configureUriWithDefaults(Builder builder) {
		if (!getEmbedded().isEnabled()
				|| !ClassUtils.isPresent(EMBEDDED_DRIVER, this.classLoader)) {
			builder.uri(DEFAULT_BOLT_URI);
		}
	}

	public static class Embedded {

		/**
		 * Whether to enable embedded mode if the embedded driver is available.
		 */
		private boolean enabled = true;

		public boolean isEnabled() {
			return this.enabled;
		}

		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
	}

    //省略相关的 getter 和 setter
    
}

Java Config 配置

如果要自定义配置属性,则需要使用 Java Config 的形式,本人在测试 SDN 的并发写入属性时遇到连接池资源不足的情况,需要设置连接池大小,OGM(Object-Graph Mapping)中提供了这个属性,但是在SDN中并没用对外暴露设置,所以使用application.properties没用默认可配置属性,可以使用如下Java Config的方法来实现一些特殊属性的配置:@Value注解的属性在application.properties中进行声明管理就可以使用了

Java Config:

/**
 *  Neo4j OGM 配置
 */
@Configuration
public class Neo4jConfig {

    @Value("${neo4j.uri}")
    private String uri;

    @Value("${neo4j.username}")
    private String username;

    @Value("${neo4j.password}")
    private String password;

    @Value("${neo4j.connection.pool.size}")
    private Integer connectionPoolSize;

    @Bean
    public SessionFactory getSessionFactory() {
        return new SessionFactory(configuration(), "com.kay.model.neo4j");
    }

    @Bean
    public Neo4jTransactionManager transactionManager(){
        return new Neo4jTransactionManager(getSessionFactory());
    }

    @Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        return new org.neo4j.ogm.config.Configuration.Builder()
                .uri(uri)
                .connectionPoolSize(connectionPoolSize)  //配置连接池大小
                .credentials(username,password)       //用户密码
                .autoIndex("update")                 //索引策略
                .build();
    }
}

Neo4j 与 对象实体间的映射

节点映射

实体对象的配置:比如我在 Neo4j 中有 一个 User 节点,添加 OGM 提供的注解进行如下映射即可:

/**
 * Created by kay on 2018/6/20
 */
@Data  //这是lombok 的注解
@NodeEntity
public class User {

    @Id
    @GeneratedValue
    private Long id; // neo4j 自动生成的唯一ID

    private String userId;       

    private String phone;       

    private String nickName;    

    @DateLong   //将日期类型转换为时间戳,或者用 @DateString 转换为String
    private Date createTime;

}
关系映射

比如一个用户 User,他可能参演了一部电影 Movie, 那么这之间就有一种关系,演员参演电影:

(u:User)-[ACTED_IN]->(m:Movie) , 用对象来表示就是:

// 参演
@RelationshipEntity(type = "ACTED_IN")
public class Role {

    @Id
    @GeneratedValue
	private Long id;
	private List<String> roles = new ArrayList<>(); 

	@StartNode  // 代表关系的起点
	private User user;

	@EndNode    //代表关系的终点
	private Movie movie;

	public Role() {
	}

	public Role(Movie movie, Person actor) {
		this.movie = movie;
		this.person = actor;
	}

	//getter setter
   
}

User类里面再加上一个Movie 的集合,代表参演的电影:

@Relationship(type = "ACTED_IN")
private List<Movie> movies = new ArrayList<>();

这样一个 用户参演多部电影的关系就出来了。

给节点添加 Lable

一个 User参演了电影,那么他还是一个演员 Actor,此时他就应该有2个Lable,分别代表他的不同身份:

User类里面添加

 @Labels
 private List<String> labels = new ArrayList<>();

@Lables 代表这个String 集合是User的所有标签,每当User有一个新的Label,就可以 add 进入即可。

添加索引

如果在进行图遍历的时候,需要给属性添加索引,可按如下方式添加:

// @Index(unique=true) //可设置唯一约束
@Index
private String userId;  

使用Spring Data Neo4j

SDN 提供了类似于 JPA 接口,只要继承 Neo4jRepository接口即可使用:

public interface UserNeo4jRepository extends Neo4jRepository<User,Long> {}

其默认提供了很多查询方法的实现,只要遵循Spring Data 的规范即可使用,例如

findBy+属性名
findLike+属性名

当然也可以自己写Cypher语句来进行操作,只要加上@Query注解即可

@Query("match (u:User) where u.userId={0} return u ")
User findByUserId(String userId);

其他使用 和 Spring Data 其他模块使用方法一样,不再赘述。

OGM 索引策略

在使用 Java Config 配置 Neo4j 的时候使用了如下代码:

@Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        return new org.neo4j.ogm.config.Configuration.Builder()
                .uri(uri)
                .connectionPoolSize(connectionPoolSize)  //配置连接池大小
                .credentials(username,password)       //用户密码
                .autoIndex("update")                 //索引策略
                .build();
    }

其中 autoIndex("update")是 OGM 提供的一种索引策略,其规则如下:

OptionDescriptionProperties ExampleJava Example
none (default)Nothing is done with index and constraint annotations.--
validate确保连接的数据库在启动前具有所有索引和约束indexes.auto=validateconfig.setAutoIndex(“validate”);
assert在启动时删除所有约束和索引,然后根据@Index在OGM中表示的内容构建索引。方便在开发过程中indexes.auto=assertconfig.setAutoIndex(“assert”);
update根据@Index在OGM中表示的任何内容构建索引。如果数据库中的定义与元数据不同,索引将更改为约束,反之亦然。方便在开发过程中indexes.auto=updateconfig.setAutoIndex(“update”);
dump将生成的约束和索引转储到文件。很适合建立环境。 none:默认。只需将该字段标记为使用索引即可indexes.auto=dump indexes.auto.dump.dir= indexes.auto.dump.filename=config.setAutoIndex(“dump”); config.setDumpDir(“XXX”); config.setDumpFilename(“XXX”);

其源码如下,通过注释也可以看出各种策略的作用:

package org.neo4j.ogm.config;
 
/**
* Denotes the types of auto indexing that can be done by the OGM at startup.
*
* @author Mark Angrish
*/
public enum AutoIndexMode {
    /**
     * No indexing will be performed.
     */
    NONE("none"),
 
    /**
     * Removes all indexes and constraints on startup then creates all indexes and constraints defined in metadata.
     */
    ASSERT("assert"),
 
    /**
     * Creates all missing indexes and constraints.
     * <p>
     * If there is an index in the database and constraint in the metadata the index is dropped and constraint created.
     * (and vise versa).
     * <p>
     * Other indexes and constraints are left untouched.
     * <p>
     * NOTE: When a field with index or constraint is renamed new index or constraint will be created.
     * Existing for the old name will be left untouched.
     */
    UPDATE("update"),
 
    /**
     * Ensures that all constraints and indexes exist on startup or will throw a Runtime exception.
     */
    VALIDATE("validate"),
 
    /**
     * Runs validate then creates a file (in same dir where launched) with the cypher used to build indexes and constraints.
     */
    DUMP("dump");
 
    /**
     * Parses an option name into the Enumeration type it represents.
     *
     * @param name The lowercase name to parse.
     * @return The <code>AutoIndexMode</code> this name represents.
     */
    public static AutoIndexMode fromString(String name) {
        if (name != null) {
            for (AutoIndexMode mode : AutoIndexMode.values()) {
                if (name.equalsIgnoreCase(mode.name)) {
                    return mode;
                }
            }
        }
        return null;
    }
 
    private final String name;
 
    AutoIndexMode(String name) {
 
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
}

小结

Spring Data Neo4j 的使用方式类似于 Spring Data JPA等其他模块,不过其实现也并没用JPA提供的那么多,具体的支持可以参考 SDN的官方文档参看,需要注意的是,如果 节点关系映射处理的不好,可能在查询的时候会带来级联查询,也就是 1+N 问题,查询一个节点带出 N 层关系,可以通过在下层终止的节点上加上 @JsonIgnore 注解取消属性的向下级联。当然这个问题也可以通过自定义Cypher 来实现,而不使用 SDN 提供的默认方法。

参考文档:

https://docs.spring.io/spring-data/neo4j/docs/5.0.7.RELEASE/reference/html/#reference

转载请注明出处:https://blog.csdn.net/sinat_25295611

Spring Data Neo4j是一个通过对象图映射(OGM)技术将Neo4j图数据库集成到Spring应用程序中的框架。 使用Spring Data Neo4j,您可以将Neo4j作为您的应用程序的数据存储,使用Java对象来表示节点和关系,并使用注释或接口定义查询和持久性操作。 下面是Spring Data Neo4j使用步骤: 1. 添加依赖项 您需要将以下依赖项添加到您的Maven或Gradle构建文件中,以使用Spring Data Neo4j: ``` <!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> <!-- Gradle --> implementation 'org.springframework.boot:spring-boot-starter-data-neo4j' ``` 2. 配置数据库连接 您需要在application.properties或application.yml文件中配置Neo4j数据库连接信息: ``` spring.data.neo4j.uri=bolt://localhost:7687 spring.data.neo4j.username=neo4j spring.data.neo4j.password=password ``` 3. 创建实体类 您需要创建Java类来表示Neo4j节点和关系。您可以使用@NodeEntity和@RelationshipEntity注释来定义这些类。例如: ``` @NodeEntity public class Person { @Id @GeneratedValue private Long id; private String name; @Relationship(type = "FRIEND") private List<Person> friends; // getters and setters } @RelationshipEntity(type = "FRIEND") public class Friendship { @Id @GeneratedValue private Long id; @StartNode private Person person1; @EndNode private Person person2; private Date since; // getters and setters } ``` 4. 定义存储库 您需要创建一个存储库接口来定义CRUD操作和自定义查询。您可以扩展Neo4jRepository接口或使用Repository接口定义您自己的方法。例如: ``` public interface PersonRepository extends Neo4jRepository<Person, Long> { List<Person> findByName(String name); @Query("MATCH (p:Person)-[:FRIEND]->(f:Person) WHERE p.name = $name RETURN f") List<Person> findFriendsByName(String name); } ``` 5. 使用存储库 您可以使用自动装配的存储库接口来执行CRUD操作和自定义查询。例如: ``` @Autowired private PersonRepository personRepository; public void savePerson(Person person) { personRepository.save(person); } public List<Person> findFriendsByName(String name) { return personRepository.findFriendsByName(name); } ``` 这就是Spring Data Neo4j的基本使用方法。通过使用它,您可以轻松地将Neo4j图数据库集成到Spring应用程序中,并使用Java对象来表示节点和关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带着天使反上帝 - Kaybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值