Java学习手册:Hibernate/JPA 使用指南

Hibernate/JPA 使用指南

一、Hibernate 和 JPA 的核心概念

  • 实体(Entity) :实体是 JPA 中用于表示数据库表的 Java 对象。通过在实体类上添加 @Entity 注解,JPA 可以将实体类映射到数据库表。例如,定义一个 User 实体类:
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "username")private String username;@Column(name = "password")private String password;// 省略 getter 和 setter 方法
}
  • 持久化上下文(Persistence Context) :持久化上下文是 JPA 中用于管理实体对象的容器。它通过实体管理器(EntityManager)来管理实体的生命周期,包括实体的创建、读取、更新和删除操作。
  • EntityManager :是 JPA 中用于操作实体的核心接口。通过 EntityManager,开发者可以执行查询、插入、更新和删除操作。例如:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;public class UserDao {private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");private EntityManager entityManager = entityManagerFactory.createEntityManager();public User findUser(Long id) {return entityManager.find(User.class, id);}public void saveUser(User user) {entityManager.getTransaction().begin();entityManager.persist(user);entityManager.getTransaction().commit();}
}
  • 事务管理(Transaction Management) :JPA 中的事务管理通过 EntityTransaction 接口实现。事务管理确保数据库操作的原子性、一致性、隔离性和持久性。在上述代码示例中,通过 entityManager.getTransaction() 获取事务对象,并调用其 begin()commit() 方法来控制事务的开始和提交。

二、Hibernate 和 JPA 的配置与初始化

  • 配置文件 :在使用 Hibernate 实现 JPA 时,通常会涉及到以下几个主要的配置文件:
    • hibernate.cfg.xml :这是 Hibernate 的主要配置文件,负责定义会话工厂的相关配置,包括数据库连接信息、方言、事务类型等。以下是一个示例配置:
<hibernate-configuration><session-factory><property name="connection.driver_class">org.h2.Driver</property><property name="connection.url">jdbc:h2:mem:test</property><property name="connection.username">sa</property><property name="connection.password"></property><property name="dialect">org.hibernate.dialect.H2Dialect</property><property name="show_sql">true</property><property name="hbm2ddl.auto">update</property><property name="hibernate.c3p0.max_size">10</property><property name="hibernate.c3p0.min_size">1</property><property name="hibernate.c3p0.timeout">1800</property><property name="hibernate.c3p0.max_statements">50</property></session-factory>
</hibernate-configuration>
* **`persistence.xml`** :作为 JPA 规范的一部分,此文件定义了持久化单元的信息,包括 JPA 提供者、实体类列表、数据库连接池等。以下是一个示例配置:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"version="2.0"><persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL"><class>com.example.model.User</class><properties><property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/><property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC"/><property name="javax.persistence.jdbc.user" value="root"/><property name="javax.persistence.jdbc.password" value="password"/><property name="hibernate.hbm2ddl.auto" value="update"/><property name="hibernate.show_sql" value="true"/></properties></persistence-unit>
</persistence>
  • 初始化 EntityManagerFactory :通过配置文件或代码方式创建 EntityManagerFactory。以下是一个基于 Spring 的配置示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
import java.util.Properties;@Configuration
public class JpaConfig {@Autowiredprivate DataSource dataSource;@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {LocalContainerEntityManagerFactoryBean emFactory = new LocalContainerEntityManagerFactoryBean();emFactory.setDataSource(dataSource);emFactory.setPackagesToScan("com.example.model");emFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());Properties jpaProperties = new Properties();jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");jpaProperties.setProperty("hibernate.show_sql", "true");emFactory.setJpaProperties(jpaProperties);return emFactory;}
}

三、基本操作

  • 查询操作 :可以通过 EntityManager 的 find() 方法根据主键查询实体对象,也可以使用 JPQL 进行复杂查询。例如:
// 根据主键查询
User user = entityManager.find(User.class, 1L);// 使用 JPQL 查询
String jpql = "SELECT u FROM User u WHERE u.username = :username";
List<User> users = entityManager.createQuery(jpql, User.class).setParameter("username", "john_doe").getResultList();
  • 插入操作 :使用 EntityManager 的 persist() 方法将实体对象持久化到数据库。例如:
User newUser = new User();
newUser.setUsername("john_doe");
newUser.setPassword("password123");
entityManager.getTransaction().begin();
entityManager.persist(newUser);
entityManager.getTransaction().commit();
  • 更新操作 :从数据库中查询出实体对象后,修改其属性值,然后调用 merge() 方法将修改后的对象合并到持久化上下文中。例如:
User user = entityManager.find(User.class, 1L);
user.setUsername("john_doe_updated");
user = entityManager.merge(user);
  • 删除操作 :使用 EntityManager 的 remove() 方法从数据库中删除实体对象。例如:
User user = entityManager.find(User.class, 1L);
entityManager.getTransaction().begin();entityManager.remove(user);entityManager.getTransaction().commit();

四、事务管理

在 JPA 中,事务管理通过 EntityTransaction 接口实现。以下是一个完整的事务管理示例:

EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();try {transaction.begin();// 执行数据库操作User user = new User();user.setUsername("john_doe");user.setPassword("password123");entityManager.persist(user);transaction.commit();
} catch (Exception e) {if (transaction.isActive()) {transaction.rollback();}
} finally {entityManager.close();
}

五、对象关系映射

  • 一对一映射 :例如,一个用户对应一个详细信息:
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)private UserInfo userInfo;// 省略 getter 和 setter 方法
}@Entity
public class UserInfo {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String email;private String phone;@OneToOne@JoinColumn(name = "user_id")private User user;// 省略 getter 和 setter 方法
}
  • 一对多映射 :例如,一个部门对应多个员工:
@Entity
public class Department {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)private List<Employee> employees = new ArrayList<>();// 省略 getter 和 setter 方法
}@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@ManyToOne@JoinColumn(name = "department_id")private Department department;// 省略 getter 和 setter 方法
}
  • 多对多映射 :例如,用户和角色之间的多对多关系:
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@ManyToMany(mappedBy = "users")private List<Role> roles = new ArrayList<>();// 省略 getter 和 setter 方法
}@Entity
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String roleName;@ManyToMany@JoinTable(name = "user_role",joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "user_id"))private List<User> users = new ArrayList<>();// 省略 getter 和 setter 方法
}

六、性能优化

  • 缓存策略 :Hibernate 提供了一级缓存和二级缓存。一级缓存是 Session 级别的缓存,二级缓存是 SessionFactory 级别的缓存。可以通过配置启用二级缓存,如使用 EHCache:
<cache usage="read-write" region="user-region"/>
  • 批量操作 :对于大数据量的插入、更新和删除操作,可以使用批量操作来提高性能。例如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hql = "UPDATE Employee SET salary = :salary WHERE department_id IN (:departmentIds)";
Query query = session.createQuery(hql);
query.setParameter("salary", 5000);
query.setParameterList("departmentIds", Arrays.asList(1, 2, 3));
int updatedCount = query.executeUpdate();
tx.commit();
session.close();

七、与 Spring 框架的集成

  • 引入依赖 :在 Spring Boot 项目的 pom.xml 文件中添加 Spring Data JPA 和数据库驱动的依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
  • 配置文件 :在 application.properties 文件中配置数据库连接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
  • Repository 接口 :创建一个 Repository 接口,继承 JpaRepository 接口以获得基本的 CRUD 功能:
import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {
}
  • Service 层 :创建一个 Service 类,使用 @Transactional 注解管理事务,并通过 @Autowired 注入 UserRepository
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic User saveUser(User user) {return userRepository.save(user);}public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}
}
  • Controller 层 :创建一个 Controller 类,通过 @Autowired 注入 UserService,并定义 RESTful API 接口:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@PostMappingpublic User createUser(@RequestBody User user) {return userService.saveUser(user);}@GetMapping("/{id}")public User getUser(@PathVariable Long id) {return userService.getUserById(id);}
}

八、总结

Hibernate 是 JPA 的一个实现,它提供了丰富的功能和灵活的配置选项。通过合理配置 Hibernate 和 JPA,可以实现高效的数据库操作,提高开发效率和代码质量。在实际项目中,结合 Spring 框架可以进一步简化开发过程,提高应用的可维护性和可扩展性。

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

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

相关文章

字符串匹配 之 拓展 KMP算法(Z算法)

文章目录 习题2223.构造字符串的总得分和3031.将单词恢复初始状态所需的最短时间 II 灵神代码模版 区别与KMP算法 KMP算法可用于求解在线性时间复杂度0(n)内求解模式串p在主串s中匹配的未知当然&#xff0c;由于在KMP算法中&#xff0c;预处理求解出了next数组&#xff0c;也就…

安全为上,在系统威胁建模中使用量化分析

*注&#xff1a;Open FAIR™ 知识体系是一种开放和独立的信息风险分析方法。它为理解、分析和度量信息风险提供了分类和方法。Open FAIR作为领先的风险分析方法论&#xff0c;已得到越来越多的大型组织认可。 在数字化风险与日俱增的今天&#xff0c;企业安全决策正面临双重挑战…

游戏引擎学习第259天:OpenGL和软件渲染器清理

回顾并为今天的内容做好铺垫 今天&#xff0c;我们将对游戏的分析器进行升级。在之前的修复中&#xff0c;我们解决了分析器的一些敏感问题&#xff0c;例如它无法跨代码重新加载进行分析&#xff0c;以及一些复杂的小问题。现在&#xff0c;我们的分析器看起来已经很稳定了。…

讯睿CMS模版常用标签参数汇总

一、模板调用标签 1、首页 网站名称&#xff1a;{SITE_NAME} 标题&#xff1a;{$meta_title}&#xff08;列表页通用&#xff09; Keywords&#xff1a;{$meta_keywords} Description&#xff1a;{$meta_description}2、列表页 迅睿cms调用本栏目基础信息标签代码 当前栏目…

【C#】Buffer.BlockCopy的使用

Buffer.BlockCopy 是 C# 中的一个方法&#xff0c;用于在数组之间高效地复制字节块。它主要用于操作字节数组&#xff08;byte[]&#xff09;&#xff0c;但也可以用于其他类型的数组&#xff0c;因为它直接基于内存操作。 以下是关于 Buffer.BlockCopy 的详细说明和使用示例&…

记一次pdf转Word的技术经历

一、发现问题 前几天在打开一个pdf文件时&#xff0c;遇到了一些问题&#xff0c;在Win10下使用WPS PDF、万兴PDF、Adobe Acrobat、Chrome浏览器打开都是正常显示的&#xff1b;但是在macOS 10.13中使用系统自带的预览程序和Chrome浏览器&#xff08;由于macOS版本比较老了&am…

在Laravel 12中实现4A日志审计

以下是在Laravel 12中实现4A&#xff08;认证、授权、账户管理、审计&#xff09;日志审计并将日志存储到MongoDB的完整方案&#xff08;包含性能优化和安全增强措施&#xff09;&#xff1a; 一、环境配置 安装MongoDB扩展包 composer require jenssegers/mongodb配置.env …

链表高级操作与算法

链表是数据结构中的基础&#xff0c;但也是面试和实际开发中的重点考察对象。今天我们将深入探讨链表的高级操作和常见算法&#xff0c;让你能够轻松应对各种链表问题。 1. 链表翻转 - 最经典的链表问题 链表翻转是面试中的常见题目&#xff0c;也是理解链表指针操作的绝佳练…

架构思维:构建高并发读服务_使用懒加载架构实现高性能读服务

文章目录 一、引言二、读服务的功能性需求三、两大基本设计原则1. 架构尽量不要分层2. 代码尽可能简单 四、实战方案&#xff1a;懒加载架构及其四大挑战五、改进思路六、总结与思考题 一、引言 在任何后台系统设计中&#xff0c;「读多写少」的业务场景占据主流&#xff1a;浏…

在运行 Hadoop 作业时,遇到“No such file or directory”,如何在windows里打包在虚拟机里运行

最近在学习Hadoop集群map reduce分布运算过程中&#xff0c;经多方面排查可能是电脑本身配置的原因导致每次运行都会报“No such file or directory”的错误&#xff0c;最后我是通过打包文件到虚拟机里运行得到结果&#xff0c;具体步骤如下&#xff1a; 前提是要保证maven已经…

软考-软件设计师中级备考 11、计算机网络

1、计算机网络的分类 按分布范围分类 局域网&#xff08;LAN&#xff09;&#xff1a;覆盖范围通常在几百米到几千米以内&#xff0c;一般用于连接一个建筑物内或一个园区内的计算机设备&#xff0c;如学校的校园网、企业的办公楼网络等。其特点是传输速率高、延迟低、误码率低…

【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&#…

当LLM遇上Agent:AI三大流派的“复仇者联盟”

你一定听说过ChatGPT和DeepSeek&#xff0c;也知道它们背后的LLM&#xff08;大语言模型&#xff09;有多牛——能写诗、写代码、甚至假装人类。但如果你以为这就是AI的极限&#xff0c;那你就too young too simple了&#xff01; 最近&#xff0c;**Agent&#xff08;智能体&a…

Spring Boot多模块划分设计

在Spring Boot多模块项目中&#xff0c;模块划分主要有两种思路&#xff1a;​​技术分层划分​​和​​业务功能划分​​。两种方式各有优缺点&#xff0c;需要根据项目规模、团队结构和业务特点来选择。 ​​1. 技术分层划分&#xff08;横向拆分&#xff09;​​ 结构示例&…

两次解析格式化字符串 + 使用SQLAlchemy的relationship执行任意命令 -- link-shortener b01lersCTF 2025

题目描述: A fast and reliable link shortener service, with a new feature to add private links! 我们走一遍逻辑 注册 app.route("/register", methods[GET, POST]) def register(): """ 用户注册路由&#xff0c;处理用户注册请求&#xff…

后端id类型为long类型时,返回给前端浏览器四舍五入,导致id精度缺失问题

背景 今天在代码里&#xff0c;掉了别人写的接口&#xff0c;有个id的字段是long类型的&#xff0c;我这边加点参数返回给前端&#xff0c;然后前端根据id修改&#xff0c;结果修改的数据记录有&#xff0c;但是没起作用&#xff0c;后来发现根据他传给我的id在后台数据库查不…

Scartch038(四季变换)

知识回顾 1.了解和简单使用音乐和视频侦测模块 2.使用克隆体做出波纹特效 3.取色器妙用侦测背景颜色 前言 我国幅员辽阔,不同地方的四季会有不同的美丽景色,这节课我带你使用程序做一个体现北方四季变化的程序 之前的程序基本都是好玩的,这节课做一个能够赏心悦目的程序。…

JVM happens-before 原则有哪些?

理解Java Memory Model (JMM) 中的 happens-before 原则对于编写并发程序有很大帮助。 Happens-before 关系是 JMM 用来描述两个操作之间的内存可见性以及执行顺序的抽象概念。如果一个操作 A happens-before 另一个操作 B (记作 A hb B)&#xff0c;那么 JMM 向你保证&#x…

从 Eclipse Papyrus / XText 转向.NET —— SCADE MBD技术的演化

从KPN[1]的萌芽开始&#xff0c;到SCADE的推出[2]&#xff0c;再到Scade 6的技术更迭[3]&#xff0c;SCADE 基于模型的开发技术已经历许多。现在&#xff0c;Scade One 已开启全新的探索 —— 从 Eclipse Papyrus / XText 转向.NET 8跨平台应用。 [1]: KPN, Kahn进程网络 (197…

osquery在网络安全入侵场景中的应用实战(二)

背景 上次写了osquery在网络安全入侵场景中的应用实战(一)结果还不错,这次篇目二再增加一些场景。osquery主要解决的时员工被入侵之后电脑该如何溯源取证的问题。通常EDR会有日志,但是不会上报全量的日志。发现机器有恶意文件需要上级取证的时候,往往是比较麻烦的,会有这…