JPA之Hibernate

JPA


定义:是 JavaEE 中一组用于持久化数据的 API,它提供了一种标准的 ORM 规范,用于 Java 对象映射到数据库中。
JPA 的开发是为了简化企业级应用程序的开发,降低应用程序与数据库之间的耦合度,并提高应用程序的可维护性和可扩展性。
JPA 定义了一系列注解和接口,用于描述 Java 对象与数据库表之间的映射关系。其中,最重要的是实体类(Entity)和实体管理器(EntityManager)。

注意:JPA 只是一种规范,具体的实现由不同的厂商提供,比如 Hibernate、EclipseLink 等。因此,在使用 JPA 时,需要选择一个合适的实现,并按照其提供的文档进行配置和使用。

Interview & Answer

什么是 JPA?它的作用是什么?

JPA(Java Persistence API)是 JavaEE 中一组用于持久化数据的 API,它提供了一种标准的 ORM(对象关系映射)规范,用于将 Java 对象映射到关系型数据库中。JPA 的作用是简化企业级应用程序的开发,降低应用程序与数据库之间的耦合度,并提高应用程序的可维护性和可扩展性。

JPA 中的实体类是什么?如何定义实体类?

实体类是一个普通的 Java 类,用于表示数据库中的一张表。在实体类中,使用注解来描述类与表之间的映射关系,比如 @Entity、@Table、@Id 等。实体类通常包含一组属性(属性对应表中的列),以及一些方法(用于操作这些属性)。

JPA 提供了哪些 API 接口?分别有什么作用?

JPA 提供了一些 API 接口,包括 EntityManager、EntityTransaction、Query 等,这些接口可以用来操作 Java 对象和数据库之间的映射关系。EntityManager 用于管理实体对象,EntityTransaction 用于管理事务,Query 用于执行查询操作。

JPA 中的实体管理器是什么?如何使用它来操作实体对象?

实体管理器是用于管理实体对象的类,它提供了一系列方法,用于对实体对象进行增删改查等操作。在 JPA 中,实体管理器是通过 EntityManagerFactory 创建的,每个应用程序通常只需要一个 EntityManagerFactory 实例,但可以创建多个 EntityManager 实例。可以通过调用 EntityManager 的方法来对实体对象进行操作,比如 persist、remove、merge、find 等方法。

JPA 中的注解有哪些?它们的作用是什么?

JPA 中的注解包括 @Entity、@Table、@Id、@Column 等,用于描述 Java 对象与数据库表之间的映射关系。其中,@Entity 用于指定一个 Java 类为实体类,@Table 用于指定实体类对应的数据库表,@Id 用于指定实体类属性为主键,@Column 用于指定实体类属性与数据库表列之间的映射关系。

JPA 中的事务管理是如何实现的?如何配置事务管理器?

JPA 中的事务管理可以通过实体管理器的 getTransaction 方法来获取一个 EntityTransaction 实例,然后调用其 begin、commit、rollback 等方法来管理事务。在 Spring 框架中,可以使用 @Transactional 注解来配置事务管理器,通过在方法或类上添加该注解来实现事务管理。

JPA 中的缓存机制是如何实现的?什么是一级缓存和二级缓存?

JPA 中的缓存机制包括一级缓存和二级缓存。一级缓存是指实体管理器与数据库之间的缓存,它是默认开启的,可以通过 EntityManager 的 clear、refresh 等方法来操作。二级缓存是指在多个实体管理器之间共享的缓存,它需要通过配置文件来启用,并且需要使用 JPA 提供商提供的缓存实现。二级缓存可以减少数据库访问次数,提高应用程序的性能。

JPA 中的 JPQL 是什么?如何使用 JPQL 进行查询操作?

JPQL(Java Persistence Query Language)是一种面向对象的查询语言,用于查询实体对象。JPQL 与 SQL 语句类似,但是它是面向对象的,可以直接引用实体类和实体类属性。JPQL 可以使用 EntityManager 的 createQuery 方法来创建查询对象,然后使用查询对象的 setParameters、getResultList 等方法来执行查询操作。

JPA 的实现有哪些?它们之间有什么区别?

JPA 的实现有很多,比较常见的有 Hibernate、EclipseLink、OpenJPA 等。这些实现都遵循 JPA 规范,但是在实现上有些许差异,比如性能、功能、稳定性等方面。开发人员可以根据自己的需求选择合适的实现。

JPA 和 Hibernate 之间有什么关系?它们之间有什么区别?

JPA 是一种规范,而 Hibernate 是实现了 JPA 规范的 ORM 框架。Hibernate 可以看作是 JPA 的一种实现,它实现了 JPA 规范,并提供了一些 JPA 规范之外的功能,比如缓存、批量操作、动态查询等。但是,使用 Hibernate 并不一定要遵循 JPA 规范,开发人员可以直接使用 Hibernate 提供的 API 来操作数据库。

JPA 实现方式及缓存默认状态

        JPA规范并没有指定一级和二级缓存的默认状态,这取决于具体的JPA实现和配置。下面是常见的JPA实现的默认缓存状态:

  • Hibernate:Hibernate是一个常用的JPA实现,它的一级缓存(Session级别的缓存)默认是开启的,而二级缓存(应用程序级别的缓存)默认是关闭的。可以通过配置文件或者代码的方式来开启或关闭二级缓存。

  • EclipseLink:EclipseLink是另一个常用的JPA实现,它的一级缓存(EntityManager级别的缓存)默认是开启的,而二级缓存(应用程序级别的缓存)默认是关闭的。可以通过配置文件或者代码的方式来开启或关闭二级缓存。

  • OpenJPA:OpenJPA是另一个流行的JPA实现,它的一级缓存(EntityManager级别的缓存)默认是开启的,而二级缓存(应用程序级别的缓存)默认是关闭的。可以通过配置文件或者代码的方式来开启或关闭二级缓存。

如何理解都默认开一级缓存

        有点类似都在一个事务中,这要求可重复读等,所以都要开启

JPA 注解使用 demo

    // 查询@Query(value = "SELECT * FROM user WHERE name = :name", nativeQuery = true)List<User> findByName(@Param("name") String name);// 修改@Modifying@Query(value = "UPDATE user SET age = :age WHERE id = :id", nativeQuery = true)void updateAgeById(@Param("id") Long id, @Param("age") Integer age);// 删除@Modifying@Query(value = "DELETE FROM user WHERE id = :id", nativeQuery = true)void deleteById(@Param("id") Long id);// list 入参@Query("SELECT u FROM User u WHERE u.name IN :names")List<User> findByNames(@Param("names") List<String> names);// map 入参// 在这个示例中,我们定义了一个自定义查询方法findByCondition,使用@Query注解指定了JPQL查询语句。查询语句中使用了实体类User和其属性name、age,使用AND关键字指定查找name属性等于condition中的"name"键对应的值,age属性大于等于condition中的"minAge"键对应的值的用户信息// 使用Map作为查询条件时,需要注意的是,Map中的键必须与JPQL查询语句中的参数名一致,否则会抛出异常。@Query("SELECT u FROM User u WHERE u.name = :name AND u.age >= :minAge")List<User> findByCondition(@Param("condition") Map<String, Object> condition);// 复杂对象入参// @Query("SELECT u FROM User u WHERE u.name = :#{#query.name} AND u.age >= :#{#query.minAge}")//    List<User> findByCondition(@Param("query") UserQuery query);////public class UserQuery {//    private String name;//    private Integer minAge;//    // 省略getter和setter方法//}// 联表查询// @Query("SELECT o FROM Order o JOIN o.user u WHERE u.name = :name")//    List<Order> findByUserName(@Param("name") String name);// null 不更新@Query("UPDATE TP_USER_ACTIVITY_LOG \n" +"SET IF :name IS NOT NULL THEN name = :name END IF\n" +",age = :age\n" +"WHERE LOG_DATE = :logDate")Integer updateTest(@Param("name") String name, @Param("age") String age, @Param("logDate") Date logDate);// 关键在于数据库if 语句使用,不同数据库if的用法有所不同,所以,没有通用性// where 条件 为 null //  如果为空时显示1=1 代表参数为真,对查询结果不产生作用。// "WHERE IF (:byname is not null, c.byname LIKE CONCAT('%',:byname,'%') , 1 = 1) and IF (:isMember is not null, c.is_member = :isMember , 1 = 1) and IF (:isBlacklist is not null, c.is_blacklist = :isBlacklist , 1 = 1) and "// + "IF (:phone is not null, c.phone = :phone , 1 = 1)"

Hibernate


Hibernate 一级缓存

Hibernate 的一级缓存是 Session 级别的缓存,它默认是开启的,并且通常是不建议关闭的。但是,在某些特定的场景下,关闭一级缓存可能是有必要的,例如:

  • 当需要强制刷新缓存,以避免缓存数据和数据库数据不一致时,可以考虑关闭一级缓存。
  • 当需要避免缓存数据的过期或者内存溢出时,可以考虑关闭一级缓存。
  • 当需要测试或者调试缓存相关的问题时,可以考虑关闭一级缓存。

关闭 Hibernate 的一级缓存有以下两种方式:

① 在 Session 中调用 clear() 方法:通过 Session 的 clear() 方法可以清空一级缓存中的所有数据。例如:

    Session session = sessionFactory.openSession();session.beginTransaction();// 这里执行数据库操作,将数据写入数据库session.clear(); // 清空一级缓存// 这里再次执行数据库操作,从数据库中读取最新的数据

② 在 Hibernate 配置文件中设置缓存策略:通过在 Hibernate 配置文件(如 hibernate.cfg.xml)中设置缓存策略可以关闭一级缓存。例如:

<hibernate-configuration>
<session-factory><!-- ... --><property name="hibernate.cache.use_second_level_cache">false</property><property name="hibernate.cache.use_query_cache">false</property><!-- ... --></session-factory>
</hibernate-configuration>

在上述配置中,将 hibernate.cache.use_second_level_cache 和 hibernate.cache.use_query_cache 都设置为 false,可以关闭一级缓存和查询缓存。

注意:关闭一级缓存可能会导致性能下降和数据不一致等问题,因此在实际应用中需要慎重考虑是否关闭一级缓存。

Hibernate 一级缓存过期

        Hibernate 的一级缓存是 Session 级别的缓存,它存储的是 Session 中查询的实体对象。一级缓存的过期时间是根据缓存中的对象状态和 Session 的状态来判断的。一级缓存的过期包括以下几种情况:

  • 对象状态为持久化状态:当Session中的实体对象状态为持久化状态时,即该对象已经被保存到数据库中并且与数据库中的数据保持一致,那么该对象会一直保留在一级缓存中,直到Session关闭或者显式地从缓存中清除。

  • 对象状态为游离状态:当Session中的实体对象状态为游离状态时,即该对象已经被从Session中分离出来,与数据库中的数据不再保持一致,那么该对象会失效并从一级缓存中移除。

  • 对象状态为脱管状态:当Session中的实体对象状态为脱管状态时,即该对象已经被Session关闭或者从Session中分离出来,那么该对象会失效并从一级缓存中移除。

注意:一级缓存中的对象生命周期与 Session 的生命周期相关联。当 Session 关闭时,所有在一级缓存中的对象都会失效并从缓存中移除。因此,在使用 Hibernate 的过程中,需要根据具体的业务需求和场景来管理缓存,以避免数据的不一致和缓存的内存溢出等问题。

分布式 Hibernate 二级缓存一致性

        在分布式系统中,由于存在多个应用程序实例和多个数据库实例,使用Hibernate的二级缓存可能会导致数据的不一致性问题。为了保持Hibernate的二级缓存一致性,可以采用以下几种方法:

  • 配置缓存同步策略:通过配置缓存同步策略,可以保证多个应用程序实例之间的缓存数据一致性。例如,可以使用JGroups、ZooKeeper等工具来实现缓存同步和协调。

  • 配置缓存失效策略:通过配置缓存失效策略,可以及时使缓存数据失效,避免缓存数据和数据库数据不一致。例如,可以使用时间戳、版本号等方式来实现缓存数据的失效和更新。

  • 选择合适的二级缓存实现:不同的二级缓存实现具有不同的特点和优缺点,需要根据具体的业务需求和场景来选择合适的缓存实现。例如,Ehcache、Redis等缓存工具都是常用的二级缓存实现,它们都具有不同的特点和适用场景。

  • 避免缓存数据过期:在使用Hibernate的二级缓存时,需要注意缓存数据的过期时间,避免缓存数据过期导致数据不一致。需要根据具体的业务需求和场景来设置缓存数据的过期时间,以保证数据的一致性和有效性。

注意:保持 Hibernate 的二级缓存一致性是一个复杂的问题,需要综合考虑多个因素和技术手段。在实际应用中,需要根据具体的业务需求和场景来选择合适的缓存策略和技术,以保证系统的性能和可靠性。

Springboot 接入 Hibernate

  1. maven 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>${hibernate.version}</version>
</dependency>
  1. yaml 配置
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
  1. 创建 Entity
@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "name")private String name;@Column(name = "age")private int age;// getters and setters
}
  1. 创建 Repository
public interface UserRepository extends JpaRepository<User, Long> {List<User> findByName(String name);
}
  1. 调用
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public List<User> findByName(String name) {return userRepository.findByName(name);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13349.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Vuvuzela 声音去噪算法】基于流行的频谱减法技术的声音去噪算法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

WEB:unseping

背景知识 php序列化和反序列化 命令执行绕过方式 题目 进行代码审计 可知为反序列化 整体是创建case类&#xff0c;可接受post传来的ctf值 _consturuct函数,是在函数调动前启用&#xff0c;构造了$method和$args两个变量。 _dexstruct函数在变量摧毁的时使用&#xff0c;所…

【嵌入式学习笔记】嵌入式基础10——STM32时钟配置

1.认识时钟树 简单来说&#xff0c;时钟是具有周期性的脉冲信号&#xff0c;最常用的是占空比50%的方波 1.1.F1的时钟树 1.2.F4的时钟树(407为例) 1.3.F7的时钟树 1.4.H7的时钟树 2.配置系统时钟(F1为例) 2.1.系统时钟配置步骤 配置HSE VALUE&#xff1a;告诉HAL库外部晶振…

2021 年高教社杯全国大学生数学建模竞赛 E 题 中药材的鉴别 第一题

目录 1.数据预处理 1.1 数据基本信息探索 1.2 数据可视化 1.3 异常值处理 2. 数据特征值提取 2.1 数据标准化 2.2 PCA提取特征值 3. 数据聚类鉴别药材种类 3.1 肘部图确定K值 3.2 轮廓系数图确定K值 3.3 数据聚类 3.4 聚类结果可视化 4. 研究不同种类药材…

vue-element-plus-admin框架的tag上下文切换bug

问题 首先贴上该框架的链接&#xff1a;https://github.com/kailong321200875/vue-element-plus-admin 在对路由进行部分修改后&#xff0c;网站多次切换tag时&#xff0c;控制台会出现报错&#xff1a;Cannot read properties of undefined (reading offsetLeft)。 我在框架…

SQL基础培训24-存储过程详解

1.存储过程的概念与语法 1.1.概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句的集合。 1.2.语法 创建测试表: create table student <

jdk11环境 提示“因为 accessExternalDTD 属性设置的限制导致不允许 ‘http‘ 访问“bug

在运行mybatis源码的时候&#xff0c;提示一下错误&#xff1a; Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### Cause: org.apache.ibatis.builder.BuilderException: Error creating docum…

CentOS下 Docker、Docker Compose 的安装教程

Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 Docker Compose是用于定义…

C语言基础入门详解一

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 初识C语言 //#include 相当于java的import,stdio全称&#xff1a;st…

PostMan+Jmeter+QTP工具介绍及安装

目录 一、PostMan介绍​编辑 二、下载安装 三、Postman与Jmeter的区别 一、开发语言区别&#xff1a; 二、使用范围区别&#xff1a; 三、使用区别&#xff1a; 四、Jmeter安装 附一个详细的Jmeter按照新手使用教程&#xff0c;感谢作者&#xff0c;亲测有效。 五、Jme…

微信读书:长期投资(阅读摘录)

微信读书&#xff1a;长期投资&#xff08;阅读摘录&#xff09; 所有投资高手的时间精力都投向了这三大块&#xff1a;行动、思考、读书。 我们把耐心发挥到了极致&#xff0c;这正是价值投资的关键特征之一。 通常在牛市中想要跑赢大盘&#xff0c;难度非常大。 实际上&am…

深度剖析C++ 异常机制

传统排错 我们早在 C 程序里面传统的错误处理手段有&#xff1a; 终止程序&#xff0c;如 assert&#xff1b;缺陷是用户难以接受&#xff0c;说白了就是一种及其粗暴的手法&#xff0c;比如发生内存错误&#xff0c;除0错误时就会终止程序。 返回错误码。缺陷是需要我们自己…

java接口实现

文章目录 java接口实现接口中成员组成默认方法静态方法私有接口&#xff08;保证自己的JDK版本大于等于9版本&#xff09;类和接口的关系抽象类与接口之间的区别 java接口实现 1.接口关键字 interface2.接口不能实例化3.类与接口之间的关系是实现关系&#xff0c;通过 impleme…

职场中是否存在公平

不管是人还是动物&#xff0c;只要有思考的物体&#xff0c;不可避免就会面临公平的问题。 好比一头雄狮&#xff0c;它也纳闷&#xff0c;为啥老子吼缺氧的四嗓子都换不回母狮的回眸&#xff0c;而另一头搓B&#xff0c;只哼哼两声&#xff0c;母狮就过去了&#xff0c;尼玛真…

C++11类模板

类模板是用来生成类的蓝图&#xff0c;与函数模板的不同之处是&#xff0c;编译器不能为类模板推断模板参数类型。 所以我们在使用类的时候要带上<>并且指定类型如下 vector<int> v; // 需要带上<int> 哦定义类模板 如下&#xff0c;和函数模板差不多都是…

【Docker consul的容器服务更新与发现】

文章目录 一、Consul 的简介&#xff08;1&#xff09;什么是服务注册与发现&#xff08;2&#xff09;什么是consul 二、consul 部署1、consul服务器1. 建立 Consul 服务2. 查看集群信息3. 通过 http api 获取集群信息 2、registrator服务器1. 安装 Gliderlabs/Registrator2. …

Generative Diffusion Prior for Unified Image Restoration and Enhancement 论文阅读笔记

这是CVPR2023的一篇用diffusion先验做图像修复和图像增强的论文 之前有一篇工作做了diffusion先验&#xff08;Bahjat Kawar, Michael Elad, Stefano Ermon, and Jiaming Song, “Denoising diffusion restoration models,” arXiv preprint arXiv:2201.11793, 2022. 2, 4, 6,…

linux 查看网卡,网络情况

1&#xff0c;使用nload命令查看 #yum -y install nload 2&#xff0c; 查看eth0网卡网络情况 #nload eth0 Incoming也就是进入网卡的流量&#xff0c;Outgoing&#xff0c;也就是从这块网卡出去的流量&#xff0c;每一部分都有下面几个。 – Curr&#xff1a;当前流量 – Avg…

面试题模拟

C# 装箱和拆箱是什么&#xff1f; 装箱是指用堆空间来存放值类型数据 拆箱是指将存放在堆空间的值类型数据转换到栈空间 值和引用类型在变量赋值时的区别是什么&#xff1f; 值类型的数据赋值的时候是指向同一块内存区域&#xff0c;当前一个改变的时候后一个也会跟着改变。 引…

数据库—数据库备份(三十四)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 二、数据备份的重要性 三、造成数据丢失的原因 四、备份类型 4.1物理与逻辑角度 4.2数据库备份策略角度 五、常见的备份方法 5.1 物理备份 5.2 使用专用备…