.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.markdown-body pre, .markdown-body pre>code.hljs { color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.hljs-comment, .hljs-quote { color: rgba(153, 153, 136, 1); font-style: italic }
.hljs-keyword, .hljs-selector-tag, .hljs-subst { color: rgba(51, 51, 51, 1); font-weight: 700 }
.hljs-literal, .hljs-number, .hljs-tag .hljs-attr, .hljs-template-variable, .hljs-variable { color: rgba(0, 128, 128, 1) }
.hljs-doctag, .hljs-string { color: rgba(221, 17, 68, 1) }
.hljs-section, .hljs-selector-id, .hljs-title { color: rgba(153, 0, 0, 1); font-weight: 700 }
.hljs-subst { font-weight: 400 }
.hljs-class .hljs-title, .hljs-type { color: rgba(68, 85, 136, 1); font-weight: 700 }
.hljs-attribute, .hljs-name, .hljs-tag { color: rgba(0, 0, 128, 1); font-weight: 400 }
.hljs-link, .hljs-regexp { color: rgba(0, 153, 38, 1) }
.hljs-bullet, .hljs-symbol { color: rgba(153, 0, 115, 1) }
.hljs-built_in, .hljs-builtin-name { color: rgba(0, 134, 179, 1) }
.hljs-meta { color: rgba(153, 153, 153, 1); font-weight: 700 }
.hljs-deletion { background: rgba(255, 221, 221, 1) }
.hljs-addition { background: rgba(221, 255, 221, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }

Java21 + SpringBoot3集成Spring Data JPA

@[toc]

前言

近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。

本项目为前后端分离开发,后端基于Java21SpringBoot3开发,后端使用Spring SecurityJWTSpring Data JPA等技术栈,前端提供了vueangularreactuniapp微信小程序等多种脚手架工程。

本文主要介绍JPA相关技术以及在项目中如何集成Spring Data JPA。

相关技术简介

ORM(Object-Relational Mapping,对象-关系映射)

ORM(Object-Relational Mapping) 即对象-关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中,一个类可以视作数据库中的一张表,类中的属性视作表中的字段,一个对象可以视为表中的一行记录。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM。也就是说ORM是建立了一个实体与数据库表的联系,这使得开发者对实体的直接操作而不是对数据库的操作,但操作实体也就等同于操作了数据库。主流的ORM框架有MyBatis、Hibernate、Spring Data JPA等。

JPA(Java Persistence API,Java持久层API)

JPA(Java Persistence API)是 Java EE 标准中的一部分,它通过提供提供一套对象关系模型(ORM)来帮助在开发应用过程中高效的管理关系型数据。和 JDBC 一样,JPA 本身并不是一个框架,只是一套标准接口,是ORM框架的标准和规范,目前比较成熟的 JPA 实现有 Hibernate、EclipseLink 等。

Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。

JPA的目标是提供一种统一的、面向对象的数据访问方式,使开发人员能够更加方便地进行数据库操作,而不需要关注底层数据库的细节。它抽象了不同数据库之间的差异,提供了一套通用的API,使开发人员能够以相同的方式操作不同的数据库。

JPA的核心概念包括实体(Entity)、实体管理器(EntityManager)、持久化上下文(Persistence Context)等。开发人员可以通过注解或XML配置来定义实体类和数据库表之间的映射关系,然后使用EntityManager进行增删改查等数据库操作。

Hibernate

Hibernate是一个标准的ORM框架,实现Jpa接口。Hibernate着手解决如何实现映射的方案,是一种处理映射关系方法类框架。

JPA和Hibernate 的关系就像JDBC和JDBC 驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。

Spring Data

Spring Data是Spring Framework的一个子项目,它提供了一种简化数据访问层的方式。Spring Data支持多种数据存储技术,包括关系型数据库、NoSQL数据库、搜索引擎等。

通过使用Spring Data,开发人员可以更轻松地进行数据访问,同时还能够利用Spring Framework的其他功能,如依赖注入、面向切面编程等。

Spring Data提供了一组通用的API和实现,可以帮助开发人员快速、简便地访问各种类型的数据存储。

Spring Data JPA

Spring Data JPA是Spring Data项目中的一个模块,它提供了对JPA(Java Persistence API)的支持。

Spring Data JPA通过提供一组简化的API和自动化的实现,使得开发人员可以更轻松地进行数据库访问和操作。它减少了编写重复、繁琐的数据访问代码的工作量,同时还提供了一些方便的特性,如查询方法的自动生成、分页和排序的支持等。

使用Spring Data JPA,开发人员只需定义好实体类和接口,通过继承一些预定义的接口,就可以实现常见的数据访问操作,而无需编写具体的SQL语句。这样可以大大简化开发过程,提高开发效率。

Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,但底层还是使用了 Hibernate 的 JPA 技术实现。

SpringBoot整合Spring Data JPA

zhuanlan.zhihu.com/p/570922724

在下文中笔者将以实现对用户表SysUser的增删改查为例,介绍SpringBoot整合Spring Data JPA的详细过程。所示项目基于Java21SpringBoot3实现,数据库使用MySQL 5.7

引入maven依赖

pom.xml中添加MySQL和Spring Data JPA相关依赖,并引入Lombok用于简化代码。

  1. <dependencies>
  2. <!--Spring Data JPA Starter-->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-data-jpa</artifactId>
  6. </dependency>
  7. <!--MySQL依赖包-->
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. <scope>runtime</scope>
  12. </dependency>
  13. <!-- Lombok -->
  14. <dependency>
  15. <groupId>org.projectlombok</groupId>
  16. <artifactId>lombok</artifactId>
  17. <version>1.18.30</version>
  18. <optional>true</optional>
  19. </dependency>
  20. </dependencies>

修改配置文件

在配置文件application.yml或application.properties中增加数据库和jpa相关配置。以下代码使用的是yml文件。

  1. spring:
  2. datasource:
  3. driver-class-name: com.mysql.cj.jdbc.Driver # JDBC驱动类
  4. url: jdbc:mysql://localhost:3306/db_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai # 数据库url
  5. username: developer # 数据库用户名
  6. password: abc123 # 数据库密码
  7. jpa:
  8. database: mysql # 数据库类型
  9. database-platform: org.hibernate.dialect.MySQL57Dialect # 数据库方言
  10. show-sql: true # 控制台打印SQL
  11. hibernate:
  12. ddl-auto: create # 根据实体类自动建表

上述配置中spring.jpa.hibernate.ddl-auto作用是根据实体类自动建表,无需手写ddl来建表。这样就使得开发者可以专注于实体类的设计,无需再去考虑建表SQL,可以提高开发效率。但此配置项更适合于开发环境时使用,不建议生产环境使用。

ddl-auto可选值如下:

  • none,默认值,无任何操作;
  • create,服务启动时没有表会新建表,有表则删除表和已有数据后重新建表;
  • create-drop,服务启动时没有表会新建表,有表则清空数据并删除后重新建表,服务停止时删除所有表和数据;
  • update,服务启动时没有表则新建表,有表则更新表结构,不清空已有数据;
  • validate,服务启动时会校验实体类和数据库表结构是否一致,不一致会报错。

定义Spring Data JPA配置类

定义一个配置类Bean,启用Spring Data JPA,也可以直接main方法所在类上直接添加@EnableJpaRepositories@EntityScan注解。

  1. package com.demo.data.config;
  2. import org.springframework.boot.autoconfigure.domain.EntityScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  5. /**
  6. * Spring Data JPA Bean配置
  7. * 启用Jpa,扫描指定包下的Repository类和指定包下的实体类
  8. */
  9. @Configuration
  10. @EnableJpaRepositories(basePackages = {"com.demo.data.repo"})
  11. @EntityScan(basePackages = "com.demo.data.model")
  12. public class JpaConfig {
  13. }

定义实体类

定义数据库实体基类

为了简化代码,可以将所有数据库实体类共有的属性提取出来,定义一个基础类。

  1. /**
  2. * 数据库实体基类,声明数据库实体类共有属性
  3. */
  4. @Getter
  5. @Setter
  6. @MappedSuperclass
  7. public abstract class BaseEntity implements Serializable {
  8. /**
  9. * ID,唯一标识列,使用主键自增策略
  10. */
  11. @Id
  12. @GeneratedValue(strategy = GenerationType.IDENTITY)
  13. private Long id;
  14. /**
  15. * 创建时间
  16. */
  17. @CreatedDate
  18. private LocalDateTime createdTime;
  19. /**
  20. * 最后修改时间
  21. */
  22. @LastModifiedDate
  23. private LocalDateTime lastModifiedTime;
  24. /**
  25. * 创建人ID
  26. */
  27. private Long creatorId;
  28. /**
  29. * 最后修改人ID
  30. */
  31. private Long lastModifierId;
  32. }
  • @MappedSuperclass,表示一个类是某些实体类的超类,它不会直接映射为数据库表,但是可以被其他实体类继承,它的子类映射的数据库表中会包含它自身声明的属性。
  • @Id,用于声明一个实体类的属性映射为数据库的主键列,一个JPA实体类中必须要有一个使用@Id注解的属性。
  • @GeneratedValue,用于指定主键的生成策略,通过strategy属性来设置。
  • @CreatedDate,表示该字段为创建时间字段,执行insert语句前会自动赋值。
  • @LastModifiedDate,表示该字段为最后修改时间字段,执行insertupdate语句前会自动赋值。

定义用户实体类

用户实体类SysUser中还用到了部门类Department,使用Department主要是为了介绍@Transient注解,本文不再给出其详细代码。它同样继承自BaseEntity,有部门编号(code)部门名称(name)两个属性。

  1. /**
  2. * 用户实体类
  3. */
  4. @Getter
  5. @Setter
  6. @Entity(name = "sys_user")
  7. public class SysUser extends BaseEntity {
  8. /**
  9. * 用户名
  10. */
  11. @Column(unique = true)
  12. private String username;
  13. /**
  14. * 密码
  15. */
  16. private String password;
  17. /**
  18. * 电话
  19. */
  20. private String phone;
  21. /**
  22. * 个人介绍
  23. */
  24. @Lob
  25. private String introduce;
  26. /**
  27. * 所属部门ID
  28. */
  29. private Long departmentId;
  30. /**
  31. * 所属部门
  32. */
  33. @Transient
  34. private Department department;
  35. }
  • @Entity,表示该类是一个实体类,可以映射为数据库表。name属性用于自定义表名,不设置name属性时默认会取类名转化为全小写+下划线分隔的字符串作为表名,比如类名为SysUser则默认映射的表名为sys_user

    在使用了@Entity注解的类中,必须要有一个使用@Id注解修饰的属性。
    在使用了@Entity注解的类中,所有的属性都会被映射为数据库表中的字段,除非属性上使用了@Transient注解。

  • @Column,表示该属性是一个表中的字段,unique = true可以在对应字段上定义唯一约束,在有@Entity注解修饰的类中,属性上不加@Column注解也可以被映射为字段。

  • @Lob,表示该属性需要映射成数据库支持的大对象类型的字段,比如Clob或者Blob

  • @Transient,表示该属性并非一个到数据库表中字段的映射,ORM框架映射时会忽略该属性。

定义Repository接口

JPA中的Repository可以理解为DAO(Data Access Object),即数据操纵对象。一个JPA的实体类需要有一个对应的Repository,用于操作该实体类所映射的数据库表。Repository可以仅仅是一个接口无需创建它的实现类,需要继承JpaRepository<T, ID>接口,T是实体类,ID是实体类中@Id修饰的属性的类型。程序启动时Spring Data JPA会自动生成该接口的实现,并注册为Spring Bean。

JpaRepository中定义了一系列最基本的CURD方法,开发者可以直接使用,也可以根据业务需求自定义查询方法。Spring Data JPA支持多种查询定义方式,主要包括:

  • 基于方法名创建查询,可以根据方法名中的关键词构造出实际的查询SQL,在附录中给出了Spring Data JPA所支持的关键词;
  • 基于@Query注解创建JPQL查询或者原生SQL查询,nativeQuery属性设置为true时表示使用原生SQL
  • 基于Specification构造动态查询,此方式需要Repository继承JpaSpecificationExecutor<T>接口,T是实体类;

以下代码是使用不同方法创建查询的示例,基于Specification的查询方式在下一章节中给出。

  1. /**
  2. * 用户表Repository
  3. */
  4. public interface SysUserRepository extends JpaRepository<SysUser, Long>, JpaSpecificationExecutor<SysUser> {
  5. /**
  6. * 根据username精确查询
  7. */
  8. Optional<SysUser> findByUsername(String username);
  9. @Query("select u from SysUser u where u.username = ?1")
  10. Optional<SysUser> findByUsername2(String username);
  11. }

使用Repository接口

在前文中我们已经定义好了一个用户实体类SysUser和一个用户表的DAO接口SysUserRepository,下面我们就来使用它们完成简单的增删改查操作。以下代码中我们定义了一个服务类接口SysUserService和它的具体实现SysUserServiceImpl

  1. public interface SysUserService {
  2. /**
  3. * 分页查询
  4. */
  5. Page<SysUser> page(Pageable pageable);
  6. /**
  7. * 查询全部用户
  8. */
  9. List<SysUser> list();
  10. /**
  11. * 根据ID查询
  12. */
  13. SysUser retrieve(Long id);
  14. /**
  15. * 根据用户名查询
  16. */
  17. SysUser findByUsername(String username);
  18. /**
  19. * 新增用户
  20. */
  21. SysUser create(SysUser user);
  22. /**
  23. * 修改用户
  24. */
  25. SysUser update(SysUser user);
  26. /**
  27. * 批量删除用户
  28. */
  29. void remove(List<Long> ids);
  30. }
  1. @Service
  2. public class SysUserServiceImpl implements SysUserService {
  3. private final SysUserRepository userRepository;
  4. public SysUserServiceImpl(SysUserRepository userRepository) {
  5. this.userRepository = userRepository;
  6. }
  7. @Override
  8. public Page<SysUser> page(Pageable pageable) {
  9. return userRepository.findAll(pageable);
  10. }
  11. @Override
  12. public List<SysUser> list() {
  13. return userRepository.findAll();
  14. }
  15. @Override
  16. public SysUser retrieve(Long id) {
  17. return userRepository.findById(id).orElse(null);
  18. }
  19. @Override
  20. public SysUser findByUsername(String username) {
  21. // 使用基于方法名定义的查询
  22. return userRepository.findByUsername(username).orElse(null);
  23. // 使用基于@Query定义的查询
  24. // return userRepository.findByUsername2(username).orElse(null);
  25. // 使用Specification查询
  26. // return userRepository.findOne(
  27. // (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("username").as(String.class), username)
  28. // ).orElse(null);
  29. }
  30. @Override
  31. public SysUser create(SysUser user) {
  32. return userRepository.save(user);
  33. }
  34. @Override
  35. public SysUser update(SysUser user) {
  36. if (userRepository.findById(user.getId()).isEmpty()) {
  37. throw new RuntimeException("未查询到数据");
  38. }
  39. return userRepository.save(user);
  40. }
  41. @Override
  42. public void remove(List<Long> ids) {
  43. userRepository.deleteAllById(ids);
  44. }
  45. }

总结

在本文中,我们一起学习了与Spring Data JPA相关的技术简介,学习了如何基于Java21和SpringBoot3整合Spring Data JPA,也学习了JPA Repository的简单使用方法,如有错误,还望批评指正。

在后续实践中我也是及时更新自己的学习心得和经验总结,希望与诸位看官一起进步。

附录

Spring Data JPA 基于方法名创建查询支持的关键词

数据来源:Spring Data JPA 3.2.2官方文档docs.spring.io/spring-data…

关键词 示例 对应的JPQL语句
Distinct findDistinctByLastnameAndFirstname select distinct … where x.lastname = ?1 and x.firstname = ?2
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull, Null findByAge(Is)Null … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstname) = UPPER(?1)

Java21 + SpringBoot3集成Spring Data JPA的更多相关文章

  1. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  2. 集成Spring Data JPA

    1.Spring Data JPA简介 Spring Data是一个用于简化数据访问,并支持云服务的开源框 使用完成Spring Data JPA对user表的CRUD操作. 2.步骤 1.创建工程勾 ...

  3. Spring Boot集成Spring Data Jpa完整实例

    步骤: 添加依赖: 配置文件: 出了数据库的配置,还要配置jpa相关的: 实体类: Dao接口: 定义一个查询的方法,如果是jpa默认就有也可以不写: 测试: 如果报下面的错误,说明jdk9中缺少相关 ...

  4. SpringBoot系列之Spring Data Jpa集成教程

    SpringBoot系列之Spring Data Jpa集成教程 Spring Data Jpa是属于Spring Data的一个子项目,Spring data项目是一款集成了很多数据操作的项目,其下 ...

  5. Spring Boot (五)Spring Data JPA 操作 MySQL 8

    一.Spring Data JPA 介绍 JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Sprin ...

  6. JPA、Hibernate、Spring data jpa之间的关系,终于明白了

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

  7. Spring Boot-JPA、Hibernate、Spring data jpa之间的关系

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

  8. JPA、Hibernate、Spring data jpa之间的关系,以及和springboot的整合

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

  9. JPA、Hibernate、Spring Data JPA 的关系,你懂吗?

    来源:https://my.oschina.net/u/3080373/blog/1828589 什么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表 ...

  10. JPA、Hibernate、Spring data jpa之间的关系

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

随机推荐

  1. awk所有常用语法

    awk [OPTIONS] PROGRAM FILE... 选项: -F 指定分隔符 -f 引用awk脚本 -v VAR=VALUE 定义一个变量传递给PROGRAM,但是这里的变量BEGIN读不了, ...

  2. el-table 设置合并行或列时,显示错乱问题

    1. 需求效果图: 2. 接口数据格式: 点击查看代码 const list = [ { contractNo: "CAI-20220801001", contractItem: ...

  3. 通过 KernelUtil.dll 劫持 QQ / TIM 客户端 QQClientkey / QQKey 详细教程(附源码)

    前言 由于 QQ 9.7.20 版本后已经不能通过模拟网页快捷登录来截取 QQClientkey / QQKey,估计是针对访问的程序做了限制,然而经过多方面测试,诸多的地区.环境.机器也针对这种获取 ...

  4. SHA加密解密

    一.概述 SHA(Secure Hash Algorithm,安全哈希算法)是一类广泛应用于加密领域的算法,主要用于数据完整性校验和加密认证.SHA算法首次出现在1993年,由美国国家安全局(NSA) ...

  5. MongoDB经典故障系列六:CPU利用率太高怎么办?

    每逢电商大促,全民狂欢,但热闹是属于疯狂剁手的人们.而开发者们有的缺是"高流量.高访问.高并发"三高下带来的种种问题.为了应对大促期间的高I/O情况,企业会选择MongoDB云数据 ...

  6. RT-DETR:可以满足实时性要求的DETR模型

    本文分享自华为云社区<高性能网络设计秘笈:深入剖析Linux网络IO与epoll>,作者: Lion Long . 一.epoll简介 epoll是Linux内核中一种可扩展的IO事件处理 ...

  7. 使用appuploader工具发布证书和描述性文件教程

    使用APPuploader工具发布证书和描述性文件教程 之前用AppCan平台开发了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到App Store试试,于是找同学借了个苹果开发者账号 ...

  8. 如何使用appuploader制作描述文件​

    如何使用appuploader制作描述文件​ 承接上文我们讲述了怎么制作证书,本文我们来看下怎么制作描述文件吧.​制作描述文件前我们首先我们来添加一个测试设备,后面再制作描述文件. 1.添加测试设备​ ...

  9. 网页“悼念模式”全站变灰/黑白色CSS代码

    <style> html { filter:grayscale(100%); -webkit-filter:grayscale(100%); -moz-filter:grayscale(1 ...

  10. 解密Prompt系列1. Tunning-Free Prompt:GPT2 & GPT3 & LAMA & AutoPrompt

    借着ChatGPT的东风,我们来梳理下prompt范式的相关模型.本系列会以A Systematic Survey of Prompting Methods in Natural Language P ...