跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Hibernate 框架超详细说明

Hibernate 框架超详细说明 1. Hibernate 框架概述 ORM 框架 :对象关系映射(Object-Relational Mapping) JPA 实现 :Java Persistence API 的具体实现 数据库抽象 :屏蔽底层数据库差异 自动 SQL 生成 :减少手动 SQL 编写工作 2. 核心概念 2.1 持久化生命周期 瞬时态(Transient) :未与 Session 关联的对象 持久态(Persistent) :与 Session 关联的对象 脱管态(Detached) :与 Session 断开连接的对象 2.2 Session 机制 Session 接口 :Hibernate 的核心接口 事务管理 :提供 ACID 事务支持 缓存机制 :一级缓存(Session 级别) 3. 项目配置 3.1 Maven 依赖

org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java

3.2 application.yml 配置

spring:

datasource: url: jdbc:mysql://localhost:3306/hibernate_demo username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver

jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect format_sql: true hbm2ddl.auto: update

4. 实体类定义 4.1 基础实体类

@Entity

@Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

@Column(name = "username", nullable = false, length = 50) private String username;

@Column(name = "email", unique = true) private String email;

@Column(name = "created_at") private LocalDateTime createdAt;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List orders = new ArrayList<>();

// 构造函数 public User() {}

public User(String username, String email) { this.username = username; this.email = email; this.createdAt = LocalDateTime.now(); }

// Getter 和 Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; }

public String getUsername() { return username; } public void setUsername(String username) { this.username = username; }

public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }

public LocalDateTime getCreatedAt() { return createdAt; } public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }

public List getOrders() { return orders; } public void setOrders(List orders) { this.orders = orders; } }

4.2 关联实体类

@Entity

@Table(name = "orders") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

@Column(name = "order_number", unique = true) private String orderNumber;

@Column(name = "total_amount") private BigDecimal totalAmount;

@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user;

@Column(name = "order_date") private LocalDateTime orderDate;

// 构造函数 public Order() {}

public Order(String orderNumber, BigDecimal totalAmount, User user) { this.orderNumber = orderNumber; this.totalAmount = totalAmount; this.user = user; this.orderDate = LocalDateTime.now(); }

// Getter 和 Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; }

public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String orderNumber) { this.orderNumber = orderNumber; }

public BigDecimal getTotalAmount() { return totalAmount; } public void setTotalAmount(BigDecimal totalAmount) { this.totalAmount = totalAmount; }

public User getUser() { return user; } public void setUser(User user) { this.user = user; }

public LocalDateTime getOrderDate() { return orderDate; } public void setOrderDate(LocalDateTime orderDate) { this.orderDate = orderDate; } }

5. Repository 接口 5.1 基础 Repository

@Repository

public interface UserRepository extends JpaRepository { Optional findByUsername(String username); List findByEmailContaining(String email);

@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id = :id") Optional findUserWithOrders(@Param("id") Long id);

@Query("SELECT u FROM User u WHERE u.username LIKE %:keyword% OR u.email LIKE %:keyword%") List searchUsers(@Param("keyword") String keyword); }

5.2 Order Repository

@Repository

public interface OrderRepository extends JpaRepository { List findByUser(User user); List findByUserAndTotalAmountGreaterThan(User user, BigDecimal amount);

@Query("SELECT o FROM Order o WHERE o.orderDate BETWEEN :startDate AND :endDate") List findOrdersByDateRange(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate); }

6. Service 层实现 6.1 UserService

@Service

@Transactional public class UserService {

@Autowired private UserRepository userRepository;

@Autowired private OrderRepository orderRepository;

public User createUser(String username, String email) { User user = new User(username, email); return userRepository.save(user); }

public Optional findUserById(Long id) { return userRepository.findById(id); }

public User findUserWithOrders(Long id) { return userRepository.findUserWithOrders(id) .orElseThrow(() -> new EntityNotFoundException("User not found: " + id)); }

public List findAllUsers() { return userRepository.findAll(); }

public User updateUser(Long id, String username, String email) { User user = userRepository.findById(id) .orElseThrow(() -> new EntityNotFoundException("User not found: " + id));

user.setUsername(username); user.setEmail(email); return userRepository.save(user); }

public void deleteUser(Long id) { if (!userRepository.existsById(id)) { throw new EntityNotFoundException("User not found: " + id); } userRepository.deleteById(id); }

public List searchUsers(String keyword) { return userRepository.searchUsers(keyword); }

public Order createOrderForUser(Long userId, String orderNumber, BigDecimal amount) { User user = userRepository.findById(userId) .orElseThrow(() -> new EntityNotFoundException("User not found: " + userId));

Order order = new Order(orderNumber, amount, user); return orderRepository.save(order); } }

7. 控制器层 7.1 UserController

@RestController

@RequestMapping("/api/users") public class UserController {

@Autowired private UserService userService;

@PostMapping public ResponseEntity createUser(@RequestBody CreateUserRequest request) { User user = userService.createUser(request.getUsername(), request.getEmail()); return ResponseEntity.ok(user); }

@GetMapping("/{id}") public ResponseEntity getUser(@PathVariable Long id) { try { User user = userService.findUserWithOrders(id); return ResponseEntity.ok(user); } catch (EntityNotFoundException e) { return ResponseEntity.notFound().build(); } }

@GetMapping public ResponseEntity> getAllUsers() { List users = userService.findAllUsers(); return ResponseEntity.ok(users); }

@PutMapping("/{id}") public ResponseEntity updateUser(@PathVariable Long id, @RequestBody UpdateUserRequest request) { try { User updatedUser = userService.updateUser(id, request.getUsername(), request.getEmail()); return ResponseEntity.ok(updatedUser); } catch (EntityNotFoundException e) { return ResponseEntity.notFound().build(); } }

@DeleteMapping("/{id}") public ResponseEntity deleteUser(@PathVariable Long id) { try { userService.deleteUser(id); return ResponseEntity.noContent().build(); } catch (EntityNotFoundException e) { return ResponseEntity.notFound().build(); } }

@GetMapping("/search") public ResponseEntity> searchUsers(@RequestParam String keyword) { List users = userService.searchUsers(keyword); return ResponseEntity.ok(users); }

@PostMapping("/{userId}/orders") public ResponseEntity createOrder(@PathVariable Long userId, @RequestBody CreateOrderRequest request) { try { Order order = userService.createOrderForUser(userId, request.getOrderNumber(), request.getAmount()); return ResponseEntity.ok(order); } catch (EntityNotFoundException e) { return ResponseEntity.notFound().build(); } } }

8. 高级特性 8.1 事务管理

@Service

public class TransactionalService {

@Autowired private UserRepository userRepository;

@Autowired private OrderRepository orderRepository;

@Transactional public void performComplexOperation(Long userId) { // 在同一个事务中执行多个操作 User user = userRepository.findById(userId).orElse(null);

// 创建订单 Order order = new Order("ORD-001", new BigDecimal("100.00"), user); orderRepository.save(order);

// 更新用户信息 user.setUsername("updated_username"); userRepository.save(user);

// 如果发生异常,整个事务回滚 }

@Transactional(rollbackFor = Exception.class) public void customRollback() throws Exception { // 自定义回滚条件 } }

8.2 缓存配置

@Entity

@Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) @Table(name = "users") public class User { // 实体定义 }

8.3 分页和排序

@Service

public class UserService {

public Page getUsersWithPagination(int page, int size, String sortBy, String direction) { Sort sort = direction.equalsIgnoreCase("desc") ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();

Pageable pageable = PageRequest.of(page, size, sort); return userRepository.findAll(pageable); } }

9. 查询优化 9.1 Fetch Join 优化

@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id = :id")

Optional findUserWithOrders(@Param("id") Long id);

9.2 批量处理

@Service

public class BatchService {

@PersistenceContext private EntityManager entityManager;

@Transactional public void batchInsertUsers(List users) { for (int i = 0; i < users.size(); i++) { entityManager.persist(users.get(i));

if (i % 20 == 0) { // 每20个对象刷新一次 entityManager.flush(); entityManager.clear(); } } } }

10. 异常处理 10.1 自定义异常

public class EntityNotFoundException extends RuntimeException {

public EntityNotFoundException(String message) { super(message); } }

public class DataIntegrityException extends RuntimeException { public DataIntegrityException(String message) { super(message); } }

10.2 全局异常处理

@RestControllerAdvice

public class GlobalExceptionHandler {

@ExceptionHandler(EntityNotFoundException.class) public ResponseEntity handleEntityNotFound(EntityNotFoundException e) { ErrorResponse error = new ErrorResponse("ENTITY_NOT_FOUND", e.getMessage()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error); }

@ExceptionHandler(DataIntegrityException.class) public ResponseEntity handleDataIntegrity(DataIntegrityException e) { ErrorResponse error = new ErrorResponse("DATA_INTEGRITY_ERROR", e.getMessage()); return ResponseEntity.status(HttpStatus.CONFLICT).body(error); } }

11. 性能优化要点 合理使用懒加载和急加载 避免 N+1 查询问题 使用批量操作 合理配置缓存 使用索引优化查询 及时关闭 Session 和连接 12. 常见问题 LazyInitializationException :在事务外访问懒加载属性 事务边界问题 :确保在事务范围内进行数据库操作 缓存一致性 :在集群环境中注意缓存同步 并发控制 :使用乐观锁或悲观锁处理并发访问 Hibernate 懒加载机制详解 懒加载的工作原理 1. 代理对象机制 当使用

FetchType.LAZY

时,Hibernate 会创建一个 代理对象

user.getOrders()

返回的是 Hibernate 的 集合代理 代理对象继承自

PersistentBag

、

PersistentList

等 2. SQL 执行时机

User user = userRepository.findById(1L).get(); // 执行: SELECT * FROM users WHERE id = 1

// 此时 orders 集合为空的代理对象,未执行查询

List orders = user.getOrders(); // 此时才执行: SELECT * FROM orders WHERE user_id = ? // 仅当真正访问 orders 时才触发 SQL 查询

3. 持久层调用方式 初始化时

userRepository.findById(1L).get()

→ 调用

JpaRepository

的方法 执行对

users

表的查询 访问懒加载属性时

user.getOrders()

→ 代理对象拦截调用 Hibernate 内部触发 额外的 SQL 查询 通过

Session

或

EntityManager

执行查询 4. 实际执行流程

1. userRepository.findById(1L).get()

→ Spring Data JPA → Hibernate → SQL: SELECT * FROM users WHERE id = 1

2. user.getOrders() → Hibernate 代理拦截器 → 触发懒加载 → 生成 SQL: SELECT * FROM orders WHERE user_id = 1 → 执行查询并填充集合

5. 关键点 懒加载是在 访问属性时 触发,而非 方法调用时 需要在 事务范围内 访问,否则抛出

LazyInitializationException

Hibernate 通过 字节码增强 实现透明的懒加载机制 Hibernate 事务开启方式详解 1. @Transactional 注解方式 主要开启方式 使用

@Transactional

注解是 Spring 中开启事务的主要方式 可以在 方法级别 或 类级别 使用 Spring 会自动管理事务的开启、提交和回滚 代码示例

@Service

public class TransactionalService {

@Transactional // 开启事务 public void performComplexOperation(Long userId) { // 事务范围内的操作 } }

2. 事务开启的其他方式 编程式事务管理

@Service

public class ProgrammaticTransactionService {

@Autowired private PlatformTransactionManager transactionManager;

public void performWithProgrammaticTransaction() { TransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def);

try { // 业务逻辑 // ...

transactionManager.commit(status); // 提交事务 } catch (Exception e) { transactionManager.rollback(status); // 回滚事务 } } }

3. @Transactional 工作机制 Spring AOP 代理 Spring 通过 AOP 代理 实现事务管理 在方法执行前开启事务 方法执行成功后提交事务 发生异常时回滚事务 事务传播行为

@Transactional(propagation = Propagation.REQUIRED) // 默认传播行为

public void methodA() { methodB(); // 如果存在事务则加入,否则新建 }

@Transactional(propagation = Propagation.REQUIRES_NEW) // 新建事务 public void methodB() { // 独立的事务 }

4. 事务配置参数 常用配置

rollbackFor

: 指定哪些异常触发回滚

noRollbackFor

: 指定哪些异常不触发回滚

isolation

: 事务隔离级别

propagation

: 事务传播行为

timeout

: 事务超时时间 示例配置

@Transactional(

rollbackFor = Exception.class, // 所有异常都回滚 timeout = 30, // 30秒超时 isolation = Isolation.READ_COMMITTED // 隔离级别 ) public void customTransaction() { // 自定义事务配置 }

相关文章