之前写过3.x版本的neo4j使用方法,最近又要用neo4j发现版本升级了好多,我使用的是4.4.5,5.x的都差不多,但是跟以前区别挺大
引入maven包,jdk本人使用的是17
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>5.6.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.19</version>
</dependency>
</dependencies>
配置文件
server.port=9004
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=12345678
logging.level.org.springframework.data.neo4j=DEBUG
#spring.data.neo4j.database = my-database
基础类
package com.fy.entity;
import lombok.Data;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import java.io.Serializable;
/**
* @ClassName CarEntity
* @author: maliang
* @Description 汽车
* @date 2023/3/30 13:32
* @Version 1.0版本
*/
@Data
@Node("car")
public class CarEntity implements Serializable {
@Id
@GeneratedValue
private Long id;
private String carName;
private String carType;
private String color;
}
package com.fy.entity;
import lombok.Data;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import java.io.Serializable;
/**
* @ClassName NeoEntity
* @author: maliang
* @Description 通用类
* @date 2023/3/29 11:15
* @Version 1.0版本
*/
@Node("neo")
@Data
public class NeoEntity implements Serializable{
@Id
@GeneratedValue
private Long id;
private String name;
private String num;
private int age;
private String local;
}
package com.fy.entity;
import lombok.Data;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;
import java.io.Serializable;
import java.util.List;
import static org.springframework.data.neo4j.core.schema.Relationship.Direction.OUTGOING;
/**
* @ClassName Person
* @author: maliang
* @Description 人员
* @date 2023/3/30 13:28
* @Version 1.0版本
*/
@Data
@Node("person")
public class Person implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private String num;
private int age;
private String local;
/**
* 拥有的商品
*/
@Relationship("have")
private List<ProductEntity> productEntityList;
/**
* 亲戚
*/
@Relationship("kinsfolk")
private List<Person> kinsfolkShips;
/**
* 拥有的汽车
*/
@Relationship(type = "have", direction = OUTGOING)
private List<CarEntity> cars;
}
package com.fy.entity;
import lombok.Data;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import java.io.Serializable;
/**
* @ClassName ProductEntity
* @author: maliang
* @Description 商品
* @date 2023/3/30 13:29
* @Version 1.0版本
*/
@Node("product")
@Data
public class ProductEntity implements Serializable {
@Id
@GeneratedValue
private Long id;
private String productName;
private String param;
}
@Repository
public interface CarRespository extends Neo4jRepository<CarEntity, Long> {
}
@Repository
public interface NeoRepository extends Neo4jRepository<NeoEntity, Long> {
}
@Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {
@Query(value = "MATCH(n:person) WHERE id(n) in $ids RETURN n",
countQuery = "MATCH(n:person) WHERE id(n) in $ids RETURN count(*)")
Page<Person> findByIds(@Param("ids") List<Long> ids, Pageable pageable);
@Query(value = "MATCH(n:person) RETURN n",
countQuery = "MATCH(n:person) RETURN count(*)")
Page<Person> getAll(Pageable pageable);
@Query(value = "MATCH(n:person) where id(n) = $id RETURN n")
Person getById(@Param("id") Long id);
@Query(value = "MATCH(n:person)-[:kinsfolk]->(m:person) where id(n) = $id RETURN m")
List<Person> getKinsfolkById(@Param("id") Long id);
}
@Repository
public interface ProductRepository extends Neo4jRepository<ProductEntity, Long> {
@Query("MATCH(n:product) RETURN n")
List<ProductEntity> getAll();
@Query("MATCH (p:person)-[:have]->(n:product) WHERE id(p) = $id RETURN n")
List<ProductEntity> getByPersonId(@Param("id") Long id);
}
package com.fy.client;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import org.neo4j.driver.Record;
import org.neo4j.driver.*;
import org.neo4j.driver.types.Node;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName Neo4jLink
* @author: maliang
* @Description 查询数据工具类
* @date 2023/3/31 10:14
* @Version 1.0版本
*/
@Component
public class Neo4jLink implements AutoCloseable {
private final Driver driver;
public Neo4jLink(@Value("${spring.neo4j.uri}") String uri, @Value("${spring.neo4j.authentication.username}") String user, @Value("${spring.neo4j.authentication.password}") String password) {
driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
}
@Override
public void close() throws RuntimeException {
driver.close();
}
public <T> T query(final String nql, Class<T> beanClass) {
try (Session session = driver.session()) {
return session.executeWrite(tx -> {
Query query = new Query(nql);
Result result = tx.run(query);
while (result.hasNext()) {
Record next = result.next();
for (int i = 0; i < next.size(); i++) {
Node value = next.get(i).asNode();
Map<String, Object> map = value.asMap();
T t = BeanUtil.mapToBean(map, beanClass, new CopyOptions());
setId(t, value.elementId());
}
}
return null;
});
}
}
public <T> T query(final String nql, Map<String, Object> paramMap, Class<T> beanClass) {
try (Session session = driver.session()) {
return session.executeWrite(tx -> {
Query query = new Query(nql, paramMap);
Result result = tx.run(query);
while (result.hasNext()) {
Record next = result.next();
for (int i = 0; i < next.size(); i++) {
Node value = next.get(i).asNode();
Map<String, Object> map = value.asMap();
T t = BeanUtil.mapToBean(map, beanClass, new CopyOptions());
setId(t, value.elementId());
}
}
return null;
});
}
}
public <T> List<T> queryList(final String nql, Class<T> beanClass) {
try (Session session = driver.session()) {
return session.executeWrite(tx -> {
Query query = new Query(nql);
Result result = tx.run(query);
List<T> list = new ArrayList<>();
while (result.hasNext()) {
Record next = result.next();
for (int i = 0; i < next.size(); i++) {
Node value = next.get(i).asNode();
Map<String, Object> map = value.asMap();
T t = BeanUtil.mapToBean(map, beanClass, new CopyOptions());
setId(t, value.elementId());
list.add(t);
}
}
return list;
});
}
}
public <T> List<T> queryList(final String nql, Map<String, Object> paramMap, Class<T> beanClass) {
try (Session session = driver.session()) {
return session.executeWrite(tx -> {
Query query = new Query(nql, paramMap);
Result result = tx.run(query);
List<T> list = new ArrayList<>();
while (result.hasNext()) {
Record next = result.next();
for (int i = 0; i < next.size(); i++) {
Node value = next.get(i).asNode();
Map<String, Object> map = value.asMap();
T t = BeanUtil.mapToBean(map, beanClass, new CopyOptions());
setId(t, value.elementId());
list.add(t);
}
}
return list;
});
}
}
public void write(final String nql) {
try (Session session = driver.session()) {
Transaction tx = session.beginTransaction();
try {
tx.run(nql);
tx.commit();
} catch (Exception e) {
tx.rollback();
}
}
}
private <T> void setId(T t, String primaryKey) {
Class<?> aClass = t.getClass();
Method[] methods = aClass.getMethods();
for (Method method : methods) {
if (method.getName().contains("setId")) {
try {
method.invoke(t, Long.parseLong(primaryKey));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
break;
}
}
}
}
package com.fy.controller;
import com.fy.dao.CarRespository;
import com.fy.entity.CarEntity;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @ClassName CarController
* @author: maliang
* @Description TODO
* @date 2023/3/30 13:50
* @Version 1.0版本
*/
@RestController
@RequestMapping("car")
public class CarController {
@Resource
private CarRespository respository;
@PostMapping
public String add(@RequestBody List<CarEntity> carEntityList) {
respository.saveAll(carEntityList);
return "success";
}
}
package com.fy.controller;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.fy.client.Neo4jLink;
import com.fy.dao.CarRepository;
import com.fy.dao.PersonRepository;
import com.fy.dao.ProductRepository;
import com.fy.entity.CarEntity;
import com.fy.entity.Person;
import com.fy.entity.ProductEntity;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @ClassName PersonController
* @author: maliang
* @Description TODO
* @date 2023/3/30 13:50
* @Version 1.0版本
*/
@RestController
@RequestMapping("person")
public class PersonController {
@Resource
private PersonRepository repository;
@Resource
private ProductRepository productRepository;
@Resource
private CarRepository carRespository;
@Resource
private Neo4jLink neo4jLink;
@PostMapping
public String add(@RequestBody List<Person> personList) {
repository.saveAll(personList);
return "success";
}
@PostMapping("addProduct")
public String saveHave(Long personId, Long productId) {
Optional<Person> person = repository.findById(personId);
person.ifPresent(e -> {
Optional<ProductEntity> product = productRepository.findById(productId);
product.ifPresent(p -> {
e.getProductEntityList().add(p);
repository.save(e);
});
});
return "success";
}
@DeleteMapping("removeProduct")
public String removeProduct(Long personId, Long productId) {
String dele = "MATCH (p:person)-[h:have]->(p1:product) where id(p) = $personId and id(p1) = $productId detach delete h";
HashMap<String, Object> objectObjectHashMap = MapUtil.newHashMap();
objectObjectHashMap.put("personId", personId);
objectObjectHashMap.put("productId", productId);
neo4jLink.write(dele, objectObjectHashMap);
return "success";
}
@PostMapping("addCar")
public String addCar(Long personId, Long carId) {
Optional<Person> person = repository.findById(personId);
person.ifPresent(e -> {
Optional<CarEntity> car = carRespository.findById(carId);
car.ifPresent(c -> {
e.getCars().add(c);
repository.save(e);
});
});
return "success";
}
@DeleteMapping("remoteCar")
public String remoteCar(Long personId, Long carId) {
Optional<Person> person = repository.findById(personId);
person.ifPresent(e -> {
List<CarEntity> cars = e.getCars();
List<CarEntity> collect = cars.stream().filter(c -> !c.getId().equals(carId)).collect(Collectors.toList());
e.setCars(collect);
repository.save(e);
});
return "success";
}
@PostMapping("addKinsfolk")
public String addKinsfolk(Long personId, Long kinsfolkId) {
Optional<Person> person = repository.findById(personId);
person.ifPresent(e -> {
Optional<Person> kinsfolk = repository.findById(kinsfolkId);
kinsfolk.ifPresent(c -> {
e.getKinsfolkShips().add(c);
repository.save(e);
});
});
return "success";
}
@GetMapping("findAll")
public Page<Person> findAll(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) {
Pageable pageable = PageRequest.of(page, size);
Page<Person> all = repository.getAll(pageable);
for (Person person : all) {
Long id = person.getId();
person.setProductEntityList(productRepository.getByPersonId(id));
person.setCars(carRespository.getByPersonId(id));
person.setKinsfolkShips(repository.getKinsfolkById(id));
}
return all;
}
@GetMapping("findById")
public Person findById(Long id) {
return repository.getById(id);
}
@GetMapping("findByIds")
public Page<Person> findByIds(String ids, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) {
List<Long> collect = StrUtil.split(ids, ',').stream().map(Long::parseLong).collect(Collectors.toList());
Pageable pageable = PageRequest.of(page, size);
Page<Person> all = repository.findByIds(collect, pageable);
for (Person person : all) {
Long id = person.getId();
Map<String, Object> idMap = MapUtil.of("id", id);
String cql = "MATCH (p:person)-[:have]->(n:product) WHERE p.id = $id RETURN n";
List<ProductEntity> productEntity = neo4jLink.queryList(cql, idMap, ProductEntity.class);
String cql2 = "MATCH (p:person)-[:have]->(n:car) WHERE id(p) = $id RETURN n";
List<CarEntity> carEntityList = neo4jLink.queryList(cql2, idMap, CarEntity.class);
String cql3 = "MATCH(n:person)-[:kinsfolk]->(m:person) where id(n) = $id RETURN m";
List<Person> personList = neo4jLink.queryList(cql3, idMap, Person.class);
person.setCars(carEntityList);
person.setKinsfolkShips(personList);
person.setProductEntityList(productEntity);
}
return all;
}
}
package com.fy.controller;
import com.fy.dao.ProductRepository;
import com.fy.entity.ProductEntity;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName ProductController
* @author: maliang
* @Description TODO
* @date 2023/3/30 13:50
* @Version 1.0版本
*/
@RestController
@RequestMapping("product")
public class ProductController {
@Resource
private ProductRepository repository;
@PostMapping
public String add(@RequestBody List<ProductEntity> productEntityList) {
repository.saveAll(productEntityList);
return "success";
}
@GetMapping("findAll")
public List<ProductEntity> findAll() {
return repository.getAll();
}
}
增加人员
127.0.0.1:9004/person
[
{
"name": "包拯",
"num": "001",
"age": "25",
"local": "保定"
},
{
"name": "狄仁杰",
"num": "002",
"age": "38",
"local": "凤阳"
}
]
增加商品
127.0.0.1:9004/product
[
{
"productName": "西门子冰箱",
"param": "size:10,long:200"
},
{
"productName": "海尔冰箱",
"param": "size:10,long:200"
},
{
"productName": "小米手机",
"param": "size:10,long:200"
},
{
"productName": "跑步机",
"param": "size:10,long:200"
}
]
127.0.0.1:9004/person
[
{
"name": "包拯",
"num": "001",
"age": "25",
"local": "保定"
},
{
"name": "狄仁杰",
"num": "002",
"age": "38",
"local": "凤阳"
},
{
"name": "李昌钰",
"num": "003",
"age": "56",
"local": "江苏"
}
]
127.0.0.1:9004/product
[
{
"productName": "西门子冰箱",
"param": "size:10,long:200"
},
{
"productName": "海尔冰箱",
"param": "size:10,long:200"
},
{
"productName": "小米手机",
"param": "size:10,long:200"
},
{
"productName": "跑步机",
"param": "size:10,long:200"
}
]
127.0.0.1:9004/person/addProduct?personId=2&productId=6
127.0.0.1:9004/person/saveKinsfolk?personId=1&kinsfolkId=0
127.0.0.1:9004/car
[
{
"carName": "宝马",
"carType": "宝马X5",
"color": "红色"
},
{
"carName": "奥迪",
"carType": "奥迪a6",
"color": "蓝色"
},
{
"carName": "宝马",
"carType": "宝马X5",
"color": "红色"
},
{
"carName": "奔驰",
"carType": "奔驰350",
"color": "黑色"
},
{
"carName": "宝马",
"carType": "宝马X5",
"color": "红色"
},
{
"carName": "五菱之光",
"carType": "五菱mini",
"color": "蓝色"
}
]
127.0.0.1:9004/person/addCar?personId=1&carId=6
127.0.0.1:9004/person/findAll
127.0.0.1:9004/person/findById?id=0
127.0.0.1:9004/person/findByIds?ids=0,1,2