SpringBoot 中JPA集成PostgreSql(详细步骤)

什么是JPA?(Java Persistence API)

Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.

Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

Features

  • Sophisticated support to build repositories based on Spring and JPA
  • Support for Querydsl predicates and thus type-safe JPA queries
  • Transparent auditing of domain class
  • Pagination support, dynamic query execution, ability to integrate custom data access code
  • Validation of @Query annotated queries at bootstrap time- Support for XML based entity mapping- JavaConfig based repository configuration by introducing @EnableJpaRepositories.

国内说法

JPA 是指 Java Persistence API,即 Java 的持久化规范,一开始是作为 JSR-220 的一部分。 JPA 的提出,主要是为了简化 Java EE 和 Java SE 应用开发工作,统一当时的一些不同的 ORM 技术。 一般来说,规范只是定义了一套运作的规则,也就是接口,而像我们所熟知的Hibernate 则是 JPA 的一个实现(Provider)。

JPA 定义了什么,大致有:

  • ORM 映射元数据,用来将对象与表、字段关联起来- 操作API,即完成增删改查的一套接口- JPQL 查询语言,实现一套可移植的面向对象查询表达式

PostgreSQL简介

PostGreSQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS),号称世界上最先进的开源关系型数据库 经过长达15年以上的积极开发和不断改进,PostGreSQL已在可靠性、稳定性、数据一致性等获得了很大的提升。 对比时下最流行的 MySQL 来说,PostGreSQL 拥有更灵活,更高度兼容标准的一些特性。 此外,PostGreSQL基于MIT开源协议,其开放性极高,这也是其成为各个云计算大T 主要的RDS数据库的根本原因。

JPA中使用PostgreSQL

一、添加依赖包

Spring Boot Mavn项目 Pom.xml文件中添加依赖包

<!--jpa与postgresql-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><scope>runtime</scope>
</dependency>

二、配置PostgreSQL和jpa

application-dev.yml(开发环境)中添加如下:

server:port: 8088
spring:datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: org.postgresql.Driverurl: jdbc:postgresql://192.168.0.30:5432/thingsboardusername: rootpassword: 123456hikari:minimum-idle: 5maximum-pool-size: 15auto-commit: trueidle-timeout: 30000connection-timeout: 60000validation-timeout: 10000jpa:show-sql: trueredis:host: 127.0.0.1database: 0port: 6379password:lettuce:pool:max-active: 10max-idle: 10max-wait: 5ms
tb:url: https://nybx-ljyz.cpic.com.cn/aimslogging:level: debuglevel.top: debug

注意:

  • yourdatabase,yourusername,yourpassword等信息是否配置正确。
  • spring.jpa.hibernate.ddl-auto 指定为 update,这样框架会自动帮我们创建或更新表结构

三、定义Entity

package com.zlzk.video.server.entity;import lombok.Data;import javax.persistence.*;@Data
@Entity
//@Table(name = "attribute_kv")
public class Attribute {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer rownum;private String entity_type;private String entity_id;private String attribute_type;private String attribute_key;private Boolean bool_v;private String str_v;private Long long_v;private Float dbl_v;/*** Type=json*/private String json_v;private Long last_update_ts;
}

注意:

  • 避坑! 若使用自定义sql,且用自定义实体类(即查出什么字段,实体类就有什么变量)来接收,如果查出来的字段没有一个字段是唯一的(jpa要求有一个唯一的字段),查询出的数据会抽风,参考链接

    解决思路:提供一个唯一字段即可,这里是用的rownum,不同数据库可用row_num、row_id等,比如我用的PostgreSQL,则是需要加row_number() OVER () AS row_num ,并在实体类加上row_num变量来接收查询结果,实际执行sql如下:

    select  row_number() OVER (ORDER BY entity_id) as rownum, * from attribute_kv where entity_id = '1eaaee56e9abd40933ce332a36104a6'
    
  • 避坑!简单类型的数据不能被设置为null,比如数据库中float8,需设置为Float,否则可能报错错误org.hibernate.PropertyAccessException: Null value was assigned to a property of…

  • 如果你的数据库中有自己创建的嵌套schema,要在Table属性中进行写明,如@Table(name = “bookshelf”,schema = “yourschema”)

  • bookName这样的写法会导致如果数据库没有这个数据元,则会创建成book_name

四、定义dao

package com.zlzk.video.server.dao;import com.zlzk.video.server.entity.Attribute;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/*** Param注解*/
import java.util.List;public interface AttributeDao extends JpaRepository<Attribute,String> {//Attribute findAttriById(String entity_id);@Query(name = "findById",nativeQuery = true,value ="select  row_number() OVER (ORDER BY entity_id) as rownum, * from attribute_kv where entity_id = :entity_id")List<Attribute> findByEntity_id(@Param("entity_id")String entity_id);
}

注意:

  • 如果**@Query中有*号**,要在尾部加上nativeQuery = true
  • 更规范的写法应该是写repository包下

五、定义service

package com.zlzk.video.server.service.attribute;import com.zlzk.video.server.dao.AttributeDao;
import com.zlzk.video.server.entity.Attribute;
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.stereotype.Service;import java.util.List;@Service
public class AttributeServiceIml implements AttributeService {@Autowiredprivate AttributeDao attributeDao;/*@Overridepublic Attribute findById(String entity_id) {return attributeDao.findAttriById(entity_id);}*/@Overridepublic void delete(String entity_id) {attributeDao.deleteById(entity_id);}@Overridepublic Attribute save(Attribute attribute) {return  attributeDao.save(attribute);}@Overridepublic Page<Attribute> findAll(int page, int pagesize) {Pageable pageable = PageRequest.of(page,pagesize);return attributeDao.findAll(pageable);}@Overridepublic Attribute update(Attribute attribute) {return attributeDao.save(attribute);}@Overridepublic List<Attribute> findByEntity_id(String entity_id) {return attributeDao.findByEntity_id(entity_id);}
}

六、定义controller

package com.zlzk.video.server.controller.attribute;import com.zlzk.video.server.entity.Attribute;
import com.zlzk.video.server.service.attribute.AttributeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.util.List;@RestController
@RequestMapping("/attr")
public class AttributeController {@Autowiredprivate AttributeService attributeService;@PostMapping("/reg")public Attribute reg(Attribute Attribute){return  attributeService.save(Attribute);}@GetMapping("/findAll")public Page<Attribute> findAll(Integer page, HttpServletResponse response){response.setHeader("Access-Control-Allow-Origin","*");if(page==null||page<=0){page = 0;}else {page -= 1;}return  attributeService.findAll(page,5);}@GetMapping("/delete/{entity_id}")public String delete(@PathVariable String entity_id){attributeService.delete(entity_id);return "sucesss";}/**** @param Attribute* @return*/@PostMapping("/update")public Attribute update(Attribute Attribute){return attributeService.save(Attribute);}/*@GetMapping("/select/{id}")public  Attribute select(@PathVariable String entity_id)throws Exception{return attributeService.findById(entity_id);}*/@GetMapping("/findByEntity_id/{entity_id}")public List<Attribute> findByName(@PathVariable String entity_id){return attributeService.findByEntity_id(entity_id);}}

注意:

  • JWT鉴权中放开

    .pathMatchers("/attr/findByEntity_id/**").permitAll()
    

本人测试结果如下(通过entity_id找数据):

[{"rownum": 1,"entity_type": "DEVICE","entity_id": "1eaaee56e9abd40933ce332a36104a6","attribute_type": "CLIENT_SCOPE","attribute_key": "battery","bool_v": null,"str_v": null,"long_v": 1,"dbl_v": null,"json_v": null,"last_update_ts": 1592377103023
}, {"rownum": 2,"entity_type": "DEVICE","entity_id": "1eaaee56e9abd40933ce332a36104a6","attribute_type": "CLIENT_SCOPE","attribute_key": "latestMoveTime","bool_v": null,"str_v": null,"long_v": 1592211412899,"dbl_v": null,"json_v": null,"last_update_ts": 1592211502537
}, {"rownum": 3,"entity_type": "DEVICE","entity_id": "1eaaee56e9abd40933ce332a36104a6","attribute_type": "CLIENT_SCOPE","attribute_key": "latitude","bool_v": null,"str_v": null,"long_v": 1,"dbl_v": null,"json_v": null,"last_update_ts": 1592377103023
}, {"rownum": 4,"entity_type": "DEVICE","entity_id": "1eaaee56e9abd40933ce332a36104a6","attribute_type": "CLIENT_SCOPE","attribute_key": "limitAlarmPeriod","bool_v": null,"str_v": null,"long_v": 10,"dbl_v": null,"json_v": null,"last_update_ts": 1592211502537
}, {"rownum": 5,"entity_type": "DEVICE","entity_id": "1eaaee56e9abd40933ce332a36104a6","attribute_type": "CLIENT_SCOPE","attribute_key": "longitude","bool_v": null,"str_v": null,"long_v": 1,"dbl_v": null,"json_v": null,"last_update_ts": 1592377103023
}

SpringBoot 中JPA集成PostgreSql(详细步骤)避坑!相关推荐

  1. 【OWA】04集成SharePoint:SharePoint集成OWA详细步骤(SharePoint与OWA集成)

    前言 在前面咱们已经从owa服务器创建.把owa服务加入域控.在owa服务器中安装部署office web app server,接下载咱们一起来了解一下owa如何域SharePoint做集成(Sha ...

  2. xp如何添加桌面计算机回收站,详解桌面回收站图标在XP电脑中操作删除的详细步骤...

    我们在电脑的很多的设置中,很多的用户都是可以打开不同的版本来设置电脑的问题的,对于电脑的回收站图标的设置有的小伙伴不是很喜欢使用桌面的这个图标怎么直接删除回收站图标的呢,今天小编就来跟大家分享一下XP ...

  3. 在虚拟机中安装Linux操作系统详细步骤

    欢迎关注博主 Mindtechnist 或加入[Linux C/C++/Python社区]一起探讨和分享Linux C/C++/Python/Shell编程.机器人技术.机器学习.机器视觉.嵌入式AI ...

  4. SpringBoot中使用Ehcache的详细教程

    本都缓存能做什么? 数据缓存在jvm中,大幅提升性能 为什么要用本地缓存? 相对于IO操作,速度快,效率高 相对于Redis,Redis是一种优秀的分布式缓存实现,受限于网卡等原因,远水救不了近火 本 ...

  5. SpringBoot 中 JPA 的使用

    前言 第一次使用 Spring JPA 的时候,感觉这东西简直就是神器,几乎不需要写什么关于数据库访问的代码一个基本的 CURD 的功能就出来了.下面我们就用一个例子来讲述以下 JPA 使用的基本操作 ...

  6. android APP集成系统详细步骤及注意事项(amlogic平台)

    此说明用于amlogic平台集成不签名的apk.(如何判断集成的apk需不需要签名.简单来说使用U盘安装后,能正常打开使用的就可以不签名方式集成.) 各平台的文件系统有差异,但整体大同小异.其他平台的 ...

  7. 基础实验中的抗体选择过程和避坑Tips

    基础实验中,抗原抗体结合反应是我们很常运用的一个原理,像免疫组化.免疫荧光.免疫印迹试验(Western Blot).ELISA等都是常见又很重要的几种实验.而实验的关键步骤,就在于抗体的选择.抗体选 ...

  8. SpringBoot中post请求报405错误排坑

    记一次排坑过程. SpringBoot中前端向后端发起post请求,页面提示405错误,方法不被支持. 然后尝试了一下get请求,是完全没问题的. 一开始以为是控制器配置错了,但仔细排查,控制器用的是 ...

  9. SpringBoot集成Redis实战——步骤、坑点、解决方案

    背景 回顾项目中的TODO工作,发现留了一条待办项,即对Redis配置参数的具体含义的了解.开发平台研发期间,由于时间紧张,对于Redis,没有进行相对充分的技术预研,集成的比较粗放,虽然目标达成了, ...

最新文章

  1. [转] L1 L2范数
  2. [EF Core]数据迁移(二)
  3. 工作占用了太多私人时间_职晓|如果工作占用了生活时间,我应不应该辞职?...
  4. 显卡在电脑什么位置_告诉你什么配置的电脑显卡/GPU才能播放4K电影视频
  5. VS2005发布网站问题及aspnet_merge.exe”已退出,代码为 1的错误
  6. 9. 回文数 golang 整数处理
  7. 精选30个优秀的CSS技术和实例
  8. 三款在线css3样式生成工具
  9. 阿里云虚拟主机针对恶意频繁攻击式访问造成CPU爆满的解决方法
  10. spring官网下载
  11. labview与C数据类型的对应关系
  12. 数字通信技术知识点一
  13. Protus 8.6 及以上如何找到library文件夹
  14. 在TX2上(arm架构)安装FastDB
  15. 美国经济数据公布时间
  16. CSAPP : Arch Lab 解题报告
  17. 金多多简述调整浪的特征十分明显
  18. python提取发票信息发票识别_分享一个电子发票信息提取工具(Python)
  19. Python实现:已知化学分子的输入文件坐标(高斯计算输入文件为例),求其中任意三个原子确定的平面的法向量和单位法向量
  20. java 设计模式 常用21种

热门文章

  1. CAD无法安装是什么原因?CAD无法安装解决办法
  2. 2020年网络安全等级保护执法典型案例汇总(截至2020年3月26日)
  3. 从金融到物联网 区块链的落地应用将如何改变世界?
  4. 在线海量主图设计模板无门槛在线设计!
  5. 计算机专硕_平均分369分!这所985大学计算机专硕!
  6. IC卡ID卡混合型多功能DLC430考勤机门禁一体机安装调试使用说明
  7. ADS16488驱动的软硬件设计以及ROS的驱动
  8. 2019年总结 - 收获很多
  9. 【华为OD考试真题】报数游戏(Python实现)
  10. android常用词汇带音标,下拉通知栏就能背单词,不知不觉懂了好多 - 贝壳单词 #Android...