Spring-Data-JPA
数据库开启操作:以管理员身份开启cmd命令运行框,输入net start mysql开启数据库
jpa学习文档连接:
- 简书详细jpa文档
- JPA查询操作
- JPA 使用 Specification 复杂查询和 Criteria 查询
- Optional和ifPresent进行判空处理
- hibernate-jpamodelgen生成 JPA 元模型
- 启用 Spring Data JPA 审计功能
Spring Data 致力为数据访问(DAO)提供熟悉且一直的基于spring的模板编程,其目的是统一和简化不同类型持久性存储(关系数据库系统和NoSQL数据存储)的访问
JPA全称Java Persistence API ,一种ORM规范(Object Relation mapping)
作用:
- 简化持久操作化的开发工作
- 基于JPA进行持久化可以随意切换数据库
Hibernate与JPA
HIbernate就是实现了JPA接口的ORM框架,----JPA是一套ORM规范,Hibernate实现了JPA规范
入门配置
实例与一些注解的解释
@Entity // 作为hibernate 实体类
@Table(name = "tb_customer") // 映射的表名(数据库中的表)
public class Customer {
/**
* @Id:声明主键的配置
* @GeneratedValue:配置主键的生成策略
* strategy
* GenerationType.IDENTITY :自增,mysql
* * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
* GenerationType.SEQUENCE : 序列,oracle
* * 底层数据库必须支持序列
* GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
* GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略
* @Column:配置属性和字段的映射关系
* name:数据库表中字段的名称
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long custId; //客户的主键
@Column(name = "cust_name")
private String custName;//客户名称
@Column(name="cust_address")
private String custAddress;//客户地址
application.properties文件配置
spring.datasource.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.username=root
spring.datasource.password=...
#Java代码实体字段命名与数据库表结构字段之间的名称映射策略
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
#下面配置开启后,会禁止将驼峰转为下划线
#spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
# 控制是否可以基于程序中Entity的定义自动创建或者修改DB中表结构
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 控制是否打印运行时的SQL语句与参数信息
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-life-time=1800000
1.@Version注解加上后,更新操作一定要带上注解修饰的字段,且要与数据库中的值一致。
2.@CreatedBy和@CreatedDate会在更新时一并更新,需要主动去维护,或者在@Column注解中加上updatable = false,比如这样@Column(name = “CREATED_DATE”,updatable = false)。
pom.xml文件
<?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>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.itsen</groupId>
<artifactId>spring-data-jpa-Competition</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-data-jpa-Competition</name>
<description>spring-data-jpa-Competition</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>
<!-- 生成jpa元模型-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.4.10.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
<compilerArguments>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</compilerArguments>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
CRUD 案例代码
代码目录
实现类代码
@Data
@Entity//指定当前类是实体类
@Table(name = "JPA_USER")//指定实体类与表之间的对应关系,name指定对应到数据表的名称
//在实体类增删改的时候进行监听,为创建人/创建时间等基础字段赋值,value指定监听类
@EntityListeners(AuditingEntityListener.class)
public class JpaUser {
@Id//指定当前字段为主键
@Column(name = "ID")
//指定主键生成方式
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "JPA_USER_S")
//指定数据库序列别名,sequenceName数据库序列名,name:取的别名
@SequenceGenerator(sequenceName = "JPA_USER_S", name = "JPA_USER_S", allocationSize = 1)
private Long id;
@Column(name = "NAME")
private String name;
@Column(name = "OBJECT_VERSION" )
@Version//修改数据的时候加这个注释的属性名一定要添加上,内容要与原先保持一致
private Long objectVersion;
@Column(name = "CREATED_BY")
@CreatedBy
private String createdBy;
@Column(name = "CREATED_DATE")
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createdDate;
@Column(name = "LAST_UPDATED_BY" )
@LastModifiedBy
private String lastUpdatedBy;
@Column(name = "LAST_UPDATED_DATE" )
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lastUpdatedDate;
}
如何对数据表中的数据进行访问
数据持久层代码
很简单只需要将接口继承与JpaRepository<实现类类名,主键类型>
JpaRepository有两个泛型,前者是具体操作的对象实体,也就是对应的表,后者是ID的类型,接口中已经定义了比较常用的数据库操作。
package com.itsen.repository;
import com.itsen.pojo.JpaUser;
import org.springframework.data.jpa.repository.JpaRepository;
public interface JpaUserRepository extends JpaRepository<JpaUser, Long> {
}
逻辑层:实现类代码
不需要写sql语句,通过创建数据持久层的对象,调用相关方法就行
package com.itsen.service;
import com.itsen.pojo.JpaUser;
import com.itsen.repository.JpaUserRepository;
import com.itsen.service.JpaUserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class JpaUserServiceImpl implements JpaUserService {
@Resource
private JpaUserRepository jpaUserRepository;
@Override
public JpaUser insertUser(JpaUser user) {
return jpaUserRepository.save(user);
}
@Override
public void deleteUser(Long id) {
jpaUserRepository.deleteById(id);
}
@Override
public JpaUser updateUser(JpaUser user) {
return jpaUserRepository.save(user);
}
@Override
public List<JpaUser> findAllUser() {
return jpaUserRepository.findAll();
}
@Override
public JpaUser findUserById(Long id) {
return jpaUserRepository.findById(id).orElse(null);
}
}
controller层代码
@RestController
@RequestMapping("/user")
public class JpaUserController {
@Autowired
private JpaUserService jpaUserService;
/**
* 新增用户
*/
@PostMapping("")
public JpaUser addUser(@RequestBody JpaUser user){
return jpaUserService.insertUser(user);
}
/**
* 删除用户
*/
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable("id") Long id){
jpaUserService.deleteUser(id);
}
/**
* 修改用户
*/
@PutMapping("")
public JpaUser updateUser(@RequestBody JpaUser user){
return jpaUserService.updateUser(user);
}
/**
* 全查用户
*/
@GetMapping("")
public List<JpaUser> findAll(){
return jpaUserService.findAllUser();
}
/**
* id查用户
*/
@GetMapping("/{id}")
public JpaUser findbyId(@PathVariable("id") Long id){
return jpaUserService.findUserById(id);
}
}
restful风格请求规范
restful风格详细文档
简化一下:
-
GET:查询
-
POST:插入、新建
-
PUT:完全更新
-
PATCH:部分更新
-
DELETE:删除
举个栗子: -
GET /zoos:获取所有动物园
-
POST /zoos:新建一个动物园
-
GET /zoos/ID:获取此ID的动物园信息
-
PUT /zoos/ID:更新此ID动物园全部信息(提供该动物园的全部信息)
-
PATCH /zoos/ID:更新此ID动物园部分信息(提供该动物园的部分信息)
-
DELETE /zoos/ID:删除此ID的动物园信息
-
GET /zoos/ID/animals:获取此ID动物园的所有动物
-
DELETE /zoos/ID/animals/ID:删除ID(前者)动物园的ID(后者)动物
注入creater和updater
创建一个Auditor类,实现AuditorAware接口,重写方法即可
@Configuration
public class UserAuditor implements AuditorAware<String> {
/**
* 获取当前创建或修改的用户
*
* @return 获取当前创建或修改的用户Uid
*/
@Override
public Optional<String> getCurrentAuditor() {
return Optional.of("俺是测试更新者");
}
}
主键生成策略
TABLE主键生成策略
动态查询补充
jpa动态查询
适用于字符串的一些模糊或者精确查询
多表操作
一对一
1.配置关联关系
修改时设置账户为null就想删除关联的账户信息
限制关联的对象不能为null
一对多
外键列名自动在多的一方(message)创建
OneToMany举例
在多的一方(article)数据表中增加了author_id外键
多对一删除操作
多对多
举例users与authority
被维护的是authority,所以在users类是进行CRUD 的维护类
users类中代码声明
authority类中声明代码
元数据的简介
按照传统的定义,元数据(Metadata)是关于数据的数据。元数据打通了源数据、数据仓库、数据应用,记录了数据从产生到消费的全过程。元数据主要记录数据仓库中模型的定义、各层级间的映射关系、监控数据仓库的数据状态及ETL的任务运行状态。在数据仓库系统中,元数据可以帮助数据仓库管理员和开发人员非常方便地找到其所关心的数据,用于指导其进行数据管理和开发工作,提高工作效率。
在DataArts Studio中,元数据是数据的描述数据,可以为数据说明其属性(数据连接、类型、名称、大小等),或其相关数据(位于拥有者、标签、分类、密级等)。
元数据按用途的不同,可以分为两类:技术元数据(Technical Metadata)和业务元数据(Business Metadata)。
技术元数据是存储关于数据仓库系统技术细节的数据,是用于开发和管理数据仓库使用的数据。在DataArts Studio中,技术元数据即为技术资产,显示数据库、数据表、数据量的数量及其详情。
业务元数据从业务角度描述了数据仓库中的数据,它提供了介于使用者和实际系统之间的语义层,使得不懂计算机技术的业务人员也能够“读懂”数据仓库中的数据。在DataArts Studio中,业务元数据包含业务资产和指标资产,业务资产显示业务对象、逻辑实体、业务属性的数量及其详情,指标资产显示业务指标及其详情。
DataArts Studio中的技术元数据来源于元数据采集任务,您需要在创建并运行元数据采集任务后才能在数据地图中查看元数据。