简介
neo4j是一种图数据库,项目开发中可能会用到。
使用的版本:
- SpringBoot 2.5.5
- neo4j 4.3
- Java 11
Maven配置:
Maven只需要配置starter即可,但starter里只包含最新版本内容,不能兼容旧版本api(貌似)。所以写代码的时候要注意。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
yaml配置:
这里配置的是bolt协议。
为什么使用bolt协议
spring:
neo4j:
authentication:
password: 123456
username: neo4j
uri: bolt://localhost:7687
使用ORM
完成配置之后,按照SpringBoot的常用层次搭建一个小demo。
项目结构如下:
实体层
注意:为了后续转换方便,最好把属性名和数据库里设置成一样的。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Node(labels = {"Station"})
public class Station implements Serializable {
@Id
@GeneratedValue
private Long id; // 这个是系统生成的假id
@Property(name = "name")
private String name;
@Property(name = "englishname")
private String englishname;
@Property(name = "stationid")
private String stationid; // 真实使用的id
@Relationship(type = "NEAR", direction = Relationship.Direction.OUTGOING)
private Set<Station> nearStations = new HashSet<>();
}
DAO
@Repository
public interface StationRespository extends Neo4jRepository<Station,Long> { // 类型和id对应
@Query("MATCH (c:Station) WHERE c.stationid = $id RETURN c")
Station findStationById(String id);
@Query("MATCH (c:Station)-[r]->() WHERE r.name = $routeName RETURN c")
List<Station> findStationsByName(String routeName);
}
服务层
@Service
public class BusInfoServiceImpl implements BusInfoService{
@Autowired
StationRespository stationRespository;
@Override
public Station findStationById(String Id) {
return stationRespository.findStationById(Id);
}
@Override
public List<Station> findRouteByName(String routeName) {
return stationRespository.findRouteByName(routeName);
}
}
控制层
@RestController
public class BusInfoController {
@Autowired
private BusInfoServiceImpl busInfoService;
@GetMapping(path = "/StationById")
public Station findStationById(
@RequestParam(name = "id") String id
){
return busInfoService.findStationById(id);
}
@GetMapping(path = "/RouteByName")
public List<Station> findRouteByName(
@RequestParam(name = "routeName") String routeName
){
return busInfoService.findRouteByName(routeName);
}
}
使用Driver
ORM在有些方面不能很好满足我们的需求,可能有时会需要使用驱动连接数据库。
配置驱动:编写configuration
// 因为要使用驱动开发,使用配置类装配Driver
public class Neo4jConfig {
@Value("${spring.neo4j.authentication.username}")
private String username;
@Value("${spring.neo4j.authentication.password}")
private String password;
@Value("${spring.neo4j.uri}")
private String uri;
@Bean
public Driver neo4jDriver() {
return GraphDatabase.driver(uri, AuthTokens.basic(username,password));
}
}
在开发中使用Driver的示例:
try (Session session = neo4jDriver.session()) {
String cypher = String.format("MATCH p=(s)-[r *.. {name:'%s'}]->(e) where '%s' in s.begins and '%s' in e.ends RETURN p", routeName, routeName, routeName);
Result result = session.run(cypher);
try {
List<Record> records = result.list();
Record record = null;
if (records != null) {
record = records.get(0);
}
Value value = record.get("p"); // 因为是return p
Path path = value.asPath(); // 返回的是路径类型,故使用.asPath()
// 得到node结果后,类型转换并加入line的station list
for (Node node : path.nodes()) {
Map<String, Object> map = node.asMap();
String mapString = JSONObject.toJSONString(map);
Station station = JSONObject.parseObject(mapString, Station.class); //json字符串直接转给java对象
stations.add(station);
}
} catch (Exception e) {
System.out.println("没有找到Record, name:" + routeName);
}
}