JPA是Java Persistence API的简称,Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

它是SUN公司推出的一套基于ORM的规范。ORM又是什么?全英文名为Object-Relational Mapping:对象关系映射,简单来说为了不用JDBC那一套原始方法来操作数据库,ORM框架横空出世。

简单介绍下,Spring中的Spring-data-jpa技术,Spring Data JPA 是 Spring Data 系列的一部分,可以轻松实现基于 JPA 的存储库。该模块在处理对基于 JPA 的数据访问层的有所增强。使用数据访问技术快速构建应用变得更加容易。

特征:

  • 支持基于spring和JPA构建存储数据业务
  • 支持基于实体映射的XML
  • 提供使用原生sql能力的@Query注解
  • 分页支持、动态查询

本文的目录结构:



表示层:controller

业务层:Entity、Service、Vo

数据访问层:Repository

下面,我们通过一个完整地项目来展现JPA地能力:

1、创建数据库和表:

我们使用Navicat for MySQL工具,执行建表语句,创建一个student表

student建表语句
CREATE TABLE `student` (
`student_id` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL DEFAULT 'cavan',
`classroom` varchar(50) NOT NULL DEFAULT '0',
`sex` varchar(10) NOT NULL DEFAULT '',
`email` varchar(50) NOT NULL,
`phone` varchar(20) NOT NULL DEFAULT '',
`created_by` varchar(20) NOT NULL DEFAULT 'cavan',
`last_modified_by` varchar(20) NOT NULL DEFAULT 'cavan',
`last_modified_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`student_id`),
UNIQUE KEY (`email`,`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

查看创建后的表:

2、引入依赖包

pom.xml的配置信息

pom.xml
        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.14</version>
</dependency>
3、配置application.properties连接数据库信息
application.properties
# 应用名称
spring.application.name=jpa
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://121.43.225.17:3306/test?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=
# 应用服务 WEB 访问端口
server.port=8888
4、业务层
4.1 定义entity实体类(StudentEntity类)
StudentEntity类
package com.cavan.jpa.entity;

import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.GenericGenerator; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; import java.sql.Timestamp; /**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-03 20:44
*/
@Entity
@Table(name = "student")
@GenericGenerator(name = "uuid", strategy = "uuid")
public class StudentEntity {
private String id;
private String name;
private String classroom;
private String sex;
private String email;
private String phone;
private String createdBy;
private String lastModifiedBy;
private Timestamp lastModifiedDate;
private Timestamp createdDate; @Id
@GeneratedValue(generator = "uuid")
@Column(name = "student_id")
public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getClassroom() {
return classroom;
} public void setClassroom(String classroom) {
this.classroom = classroom;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} public String getCreatedBy() {
return createdBy;
} public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
} public String getLastModifiedBy() {
return lastModifiedBy;
} public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
} @Column(name = "last_modified_date",
columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
insertable = false,
updatable = false)
@Generated(GenerationTime.ALWAYS)
public Timestamp getLastModifiedDate() {
return lastModifiedDate;
} public void setLastModifiedDate(Timestamp lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
} @Column(name = "created_date",
columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
insertable = false,
updatable = false)
@Generated(GenerationTime.ALWAYS)
public Timestamp getCreatedDate() {
return createdDate;
} public void setCreatedDate(Timestamp createdDate) {
this.createdDate = createdDate;
}
}

一些常用注解(本文用到不多):

注解 作用 常用属性
@Entity 指定当前类是实体类
@Table 指定实体类和表之间的对应关系 name:指定数据库表的名称
@EntityListeners 在实体类增删改的时候监听,为创建人/创建时间等基础字段赋值 value:指定监听类
@Id 指定当前字段是主键
@SequenceGenerator 指定数据库序列别名 sequenceName:数据库序列名,name:取的别名
@GeneratedValue 指定主键的生成方式 strategy :指定主键生成策略 generator:选择主键别名
@Column 指定实体类属性和数据库表之间的对应关系 name:指定数据库表的列名称, unique:是否唯一, nullable:是否可以为空,nserttable:是否可以插入,updateable:是否可以更新,columnDefinition: 定义建表时创建此列的DDL
@CreatedBy 自动插入创建人
@CreatedDate 自动插入创建时间
@LastModifiedBy 自动修改更新人
@LastModifiedDate 自动修改更新时间
@JsonFormat 插入/修改/读取的时间转换成想要的格式 pattern:展示格式,timezone:国际时间

注意:

有了@EntityListeners(AuditingEntityListener.class)这个注解,@CreatedBy、@CreatedDate 、@LastModifiedBy 、@LastModifiedDate才生效哦,而且创建人和更新人需要另作注入操作。

4.2 Vo请求/响应类

由于我们在进行增删改查操作时所需要的请求入参信息是不一样的,接口响应需要返回的信息也不太一样,所以我们定义了不同的请求类,用以接收请求消息,传递给业务使用。这里我们分别定义了StudentVo类(创建、更新使用)、StudentIdVo类(删除使用)、StudentQueryVo类(查询使用)。

实际上,当你严格校验你的请求参数时,创建和更新请求类应该创建两个类加以区分,这个在请求入参校验实践会详细讲解。

创建更新请求Vo类:

StudentVo类
package com.cavan.jpa.vo;

/**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-03 22:02
*/
public class StudentVo {
private String id;
private String name;
private String classroom;
private String sex;
private String email;
private String phone;
private String createdBy;
private String lastModifiedBy; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getClassroom() {
return classroom;
} public void setClassroom(String classroom) {
this.classroom = classroom;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} public String getCreatedBy() {
return createdBy;
} public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
} public String getLastModifiedBy() {
return lastModifiedBy;
} public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
}

删除请求类:

StudentIdVo类
package com.cavan.jpa.vo;

/**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-04 11:55
*/
public class StudentIdVo {
private String id; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
}
}

查询请求类:

StudentQueryVo类
package com.cavan.jpa.vo;

/**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-05 11:25
*/
public class StudentQueryVo {
private Integer pagesize;
private Integer pageNum;
private String id;
private String name;
private String classroom;
private String sex; public Integer getPagesize() {
return pagesize;
} public void setPagesize(Integer pagesize) {
this.pagesize = pagesize;
} public Integer getPageNum() {
return pageNum;
} public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getClassroom() {
return classroom;
} public void setClassroom(String classroom) {
this.classroom = classroom;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
}
}
4.3 service服务类(分为 StudentService 服务接口类和 StudentServiceImpl 服务实现类)

业务逻辑层的核心就是service服务及其实现类,一些重要的逻辑都会写到impl中,而不是直接写在controller中。

我们对学生实现最简单的新增、删除、修改、查询功能。

代码如下:

服务接口类:

StudentService类
package com.cavan.jpa.service;

import com.cavan.jpa.entity.StudentEntity;
import com.cavan.jpa.vo.StudentIdVo;
import com.cavan.jpa.vo.StudentQueryVo;
import com.cavan.jpa.vo.StudentVo; import java.util.List; public interface StudentService {
/**
* create student
*
* @return student
*/
String create(StudentVo studentVo); /**
* delete student
*
* @return student
*/
String delete(StudentIdVo studentIdVo); /**
* update student
*
* @return student
*/
String update(StudentVo studentVo); /**
* query student
*
* @return student
*/
List<StudentEntity> query(StudentQueryVo studentQueryVo); }

服务实现类:

StudentServiceImpl类
package com.cavan.jpa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.cavan.jpa.entity.StudentEntity;
import com.cavan.jpa.repository.StudentRepository;
import com.cavan.jpa.service.StudentService;
import com.cavan.jpa.vo.StudentIdVo;
import com.cavan.jpa.vo.StudentQueryVo;
import com.cavan.jpa.vo.StudentVo;
import org.springframework.beans.BeanUtils;
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.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList;
import java.util.List; /**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-03 21:37
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentRepository studentRepository; @Override
public String create(StudentVo studentVo) {
StudentEntity studentEntity = new StudentEntity();
BeanUtils.copyProperties(studentVo, studentEntity);
studentRepository.save(studentEntity);
return "create ok";
} @Override
public String delete(StudentIdVo studentIdVo) {
studentRepository.deleteById(studentIdVo.getId());
return "delete ok";
} @Override
public String update(StudentVo studentVo) {
StudentEntity studentEntity = studentRepository.findById(studentVo.getId()).get();
BeanUtil.copyProperties(studentVo, studentEntity, true,
CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
studentRepository.save(studentEntity);
return "update ok";
} @Override
public List<StudentEntity> query(StudentQueryVo studentQueryVo) {
Integer pageNum = studentQueryVo.getPageNum();
List<Sort.Order> orders = new ArrayList<>();
orders.add(new Sort.Order(Sort.Direction.DESC, "last_modified_date"));
Sort sort = Sort.by(orders);
Pageable pageable = PageRequest.of(pageNum > 0 ? pageNum - 1 : pageNum, studentQueryVo.getPagesize(), sort);
Page<StudentEntity> page = studentRepository.queryStudent(studentQueryVo.getId(),
studentQueryVo.getName(),
studentQueryVo.getSex(),
studentQueryVo.getClassroom(), pageable);
if (page.getTotalPages() < pageNum && page.getTotalPages() > 0) {
page = studentRepository.queryStudent(studentQueryVo.getId(),
studentQueryVo.getName(),
studentQueryVo.getSex(),
studentQueryVo.getClassroom(), pageable);
}
return page.getContent();
}
}
5、表示层

我们这里全部使用的是POST请求,分别定义了以下功能接口:

  • 创建接口,用来创建一条学生信息数据
  • 删除接口,根据学生的学号删除学生信息
  • 更新接口,根据学生的学号更新学生信息
  • 查询接口,根据学生姓名、性别、班级等进行查询操作
StudentManageController类
package com.cavan.jpa.controller;

import com.cavan.jpa.entity.StudentEntity;
import com.cavan.jpa.service.StudentService;
import com.cavan.jpa.vo.StudentIdVo;
import com.cavan.jpa.vo.StudentQueryVo;
import com.cavan.jpa.vo.StudentVo;
import org.springframework.beans.factory.annotation.Autowired;
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; /**
* @program: jpa
* @description: <description>
* @author: cavan
* @create: 2021-12-03 20:22
*/
@RestController
@RequestMapping("/student")
public class StudentManageController {
@Autowired
private StudentService service; /**
* 创建学生
*
* @param studentVo 学生信息
* @return create OK
*/
@PostMapping("/create")
public String create(@RequestBody StudentVo studentVo) {
return service.create(studentVo);
} /**
* 根据学生的学号删除学生信息
*
* @param studentIdVo 学号
* @return delete OK
*/
@PostMapping("/delete")
public String delete(@RequestBody StudentIdVo studentIdVo) {
return service.delete(studentIdVo);
} /**
* 根据学生的学号更新学生信息
*
* @param studentVo 学号
* @return update OK
*/
@PostMapping("/update")
public String update(@RequestBody StudentVo studentVo) {
return service.update(studentVo);
} /**
* 根据学生姓名、性别、班级等查询
*
* @return query OK
*/
@PostMapping("/query")
public List<StudentEntity> query(@RequestBody StudentQueryVo studentQueryVo) {
return service.query(studentQueryVo);
}
}
6、数据连接层

这里只定义了原生sql的查询方法,其他基本的增删改查操作使用JPA内部提供的即可,只用继承 JpaRepository,不需要另外声明。

StudentRepository接口
package com.cavan.jpa.repository;

import com.cavan.jpa.entity.StudentEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; @Repository
public interface StudentRepository extends JpaRepository<StudentEntity, String> {
/**
* query
*/
@Query(value = "select * from student where IF(ifnull(?1,'')!='',student_id=?1,1=1) " +
"and IF(ifnull(?2,'')!='',name like CONCAT('%',?2,'%'),1=1) " +
"and IF(ifnull(?3,'')!='',sex like CONCAT('%',?3,'%'),1=1) " +
"and IF(ifnull(?4,'')!='',classroom like CONCAT('%',?4,'%'),1=1)",
countQuery = "select count(1) from student where IF(ifnull(?1,'')!='',student_id=?1,1=1) " +
"and IF(ifnull(?2,'')!='',name like CONCAT('%',?2,'%'),1=1) " +
"and IF(ifnull(?3,'')!='',sex like CONCAT('%',?3,'%'),1=1) " +
"and IF(ifnull(?4,'')!='',classroom like CONCAT('%',?4,'%'),1=1)", nativeQuery = true)
Page<StudentEntity> queryStudent(String id, String name, String sex, String classroom, Pageable pageable);
}

问题记录:

(1)第一个问题

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

2021-12-03 22:42:34.389 ERROR 15628 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :


APPLICATION FAILED TO START


Description:

Field service in com.cavan.jpa.controller.StudentManageController required a bean of type 'com.cavan.jpa.service.StudentService' that could not be found.

The injection point has the following annotations:

- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:

Consider defining a bean of type 'com.cavan.jpa.service.StudentService' in your configuration.

问题分析:

此问题是由于我在使用注解时错误的将

@Service

@Transactional(rollbackFor = Exception.class)

这两个注解放在了StudentService接口类上,实际应该定义在实现类上。

(2)第二个问题

2021-12-03 23:10:39.864 ERROR 15240 --- [nio-8888-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'created_by' in 'field list'

2021-12-03 23:10:39.917 ERROR 15240 --- [nio-8888-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement] with root cause

java.sql.SQLSyntaxErrorException: Unknown column 'created_by' in 'field list'

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.22.jar:8.0.22]

问题分析:

在使用建表语句时,我们创建的Entity实体类中的createdBy字段,映射到数据时会自动识别小驼峰,将其对应成created_by字段,所以建表时,我们要使用下划线方式,创建字段。

错误建表字段:

(3)第三个问题

2021-12-03 23:21:02.685 ERROR 14972 --- [nio-8888-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'classroom' cannot be null

2021-12-03 23:21:02.744 ERROR 14972 --- [nio-8888-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

java.sql.SQLIntegrityConstraintViolationException: Column 'classroom' cannot be null

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.22.jar:8.0.22]

问题分析:

未在请求参数前加 @RequestBody 注解导致请求传过去的参数都为null值

(4)第四个问题

java.sql.SQLSyntaxErrorException: FUNCTION test.count does not exist. Check the 'Function Name Parsi

问题分析:

在使用原生sql的时候,多打了一个空格,导致报错。在使用原生sql这里最容易出错,可以通过在Navicat本地来测试语句的正确性。

本文代码Gitee链接:

https://gitee.com/cavan2021/springboot/tree/master/jpa

SpringBoot系列(七) jpa的使用,以增删改查为例的更多相关文章

  1. springboot+layui实现PC端用户的增删改查 & 整合mui实现app端的自动登录和用户的上拉加载 & HBuilder打包app并在手机端下载安装

    springboot整合web开发的各个组件在前面已经有详细的介绍,下面是用springboot整合layui实现了基本的增删改查. 同时在学习mui开发app,也就用mui实现了一个简单的自动登录和 ...

  2. 最简单的mybatis增删改查样例

    最简单的mybatis增删改查样例 Book.java package com.bookstore.app; import java.io.Serializable; public class Boo ...

  3. 基于SpringBoot开发一个Restful服务,实现增删改查功能

    前言 在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练. ...

  4. spring boot快速入门 4: jpa数据库操作 实现增删改查

    spring boot jpa逆向生成表 简单实例: 第一步:pom文件: <?xml version="1.0" encoding="UTF-8"?&g ...

  5. oracle学习笔记系列------oracle 基本操作之表的增删改查

    --创建一个表 CREATE TABLE employee_souvc( id ), name ), gender ), birth DATE, salary ,), job ), deptno ) ...

  6. springboot+thymeleaf+springbootJPA实现一个简单的增删改查

    1.springboot是什么,给我们带来了什么方便? 通过阅读springboot的书籍发现springboot最便利的是为我们自动配置了很多的东西,几乎可以实现无xml,甚至简单的无sql,为我们 ...

  7. JPA+Hibernate 3.3 ——增删改查

    1.     查找对象   1)  用find()方法查找对象 public void getPerson(){ EntityManagerFactory factory = Persistence. ...

  8. (五)JPA - 原生SQL实现增删改查

    6.原生SQL JPA除了对JPQL提供支持外,还对原生SQL语句也提供了支持.下面小节一起来看看吧. 6.1 查询单个 示例代码: @Test public void getSingle() { E ...

  9. JavaWeb学习记录(七)——MVC操作数据库增删改查与分页功能

    一.分页工具类 package blank.util;import java.util.List; import org.springframework.jdbc.core.JdbcTemplate; ...

  10. Aerospike系列:4:简单的增删改查aql

    [root@localhost bin]# aql --help Usage: aql OPTIONS OPTIONS -h <host> The hostname to the serv ...

随机推荐

  1. 一道SQL面试题

    表结构如下 是一张递归格式的表 使用SQL转换成如下格式 SQL实现 使用SQL转换成上图的格式 SQL代码: WITH T_Recur AS ( SELECT Id,1 num, cast(name ...

  2. 你不知道的 HTTPS 压测

    ​简介:随着互联网安全规范的普及,使用 HTTPS 技术进行通信加密,实现网站和 APP 的可信访问,已经成为公认的安全标准.本文将介绍针对 HTTPS 协议做压力测试的关注点,以及使用 PTS 做 ...

  3. 如何使用 Kubernetes 监测定位慢调用

    ​简介:本次课程主要分为三大部分,首先将介绍慢调用的危害以及常见的原因:其次介绍慢调用的分析方法以及最佳实践:最后将通过几个案例来去演示一下慢调用的分析过程. 作者:李煌东 大家好,我是阿里云的李煌东 ...

  4. [GPT] 同为 nodejs 库的 Puppeteer 和 cheerio 的区别是什么

    Puppeteer 和 cheerio 是两个完全不同的库,用途和功能也截然不同. Puppeteer 是一个 Node.js 库,它使用 Chrome 或 Chromium 浏览器作为渲染引擎,通过 ...

  5. WPF 自定义控件入门 可重写的各个方法或属性的意义

    本文属于 WPF 自定义控件入门系列博客.本文整理在 WPF 里面,自定义控件,非用户控件时,可以重写基类的许多方法和属性,这些方法和属性的作用和含义.方便让大家了解到自定义控件时,有哪些方法或属性可 ...

  6. dockerfile构建镜像常用命令

    一.什么是dockerfile Dockerfile是一个包含用于组合映像的命令的文本文档.可以使用在命令行中调用任何命令. Docker通过读取Dockerfile中的指令自动生成映像. docke ...

  7. vue使用echart(地图,弹窗展示多条数据,option定义)

    第二次用echart,第一次做地图, <template> <div class="echarts" style="background:#3bafde ...

  8. 快速搭建Zookeeper和Kafka环境

    前言 由于项目需要涉及到zookeeper和Kafka的使用,快速做了一篇笔记,方便小伙伴们搭建环境. zookeeper 官方定义 What is ZooKeeper? ZooKeeper is a ...

  9. 四、【转】基于知识图谱的推荐系统(KGRS)综述

    以下文章来源于AI自然语言处理与知识图谱 ,作者Elesdspline 导语 本文是2020年针对知识图谱作为辅助信息用于推荐系统的一篇综述.知识图谱对于推荐系统不仅能够进行更精确的个性化推荐,而且对 ...

  10. Golang ETCD包的安装使用 golang安装etcd第三方库clientv3 报错 解决

    目录 ETCD 官网 视频地址 课件资料 ETCD 日志收集项目 为什么要自己写不用ELK? 项目的架构 上节课项目进度 etcd介绍 安装etcd windows安装 Ubuntu(linux系统) ...