Neo4j整合Java

  • Neo4j安装及简单使用
    • Neo4j和图数据库简介
    • Neo4j安装
    • 配置环境变量
    • 修改Neo4j配置文件
    • Neo4j启动和停止
    • 切换数据库
    • Neo4j的CQL语句
    • 导入csv文件
  • Neo4j - Java简介
    • Neo4j Java架构
    • Neo4j - 原生Java API
  • Neo4j与Spring数据
    • Spring DATA Neo4J - 架构
    • Spring Data Neo4j - API

Neo4j安装及简单使用

Neo4j和图数据库简介

neo4j是基于Java语言编写图形数据库。图是一组节点和连接这些节点的关系。图形数据库也被称为图形数据库管理系统或GDBMS。

Neo4j的是一种流行的图形数据库。 其他的图形数据库是Oracle NoSQL数据库,OrientDB,HypherGraphDB,GraphBase,InfiniteGraph,AllegroGraph。

Neo4j图形数据库的主要构建块是:

  • 节点:是图表的基本单位。 它包含具有键值对的属性

  • 关系:连接两个节点,具有方向:单向和双向。每个关系包含“开始节点”或“从节点”和“到节点”或“结束节点”。关系也可以包含属性作为键值对。

  • 属性:是用于描述图节点和关系的键值对。Key =值,其中Key是一个字符串,值可以通过使用任何Neo4j数据类型来表示

  • 标签:将节点分组为集合。将一个公共名称与一组节点或关系相关联。 节点或关系可以包含一个或多个标签。 我们可以为现有节点或关系创建新标签。我们可以从现有节点或关系中删除现有标签。

  • 数据浏览器:用于执行CQL命令并查看输出输出。

Neo4j安装

从官网下载最新版 Neo4j 社区版(Community),注意使用Neo4j需要安装java环境,我这里使用3.5.4版本,对应java1.8可以使用。
Neo4j-3.5.4 社区window版和java1.8,网盘资源获取,提取码me9t
下载后解压压缩包文件夹内容如下:

Neo4j应用程序有如下主要的目录结构:

  • bin目录:用于存储Neo4j的可执行程序;

  • conf目录:用于控制Neo4j启动的配置文件;

  • data目录:用于存储核心数据库文件;

  • plugins目录:用于存储Neo4j的插件;

配置环境变量

在计算机-属性中创建系统环境变量NEO4J_HOME,并把主目录(E:\Program Files (x86)\neo4j-community-3.4.0)设置为变量值。

NEO4J_HOME=E:\Program Files (x86)\neo4j-community-3.4.0

如果没有安装过java的环境,也需要配置java环境变量。

JAVA_HOME=E:\Program Files (x86)\jdk1.8.0_181

再在path中添加Neo4j和java安装目录下的bin文件夹。

%NEO4J_HOME%\bin。
%JAVA_HOME%\bin。

修改Neo4j配置文件

修改neo4j-community-3.5.25\conf下的neo4j.conf配置文件

去掉第54、71、75、79前面的#

# 允许远程访问
dbms.connectors.default_listen_address=0.0.0.0
# 开启bolt服务,默认端口7687
dbms.connector.bolt.listen_address=0.0.0.0:7687
# 开启http服务,默认端口7474
dbms.connector.http.listen_address=0.0.0.0:7474
# 开启https服务,默认端口7473
dbms.connector.https.listen_address=0.0.0.0:7473

Neo4j启动和停止

方法一:通过控制台启动Neo4j程序(win10建议使用)

CMD管理员身份运行(一定要以管理员身份进入CMD,否则会出现警告。警告: This command does not appear to be running with administrative rights. Some commands may fail e.g. Start/Stop)
输入:

neo4j.bat console

方法二:把Neo4j安装为服务(linux建议使用)
安装和卸载服务:

neo4j install-service
neo4j uninstall-service

启动服务,停止服务,重启服务和查询服务的状态:

neo4j start
neo4j stop
neo4j restart
neo4j status

在浏览器中打开http://localhost:7474 默认跳转到 http://localhost:7474/browser,出现Neo4j界面,则安装成功。初始密码:neo4j ,进去之后需要修改密码。
在这里插入图片描述

切换数据库

每次启动neo4j,它只能读取一个数据库。默认情况下的Graph.db数据库。
方法一:修改配置文件(win10)
使用Neo3.x创建新数据库而不删除现有数据库,所以只需在$NEO4J_HOME\conf的目录编辑neo4j.conf。搜寻dbms.active_database=,其默认值应为graph.db。用其他名称替换它,然后再次启动neo4j。现在,将在该目录名下创建一个新数据库。若要切换回以前的db,请重复这些步骤,只需将新值替换为graph.db在配置文件中。
注意:如果在neo4j启动的时候修改了配置文件,则需要重新启动一次,浏览器页面才会更新。

方法二:建立软连接(linux)
首次修改:

// 请将$NEO4j_HOME改为你的neo4j的安装路径
cd $NEO4j_HOME/data/databases/
// 保存原来数据库
mv graph.db graph1.db
//建立指向新数据库的软件接
ln -s graph2.db graph.db//重启neo4j
cd $NEO4j_HOME/bin
./neo4j restart

再次修改
倘若我想访问graph3.db,就很简单了

//建立指向新数据库的软件接
ln -s graph3.db graph.db//重启neo4j
cd $NEO4j_HOME/bin
./neo4j restart

Neo4j的CQL语句

CQL代表Cypher查询语言。 像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言。
运行Neo4j之后,在软件窗口可以选择数据库创建位置,之后Neo4j就自动为我们创建好了数据库。

Neo4j CQL

  • 它是Neo4j图形数据库的查询语言。
  • 它是一种声明性模式匹配语言
  • 它遵循SQL语法。
  • 它的语法是非常简单且人性化、可读的格式。

我们可以通过Neo4j的图形化界面进行输入,在数据浏览器中的美元提示符下键入命令进行操控数据库。

1、创建节点

CREATE (dept:Dept { deptno:10,dname:"Accounting",location:"Hyderabad" })

2、查询节点

MATCH (dept: Dept)
RETURN dept.deptno,dept.dname

3、使用现有节点创建关系

MATCH (cust:Customer),(cc:CreditCard)
CREATE (cust)-[r:DO_SHOPPING_WITH{shopdate:"12/12/2014",price:55000}]->(cc)
RETURN r

4、使用新节点创建关系

CREATE (video1:YoutubeVideo1{title:"Action Movie1",updated_by:"Abc",uploaded_date:"10/10/2010"})
-[movie:ACTION_MOVIES{rating:1}]->
(video2:YoutubeVideo2{title:"Action Movie2",updated_by:"Xyz",uploaded_date:"12/12/2012"})

5、查询关系

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie

6、根据条件查询

MATCH (emp:Employee)
WHERE emp.name = 'Abc'
RETURN emp

7、删除节点(只能删除没有关系的节点)

MATCH (e: Employee) DELETE e

8、删除关系(可以连着节点一起删除)

MATCH (cc: CreditCard)-[rel]-(c:Customer)
DELETE cc,c,rel

9、删除节点或关系的属性和标签

MATCH (book { id:122 })
REMOVE book.price
RETURN book

10、修改添加节点或关系属性

MATCH (book:Book)
SET book.title = 'superstar'
RETURN book

11、排序

MATCH (emp:Employee)
RETURN emp.empid,emp.name,emp.salary,emp.deptno
ORDER BY emp.name

12、联合查询(必须两个查询命令属性相同)

MATCH (cc:CreditCard) RETURN cc.id,cc.number
UNION
MATCH (dc:DebitCard) RETURN dc.id,dc.number

13、过滤或限制查询返回的行数

MATCH (emp:Employee)
RETURN emp
LIMIT 2

14、跳过多少行返回数据

MATCH (emp:Employee)
RETURN emp
SKIP 2

15、不存在进行创建,存在不创建

MERGE (gp2:GoogleProfile2{ Id: 201402,Name:"Nokia"})

16、null值查询(新建时不输入任何属性也会出现null值)

MATCH (e:Employee)
WHERE e.id IS NULL
RETURN e.id,e.name,e.sal,e.deptno

17、批量查询in

MATCH (e:Employee)
WHERE e.id IN [123,124]
RETURN e.id,e.name,e.sal,e.deptno

18、字符串函数(大写:UPPER,小写:LOWER,截取:SUBSTRING,替换:REPLACE)

MATCH (e:Employee)
RETURN e.id,UPPER(e.name),e.sal,e.deptno

19、聚合函数(总行数:COUNT,最大值:MAX,最小值:MIN,求和:SUM,平均值:AVG)

MATCH (e:Employee) RETURN COUNT(*)

20、关系函数(关系启点:STARTNODE,关系终点:ENDNODE,关系id:ID,关系类型:TYPE)

MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN STARTNODE(movie)

21、创建普通索引

CREATE INDEX ON :Customer (name)

22、创建唯一索引

CREATE CONSTRAINT ON (cc:CreditCard)
ASSERT cc.number IS UNIQUE

23、删除普通索引

DROP INDEX ON :Customer (name)

24、删除唯一索引

DROP CONSTRAINT ON (cc:CreditCard)
ASSERT cc.number IS UNIQUE

25、修改密码

:server change-password

26、case表达式(选择语句)

MATCH(n)
RETURN
CASE n.eyesWHEN 'blue' THEN 1WHEN 'brown' THEN 2ELSE 3
END
AS result

27、深度匹配 (路径长度匹配)

(a)-[*2..4]->(b)  // 匹配路径长度为 2 到4 之间 的路径
(a)-[*2..]->(b) // 匹配路径长度大于2的路径
(a)-[*..2]->(b) // 匹配路径长度小于2的路径
(a)-[*]->(b) // 匹配任意长度的路径
match(n) -[r:TYPE*minHops..maxHops]->(m) return r

28、最短路径匹配 shortestPath() 函数

match (martin:Person {name:"name1"}),(oliver:Perspn{name:"name2"}),p = shortestPath((martin)-[*..15]-(oliver))
return p

29、所有最短路径 allShortestPaths()

match (martin:Person {name:"name1"}),(oliver:Perspn{name:"name2"}),p= allShortestPaths((martin)-[*]-(oliver))
return p

导入csv文件

首先从MySQL数据库导出csv文件,复制到import文件夹E:\Program Files (x86)\neo4j-community-3.4.0\import里,然后执行下列语句:

//导入节点 电影类型  == 注意类型转换
LOAD CSV WITH HEADERS  FROM "file:///genre.csv" AS line
MERGE (p:Genre{gid:toInteger(line.gid),name:line.gname})//导入节点 演员信息
LOAD CSV WITH HEADERS FROM 'file:///person.csv' AS line
MERGE (p:Person { pid:toInteger(line.pid),birth:line.birth,
death:line.death,name:line.name,
biography:line.biography,
birthplace:line.birthplace})// 导入节点 电影信息
LOAD CSV WITH HEADERS  FROM "file:///movie.csv" AS line
MERGE (p:Movie{mid:toInteger(line.mid),title:line.title,introduction:line.introduction,
rating:toFloat(line.rating),releasedate:line.releasedate})// 导入关系 actedin  电影是谁参演的 1对多
LOAD CSV WITH HEADERS FROM "file:///person_to_movie.csv" AS line
match (from:Person{pid:toInteger(line.pid)}),(to:Movie{mid:toInteger(line.mid)})
merge (from)-[r:actedin{pid:toInteger(line.pid),mid:toInteger(line.mid)}]->(to)//导入关系  电影是什么类型 == 1对多
LOAD CSV WITH HEADERS FROM "file:///movie_to_genre.csv" AS line
match (from:Movie{mid:toInteger(line.mid)}),(to:Genre{gid:toInteger(line.gid)})
merge (from)-[r:is{mid:toInteger(line.mid),gid:toInteger(line.gid)}]->(to)

Neo4j - Java简介

Neo4j提供JAVA API以编程方式执行所有数据库操作。

它支持两种类型的API:

  • Neo4j的原生的Java API
  • Neo4j Cypher Java API

Neo4j原生Java API是一种低级别的纯JAVA API,用于执行数据库操作。 Neo4j Cypher Java API是简单而强大的JAVA API,用于执行所有CQL命令以执行数据库操作。

Neo4j Java架构

下图显示了Neo4j JAVA API应用程序的体系结构

客户端程序使用Neo4j Java API之一来在Neo4j数据库上交互和执行数据库操作。

Neo4j - 原生Java API

使用idea创建SpringBoot的项目。

1、引入依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.chengkun</groupId><artifactId>springboot-neo4j</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-neo4j</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><!-- 集成springboot web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 集成springboot test组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 集成lombok 框架 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><!-- 服务器开发需要的jar包 --><groupId>org.neo4j.driver</groupId><artifactId>neo4j-java-driver</artifactId><version>1.5.0</version></dependency><dependency><!-- 嵌入式开发需要的jar包 --><groupId>org.neo4j</groupId><artifactId>neo4j</artifactId><version>3.5.4</version></dependency><!-- 文件上传组件 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>[1.3.3,)</version></dependency><!--阿里巴巴 fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.56</version></dependency><!-- 引入Spring封装的jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- 引入mysql数据库连接驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- 引入 Druid 数据源依赖:https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>org.xmlunit</groupId><artifactId>xmlunit-core</artifactId></dependency><!--swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version><exclusions><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><!-- google java lib --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>[24.1.1,)</version></dependency></dependencies><profiles><profile><id>base</id><activation><activeByDefault>true</activeByDefault></activation><properties><package.environment>base</package.environment></properties></profile><profile><id>dev</id><activation><activeByDefault>true</activeByDefault></activation><properties><package.environment>dev</package.environment></properties></profile><profile><id>test</id><properties><package.environment>test</package.environment></properties></profile></profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><mainClass>com.chengkun.neo4j.SpringbootNeo4jApplication</mainClass></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}\lib</outputDirectory></configuration></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target><encoding>utf8</encoding></configuration></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/**</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.yml</include><include>**/*.xml</include><include>**/*.tld</include><include>**/*.doc</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory><includes><!--不对excel模板过滤--><include>**/*.xlsx</include><include>**/*.xls</include></includes><excludes><exclude>**/*.properties</exclude><exclude>**/*.yml</exclude><exclude>**/*.xml</exclude><exclude>**/*.tld</exclude><exclude>**/*.doc</exclude></excludes><filtering>false</filtering></resource></resources></build></project>

2、配置文件application.yml

server:port: 8080
spring:datasource:username: rootpassword: rooturl: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: true#配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙filters: stat,wall,lombokmax-pool-prepared-statement-per-connection-size: 20use-global-data-source-stat: trueconnection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500#easypoi配置main:allow-bean-definition-overriding: true
#mybatis配置
mybatis:configuration:map-underscore-to-camel-case: truemapper-locations: classpath*:com/chengkun/**/*Mapper.xmltype-aliases-package: com.chengkun.entity
#日志
logging:config: classpath:logback-spring.xml
#########其他配置##########
##主要用于加载接口程序需要的配置信息到内存中使用 product为加载生产配置 可配置test,product,dev
environment:  dev
# 开启swagger
swagger:enabled:  true
# neo4j数据库地址
neo4j:db_neo4j: D:\neo4j-community-3.5.4-windows\data\databases\graph.db

3、创建节点标签枚举:

package com.chengkun.neo4j.entity;import org.neo4j.graphdb.Label;/*** 自定义节点标签** @author chengkun* @version v1.0* @create 2021/3/29 14:59**/
public enum MyLabel implements Label {JAVA, SCALA, SQL, NEO4J;
}

4、创建关系类型枚举

package com.chengkun.neo4j.entity;import org.neo4j.graphdb.RelationshipType;/*** 自定义关系类型** @author chengkun* @version v1.0* @create 2021/3/29 15:00**/
public enum MyRelationshipType implements RelationshipType {JVM_LANGIAGES, NON_JVM_LANGIAGES;
}

5、noe4j参数实体类

package com.chengkun.neo4j.entity;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** @author chengkun* @version v1.0* @create 2021/3/29 19:09**/
@Data
@ApiModel(description = "neo4j参数实体类")
public class Code {@ApiModelProperty(value = "id")private String id;@ApiModelProperty(value = "节点")private String node;@ApiModelProperty(value = "关系")private String relation;@ApiModelProperty(value = "属性")private String property;@ApiModelProperty(value = "节点标签")private String label;@ApiModelProperty(value = "边起点id")private String nodeFromId;@ApiModelProperty(value = "边起点标签")private String nodeFromLabel;@ApiModelProperty(value = "边终点id")private String nodeToId;@ApiModelProperty(value = "边终点标签")private String nodeToLabel;@ApiModelProperty(value = "条件语句")private String where;@ApiModelProperty(value = "修改语句")private String update;@ApiModelProperty(value = "返回结果")private String result;}

6、初始化neo4j数据库bean

package com.chengkun.neo4j.config;import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.File;/*** @author chengkun* @version v1.0* @create 2021/3/29 15:16**/
@Configuration
public class Neo4jConfig {@Value(value = "${neo4j.db_neo4j}")private String dbNoe4j;@Value(value = "${neo4j.neo4j_url}")private String noe4jUrl;@Value(value = "${neo4j.username}")private String username;@Value(value = "${neo4j.password}")private String password;//使用内嵌式数据库@Beanpublic GraphDatabaseService getGraphDatabaseService() {GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();GraphDatabaseService db = dbFactory.newEmbeddedDatabase(new File(dbNoe4j));return db;}//使用服务器式数据库@Beanpublic Driver getDrive() {return GraphDatabase.driver(noe4jUrl, AuthTokens.basic(username, password));}
}

7、创建neo4j操作Controller

package com.chengkun.neo4j.controller;import com.chengkun.neo4j.entity.Code;
import com.chengkun.neo4j.entity.MyLabel;
import com.chengkun.neo4j.entity.MyRelationshipType;
import io.swagger.annotations.*;
import lombok.extern.log4j.Log4j2;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.graphdb.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.ArrayList;
import java.util.List;import static org.neo4j.driver.v1.Values.parameters;/*** @author chengkun* @version v1.0* @create 2021/3/29 15:32**/
@Api(tags = "neo4j增删改查")
@RestController
@Log4j2
@RequestMapping("/neo4j")
public class Neo4jController {@Autowiredprivate GraphDatabaseService graphDB; //使用内嵌式数据库@Autowiredprivate Driver driver; //使用服务器式数据库(推荐)@ApiOperation(value = "创建数据(使用内嵌式数据库)")@GetMapping(value = "/create", produces = "application/text;charset=UTF-8")public String create() {Transaction tx = graphDB.beginTx();try {Node java = graphDB.createNode(MyLabel.JAVA);java.setProperty("id", 1);java.setProperty("name", "java");Node c = graphDB.createNode(MyLabel.C);c.setProperty("id", 2);c.setProperty("name", "c");Node python = graphDB.createNode(MyLabel.PYTHON);python.setProperty("id", 3);python.setProperty("name", "python");Node scala = graphDB.createNode(MyLabel.SCALA);scala.setProperty("id", 4);scala.setProperty("name", "scala");Node mysql = graphDB.createNode(MyLabel.MYSQL);mysql.setProperty("id", 5);mysql.setProperty("name", "mysql");Node neo4j = graphDB.createNode(MyLabel.NEO4J);neo4j.setProperty("id", 6);neo4j.setProperty("name", "neo4j");Relationship javaMysql = java.createRelationshipTo(mysql, MyRelationshipType.JVM_LANGIAGES);javaMysql.setProperty("id", 1);javaMysql.setProperty("name", "java连接mysql");Relationship cMysql = c.createRelationshipTo(mysql, MyRelationshipType.NON_JVM_LANGIAGES);cMysql.setProperty("id", 2);cMysql.setProperty("name", "c连接mysql");Relationship pythonMysql = python.createRelationshipTo(mysql, MyRelationshipType.NON_JVM_LANGIAGES);pythonMysql.setProperty("id", 3);pythonMysql.setProperty("name", "python连接mysql");Relationship javaNeo4j = java.createRelationshipTo(neo4j, MyRelationshipType.JVM_LANGIAGES);javaNeo4j.setProperty("id", 4);javaNeo4j.setProperty("name", "java连接neo4j");Relationship scalaNeo4j = scala.createRelationshipTo(neo4j, MyRelationshipType.NON_JVM_LANGIAGES);scalaNeo4j.setProperty("id", 5);scalaNeo4j.setProperty("name", "scala连接neo4j");tx.success();} finally {tx.close();}return "创建成功";}@ApiOperation(value = "根据id查询节点(使用内嵌式数据库)")@GetMapping(value = "/getNode", produces = "application/text;charset=UTF-8")public String getNode(@RequestParam("id") Integer id) {Transaction tx = graphDB.beginTx();Node node;try {node = graphDB.findNode(MyLabel.JAVA, "id", id); //这里类型必须与保存的类型一致System.out.println(node.getId());System.out.println(node.getLabels());System.out.println(node.getAllProperties());tx.success();} finally {tx.close();}return "查询成功";}@ApiOperation(value = "查看所有(使用内嵌式数据库)")@GetMapping(value = "/findAll", produces = "application/text;charset=UTF-8")public String findAll() {Transaction tx = graphDB.beginTx();try {for (Node node : graphDB.getAllNodes()) {System.out.println(node.getId());System.out.println(node.getLabels());System.out.println(node.getAllProperties());for (Relationship relationship : node.getRelationships()) {System.out.println(relationship.getId());System.out.println(relationship.getType());System.out.println(relationship.getAllProperties());}}tx.success();} finally {tx.close();}return "查询成功";}@ApiOperation(value = "删除节点以及关联的边(使用内嵌式数据库)")@GetMapping(value = "/deleteNode", produces = "application/text;charset=UTF-8")public String deleteNode(@RequestParam("id") Integer id) {Transaction tx = graphDB.beginTx();try {Node scala = graphDB.findNode(MyLabel.SCALA, "id", id);Iterable<Relationship> relationships = scala.getRelationships(MyRelationshipType.NON_JVM_LANGIAGES);//删除边for (Relationship relationship : relationships) {relationship.delete();}//删除节点scala.delete();System.out.println("delete ok");tx.success();} finally {tx.close();}return "删除成功";}@ApiOperation(value = "修改节点以及关联的边(使用内嵌式数据库)")@GetMapping(value = "/updateNode", produces = "application/text;charset=UTF-8")public String updateNode(@RequestParam("id") Integer id) {Transaction tx = graphDB.beginTx();try {Node c = graphDB.findNode(MyLabel.C, "id", id);Iterable<Relationship> relationships = c.getRelationships(Direction.OUTGOING, MyRelationshipType.NON_JVM_LANGIAGES);//修改边for (Relationship relationship : relationships) {relationship.setProperty("type", "c->out->other");}//修改节点c.setProperty("type", "c语言");System.out.println("update ok");tx.success();} finally {tx.close();}return "修改成功";}@ApiOperation(value = "删除所有(使用内嵌式数据库)")@GetMapping(value = "/deleteAll", produces = "application/text;charset=UTF-8")public String deleteAll() {Transaction tx = graphDB.beginTx();try {for (Node node : graphDB.getAllNodes()) {for (Relationship relationship : node.getRelationships()) {relationship.delete();}node.delete();}tx.success();} finally {tx.close();}return "删除所有";}@ApiOperation(value = "创建数据(使用服务器式数据库)")@GetMapping(value = "create1", produces = "application/text;charset=UTF-8")public String create1() {try {Session session = driver.session();session.run("CREATE (a:Person {id: {id}, name: {name}, title: {title}})",parameters("id", 1, "name", "Arthur001", "title", "King001"));StatementResult result = session.run("MATCH (a:Person) WHERE a.name = {name} RETURN a.id as id,a.name AS name, a.title AS title",parameters("name", "Arthur001"));while (result.hasNext()) {Record record = result.next();System.out.println(record.get("id").asInt() + " " + record.get("title").asString() + " " + record.get("name").asString());}session.close();System.out.println("使用服务器式数据库创建数据成功");} catch (Exception e) {log.info("使用服务器式数据库创建数据失败");return "使用服务器式数据库创建数据失败";}return "使用服务器式数据库创建数据成功";}@ApiOperation(value = "修改数据(使用服务器式数据库)")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "修改节点id"),@ApiImplicitParam(name = "name", value = "修改后的名称"),})@GetMapping(value = "update", produces = "application/json;charset=UTF-8")public void update(@RequestParam("id") Integer id, @RequestParam("name") String name) {try {Session session = driver.session();StatementResult result = session.run("MATCH (a:Person) WHERE a.id={id}  SET a.name = {name} RETURN a.id as id,a.name AS name, a.title AS title",parameters("id", id, "name", name));while (result.hasNext()) {Record record = result.next();System.out.println(record.get("id").asInt() + " " + record.get("title").asString() + " " + record.get("name").asString());}session.close();System.out.println("使用服务器式数据库修改数据成功");} catch (Exception e) {log.info("使用服务器式数据库修改数据失败");}}@ApiOperation(value = "添加关系(使用服务器式数据库)")@PostMapping(value = "relate", produces = "application/json;charset=UTF-8")public void relate(@RequestBody Code code) {try {Session session = driver.session();session.run("MATCH (a:" + code.getNodeFromLabel() + "), (b:" + code.getNodeToLabel() + ") " +"WHERE a.id = " + code.getNodeFromId() + " AND b.id = " + code.getNodeToId()+ " CREATE (a)-[:" + code.getRelation() + "]->(b)");session.close();System.out.println("使用服务器式数据库添加边成功");} catch (Exception e) {log.info("使用服务器式数据库添加边失败");}}@ApiOperation(value = "删除数据(使用服务器式数据库)")@GetMapping(value = "delete", produces = "application/text;charset=UTF-8")public String delete(@RequestParam("id") Integer id) {try {Session session = driver.session();session.run("match (n:Person) where n.id = {id} delete n",parameters("id", id));session.close();System.out.println("使用服务器式数据库删除数据成功");} catch (Exception e) {log.info("使用服务器式数据库删除数据失败");return "使用服务器式数据库删除数据失败";}return "使用服务器式数据库删除数据成功";}@ApiOperation(value = "删除关系(使用服务器式数据库)")@PostMapping(value = "deleteRelate", produces = "application/json;charset=UTF-8")public void deleteRelate(@RequestBody Code code) {try {Session session = driver.session();//不知道为什么执行报错
//            session.run("MATCH (a:{NodeFromLabel})-[r:{relation}]->(b:{nodeToLabel}) WHERE a.id={nodeFromId} and b.id={nodeToId} DELETE r",
//                    parameters("NodeFromLabel", code.getNodeFromLabel(), "relation", code.getRelation(), "nodeToLabel", code.getNodeToLabel(), "nodeFromId", code.getNodeFromId(), "nodeToId", code.getNodeToId()));session.run("MATCH (a:" + code.getNodeFromLabel() + ")-[r:" + code.getRelation() + "]->(b:" + code.getNodeToLabel() + ") WHERE a.id = " + code.getNodeFromId() + " and b.id = " + code.getNodeToId() + " DELETE r");session.close();System.out.println("使用服务器式数据库删除数据成功");} catch (Exception e) {log.info("使用服务器式数据库删除数据失败");}}@ApiOperation(value = "查询数据(使用服务器式数据库)")@GetMapping(value = "search", produces = "application/json;charset=UTF-8")public List<String> search() {List<String> resultList = new ArrayList<>();try {Session session = driver.session();StatementResult result = session.run("match (n) return n.id as id,n.name as name");while (result.hasNext()) {Record record = result.next();resultList.add(record.get("id").toString() + " " + record.get("name").toString());}session.close();System.out.println("使用服务器式数据库查询数据成功");} catch (Exception e) {log.info("使用服务器式数据库查询数据失败");}return resultList;}}

注意:
1、使用内嵌式数据库,neo4j界面启动时会锁住整个数据库,这时候java就无法连接这个据库
2、使用服务器形式数据库,可以跟界面进行联调,它比嵌入式配置更安全,推荐使用这种

Neo4j与Spring数据

Spring DATA Neo4J - 架构

下图显示了Spring DATA Neo4j模块的体系结构

Spring DATA Neo4j存储库
它提供了不同的API来支持不同的场景

  • Neo4jRepository
  • CrudRepository
  • PaginationAndSortingRepository

这些是Java类。 每个具有执行Neo4j数据库操作的特定目的,继承关系是:Neo4jRepository->PaginationAndSortingRepository->CrudRepository

S.No. Spring 数据 Neo4j 类 用法
1 Neo4jRepository 它用于执行Basic Neo4j DB操作。
2 CrudRepository 它用于使用Cypher查询语言(CQL)执行Neo4j CRUD操作。
3 PaginationAndSortingRepository 它用于执行Neo4j CQL查询结果的分页和排序。。

Spring Data Neo4j - API

1、添加Spring Data Neo4j相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>

2、application.yml添加Neo4j环境配置

spring:neo4j:uri: bolt://localhost:7687authentication:username: neo4jpassword: neo4j

3、Neo4j中要定义节点,使用Spring Data Neo4j的注解@NodeEntity,标记该类为节点,节点名称为 Student

package com.chengkun.neo4j.entity;import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.neo4j.ogm.annotation.*;import java.util.ArrayList;
import java.util.List;/*** @author chengkun* @version v1.0* @create 2021/3/30 21:46**/
@Data
@NodeEntity("Student")
public class Student{/*** neo4j 生成的id*/@Id@GeneratedValueprivate Long id;/*** 属性,name*/@Property("name")private String name;/*** 属性,age*/@Property("age")private Integer age;/*** 关系,定义为友谊 指向别人*/@JsonIgnore // 禁止json序列化无限遍历@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.OUTGOING)private List<FriendshipRelation> friendshipRelationOutList;/*** 关系,定义为友谊 指向自己*/@JsonIgnore@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.INCOMING)private List<FriendshipRelation> friendshipRelationInList;/*** 添加友谊的关系** @param friendshipRelation*/public void addOutRelation(FriendshipRelation friendshipRelation) {if (this.friendshipRelationOutList == null) {this.friendshipRelationOutList = new ArrayList<>();}this.friendshipRelationOutList.add(friendshipRelation);}/*** 添加友谊的关系** @param friendshipRelation*/public void addInRelation(FriendshipRelation friendshipRelation) {if (this.friendshipRelationInList == null) {this.friendshipRelationInList = new ArrayList<>();}this.friendshipRelationInList.add(friendshipRelation);}}

4、Neo4j也要定义关系,使用Spring Data Neo4j的注解@RelationshipEntity,标记其为关系,关系名为 FRIENDSHIP_RELATION,在里面定义StartNode和EndNode

package com.chengkun.neo4j.entity;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import org.neo4j.ogm.annotation.*;/*** 关系不能有toString方法** @author chengkun* @version v1.0* @create 2021/3/30 22:01**/
@Getter
@Setter
@RelationshipEntity(type = "FRIENDSHIP_RELATION")
public class FriendshipRelation {@Id@GeneratedValueprivate Long id;@Property("name")private String name;@StartNodeprivate Student from;@EndNodeprivate Student to;}

注意:
JSON序列化注意事项:这里的关系里面有节点,节点里面有关系,造成循环依赖,在序列化中会造成栈溢出,就需要使用@JsonIgnoreProperties或@JsonIgnore进行序列化属性忽略

  • @JsonIgnore:添加到字段上是直接忽略该字段,序列化后就没有该字段,如,在Student的两个关系字段上表示不进行序列化关系字段
 /*** 关系,定义为友谊 指向别人*/@JsonIgnore // 禁止json序列化无限遍历@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.OUTGOING)private List<FriendshipRelation> friendshipRelationOutList;/*** 关系,定义为友谊 指向自己*/@JsonIgnore@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.INCOMING)private List<FriendshipRelation> friendshipRelationInList;
  • @JsonIgnoreProperties:添加在字段上,并标注不进行序列化的字段,如,在Student的两个关系字段上,并添加忽略序列化的属性,该字段上是FriendshipRelation,所以应该表示FriendshipRelation类不需要序列化的属性,@JsonIgnoreProperties({“from”,
    “to”})
/*** 关系,定义为友谊 指向别人*/@JsonIgnoreProperties({"from", "to"}) // 禁止json序列化无限遍历@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.OUTGOING)private List<FriendshipRelation> friendshipRelationOutList;/*** 关系,定义为友谊 指向自己*/@JsonIgnoreProperties({"from", "to"})@Relationship(type = "FRIENDSHIP_RELATION", direction = Relationship.INCOMING)private List<FriendshipRelation> friendshipRelationInList;

5、StudentRepository为数据库操作,因为后面有删除关系,所以需要@Transactional

package com.chengkun.neo4j.repository;import com.chengkun.neo4j.entity.FriendshipRelation;
import com.chengkun.neo4j.entity.Student;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;import java.util.List;/*** @author chengkun* @version v1.0* @create 2021/3/31 9:30**/
@Transactional
@Repository
public interface StudentRepository extends Neo4jRepository<Student, Long> {/*** 通过name查找学生node** @param name* @return*/Student findByName(String name);/*** 根据name获取学生 out 友谊关系** @param name* @return*/@Query("match p=(a:Student)-[r:FRIENDSHIP_RELATION]->(b:Student) where a.name = {0} return p")List<FriendshipRelation> outFriendship(String name);/*** 根据name获取学生 in 友谊关系** @param name* @return*/@Query("match p=(a:Student)<-[r:FRIENDSHIP_RELATION]-(b:Student) where a.name={0} return p")List<FriendshipRelation> inFriendship(String name);/*** 根据name获取学生 both 友谊关系** @param name* @return*/@Query("match p=(a:Student) <- [r:FRIENDSHIP_RELATION] ->(b:Student) <- [rr:FRIENDSHIP_RELATION] -> (c:Student) where b.name = {0} return p")List<FriendshipRelation> bothFriendship(String name);}

6、创建SpringDataDeo4jController进行测试

package com.chengkun.neo4j.controller;import com.chengkun.neo4j.entity.FriendshipRelation;
import com.chengkun.neo4j.entity.Student;
import com.chengkun.neo4j.repository.StudentRepository;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
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.List;/*** @author chengkun* @version v1.0* @create 2021/3/31 10:21**/
@Api(tags = "spring-data-neo4j增删改查")
@RestController
@Log4j2
@RequestMapping("/spring-data-neo4j")
public class SpringDataDeo4jController {@Autowiredprivate StudentRepository studentRepository;@ApiOperation(value = " 保存单个节点(使用spring-data-neo4j)")@PostMapping(value = "/saveStudentNode", produces = "application/text;charset=UTF-8")public String saveStudentNode(String name, int age) {Student student = new Student();student.setName(name);student.setAge(age);studentRepository.save(student);return "创建成功";}@ApiOperation(value = "保存批量节点(使用spring-data-neo4j)")@GetMapping(value = "saveAllStudentNode", produces = "application/text;charset=UTF-8")public String saveAllStudentNode() {Student student1 = new Student();student1.setName("张三");student1.setAge(18);Student student2 = new Student();student2.setName("李四");student2.setAge(19);Student student3 = new Student();student3.setName("王五");student3.setAge(18);Student student4 = new Student();student4.setName("赵六");student4.setAge(20);List<Student> list = Lists.newArrayList(student1, student2, student3, student4);studentRepository.saveAll(list);return "创建成功";}@ApiOperation(value = "根据name查询学生(使用spring-data-neo4j)")@PostMapping(value = "/findStudentByName", produces = "application/json;charset=UTF-8")@ApiImplicitParam(name = "name", value = "学生名称")public Student findStudentByName(@RequestParam("name") String name) {Student student = studentRepository.findByName(name);return student;}@ApiOperation(value = "修改学生名称(使用spring-data-neo4j)")@GetMapping(value = "/updateStudentByName", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name", value = "修改前学生名称"),@ApiImplicitParam(name = "updateName", value = "修改后学生名称"),})public Student updateStudentByName(String name, String updateName) {Student student = studentRepository.findByName(name);student.setName(updateName);studentRepository.save(student);return student;}@ApiOperation(value = "根据名称删除学生(使用spring-data-neo4j)")@GetMapping(value = "/deleteStudentByName", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name", value = "修改前学生名称"),})public Student deleteStudentByName(String name) {Student student = studentRepository.findByName(name);studentRepository.delete(student);return student;}@ApiOperation(value = "删除所有学生(使用spring-data-neo4j)")@GetMapping(value = "/deleteAllStudent", produces = "application/text;charset=UTF-8")public String deleteAllStudent() {studentRepository.deleteAll();return "删除成功";}@ApiOperation(value = "查询全部(使用spring-data-neo4j)")@GetMapping(value = "/findAll", produces = "application/json;charset=UTF-8")public List<Student> findAll() {List<Student> studentNodeList = Lists.newArrayList(studentRepository.findAll());return studentNodeList;}/*** 分页查询*/@ApiOperation(value = "分页查询(使用spring-data-neo4j)")@GetMapping(value = "/pageFindAll", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "page", value = "第几页"),@ApiImplicitParam(name = "size", value = "每页条数"),})public Page<Student> pageFindAll(int page, int size) {// page从0开始Pageable pageable = PageRequest.of(page - 1, size);Page<Student> studentNodePage = studentRepository.findAll(pageable);return studentNodePage;}@ApiOperation(value = "保存友谊关系(使用spring-data-neo4j)")@GetMapping(value = "/saveFriendShip", produces = "application/text;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "studentFromName", value = "关系起点名称"),@ApiImplicitParam(name = "studentToName", value = "关系终点名称"),})public String saveFriendShip(String studentFromName, String studentToName) {Student studentFrom = studentRepository.findByName(studentFromName);Student studentTo = studentRepository.findByName(studentToName);FriendshipRelation studentFromToRelation = new FriendshipRelation();studentFromToRelation.setName("友谊关系");// 添加fromstudentFromToRelation.setFrom(studentFrom);//添加tostudentFromToRelation.setTo(studentTo);//只需要在from节点保存关系即可studentFrom.addOutRelation(studentFromToRelation);studentRepository.save(studentFrom);return "保存成功";}@ApiOperation(value = "保存双向友谊关系(使用spring-data-neo4j)")@GetMapping(value = "/saveBrotherFriendShip", produces = "application/text;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name1", value = "学生名称1"),@ApiImplicitParam(name = "name2", value = "学生名称2"),})public String saveBrotherFriendShip(String name1, String name2) {Student studentFrom = studentRepository.findByName(name1);Student studentTo = studentRepository.findByName(name2);FriendshipRelation studentFromToRelation = new FriendshipRelation();studentFromToRelation.setName("友谊关系");// 添加fromstudentFromToRelation.setFrom(studentTo);//添加tostudentFromToRelation.setTo(studentTo);//from->tostudentFrom.addOutRelation(studentFromToRelation);FriendshipRelation studentToFromRelation = new FriendshipRelation();studentToFromRelation.setName("友谊关系");// 添加fromstudentToFromRelation.setFrom(studentTo);//添加tostudentToFromRelation.setTo(studentFrom);//to->fromstudentFrom.addInRelation(studentToFromRelation);studentRepository.save(studentFrom);return "保存成功";}@ApiOperation(value = "根据名称查询in关系(使用spring-data-neo4j)")@GetMapping(value = "/inFriendshipByName", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name", value = "学生名称"),})public List<FriendshipRelation> inFriendshipByName(@RequestParam("name") String name) {List<FriendshipRelation> friendshipRelations = studentRepository.inFriendship(name);return friendshipRelations;}@ApiOperation(value = "根据名称查询out关系(使用spring-data-neo4j)")@GetMapping(value = "/outFriendshipByName", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name", value = "学生名称"),})public List<FriendshipRelation> outFriendshipByName(String name) {List<FriendshipRelation> friendshipRelations = studentRepository.outFriendship(name);return friendshipRelations;}@ApiOperation(value = "获取兄弟关系(使用spring-data-neo4j)")@GetMapping(value = "/getBrotherFriendShip", produces = "application/json;charset=UTF-8")@ApiImplicitParams({@ApiImplicitParam(name = "name", value = "学生名称"),})public List<FriendshipRelation> getBrotherFriendShip(String name) {List<FriendshipRelation> friendshipRelations = studentRepository.bothFriendship(name);return friendshipRelations;}
}


总结:

  1. java连接嵌入式数据库,因为是内嵌的,在操作数据库时无法查询数据界面,不太方便,操作使用有点类似jpa。
  2. java连接服务式数据库,需要使用驱动进行连接,完全使用cql语句进行操作,需要打开neo4j的bolt连接端口7687,操作有点类似mybatis。
  3. 使用Spring Data Neo4j连接数据库,支持cql和内置方法,相当于上面两种混合型,需要注意版本问题,这个是Spring Boot的老问题,每个版本差距还是很大的。

源码地址:springboot-neo4j

参考网址:
Neo4j安装及简单使用
W3Cschool-neo4j教程
Neo4j的使用与Java调用实例
Spring Data Neo4j 使用
Sping Data Neo4j官网

图数据库Neo4j的使用(附带源码)相关推荐

  1. Silverlight实用窍门系列:27.Silverlight二维旋转+平面渐变+动画,模拟雷达扫描图之基本框架【附带源码实例】...

    在现实生活中的雷达运行扫描到物体的某一些属性(比如:速度,频率)超过安全范围值将会报警.在实际的某一些项目中(比如监控系统),我们也想制作一个雷达扫描图来模拟扫描各种设备那么应该如何做呢? 我们将各种 ...

  2. android类中定义颜色,自定义实现简单的Android颜色选择器(附带源码)

    在写Android App过程中需要一个简单的颜色选择器,Android自带的ColorPicker和网上的一些ColorPicker都太高端了,都实现了颜色渐变功能,我要的不需要那么复杂,只想提供几 ...

  3. python面试题及答案bt_公布上期Python笔试题答案,附带源码与运行结果

    今天发布的内容没有废话,就是上一期的笔试题答案,由于内容较多,我们今天就公布前五道题的答案,附带源码哦!请感兴趣的读者细细研究! 笔试 笔试题一答案:利用Python创建如图所示的二叉树,并给出前序. ...

  4. 图书管理系统(附带源码 )

    简单的图书管理系统(附带源码 ) 因为在实训中心经理布置的一个小项目,自己就写了一个简单的图书管理,写下来和有兴趣的分享一下 这个图书管理有管理员和普通会员两种: 普通会员: 1.可以登录.注册,修改 ...

  5. 2023全新抖音快手微信取图小程序/壁纸小程序源码+代码全开源

    正文: 全新抖音快手微信取图小程序 壁纸小程序源码 全开源 此版本并非最近网传版本,其他站的网传版本是没有数据库的,故此我直接花买下来的完整版本源码! 一款全新的抖音快手微信取图小程序全开源上线了.其 ...

  6. BMP180气压传感器详解与示例(STM32 附带源码)

    BMP180气压传感器详解与示例(STM32 附带源码) 简介 工作模式 校准数值 测试流程 第一步:微处理器读取校准数值 第二步:读取温度.气压初始值 第三步:计算温度.气压 第四步:计算海拔高度 ...

  7. 当图网PPT模板下载网站源码 无错运营版 带会员系统可充值

    帝国cms仿当图网PPT模板素材下载网站源码,是一款比较大气的ppt和素材下载系统,支持6.微信登录,内容页支持ppt视频播放,带付费会员系统,微信支付,支付宝等,文件整站打包附带有测试数据,安装文档 ...

  8. 出自北大教授java项目大鱼吃小鱼游戏开发教学 附带源码和资料

    课程介绍: 大鱼吃小鱼,又称吞食鱼,是一款动作类小游戏.通过不断的吞吃比自己小的鱼类快速成长,最终成为海洋霸主. 本课程讲解一个大鱼吃小鱼游戏的详细开发过程.只要60分钟就可以完成一个你自己亲手开发出 ...

  9. 入门机器学习?好好看看《智能问答与深度学习》随书附带源码

    目录 <智能问答与深度学习>随书附带源码 安装依赖软件 下载源码 执行示例程序 取得帮助 第二章 机器学习基础 第三章 自然语言处理基础 第四章 深度学习初步 第五章 词向量实现及应用 第 ...

  10. SpringMVC异常处理机制详解[附带源码分析]

    SpringMVC异常处理机制详解[附带源码分析] 参考文章: (1)SpringMVC异常处理机制详解[附带源码分析] (2)https://www.cnblogs.com/fangjian0423 ...

最新文章

  1. 访问 Microsoft SQL Server 元数据的三种
  2. 理解 IntelliJ IDEA 的项目配置和Web部署
  3. 华为自动驾驶实车实路测试视频曝光!徐直军:比特斯拉好多了
  4. Linked List Cycle II - LeetCode
  5. 【LeetCode笔记】238. 除自身以外数组的乘积(Java、思路题)
  6. 03 CSS听课笔记
  7. 用计算机写作ppt文库,计算机专业英语Unit 19 计算机专业英语写作.pptx
  8. Objective-C的hook方案(一): Method Swizzling
  9. Android(java)学习笔记155:中文乱码的问题处理(qq登录案例)
  10. [RK3399][Android7.1] 如何将PWM背光线性处理
  11. python: Requests库的一些高级特性
  12. 集群通信组件tribes之使用方法
  13. c++教你唱响天空之城(源码奉上)
  14. [乐意黎原创] 手动挡驾驶技巧
  15. gitlab群组多项目下载
  16. 【JavaScript】笑话生成器
  17. [Swift A] - 实战-豆瓣电台总结
  18. 详细设计 英文_谷歌英文网站如何优化?
  19. 脚本计算后台程序消耗资源
  20. 死亡的意思就是没有任何意义

热门文章

  1. 利用哈夫曼编码压缩文本
  2. 程序的链接与装入过程
  3. ubuntu ufw 开放端口
  4. 数字IC,计算机体系结构方向导师。
  5. mongo数据库命令行使用
  6. Python获取城市列表
  7. IE浏览器中选择本地文件
  8. 云BI产品瓴羊Quick BI,为企业数字化转型保驾护航
  9. c语言中无符号和有符号之间的运算
  10. mysql:将数据库复制到另一个数据库