Spring Boot 中用于实体设计、关联关系、查询优化、事务、审计、索引、分页和连接池的 JPA/Hibernate 模式。
69
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
用于 Spring Boot 中的数据建模、存储库(Repository)和性能调优。
@Entity
@Table(name = "markets", indexes = {
@Index(name = "idx_markets_slug", columnList = "slug", unique = true)
})
@EntityListeners(AuditingEntityListener.class)
public class MarketEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 200)
private String name;
@Column(nullable = false, unique = true, length = 120)
private String slug;
@Enumerated(EnumType.STRING)
private MarketStatus status = MarketStatus.ACTIVE;
@CreatedDate private Instant createdAt;
@LastModifiedDate private Instant updatedAt;
}启用审计 (Auditing):
@Configuration
@EnableJpaAuditing
class JpaConfig {}@OneToMany(mappedBy = "market", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PositionEntity> positions = new ArrayList<>();JOIN FETCH。EAGER 加载,在读取路径中优先使用 DTO 投影(Projection)。@Query("select m from MarketEntity m left join fetch m.positions where m.id = :id")
Optional<MarketEntity> findWithPositions(@Param("id") Long id);public interface MarketRepository extends JpaRepository<MarketEntity, Long> {
Optional<MarketEntity> findBySlug(String slug);
@Query("select m from MarketEntity m where m.status = :status")
Page<MarketEntity> findByStatus(@Param("status") MarketStatus status, Pageable pageable);
}public interface MarketSummary {
Long getId();
String getName();
MarketStatus getStatus();
}
Page<MarketSummary> findAllBy(Pageable pageable);@Transactional 注解。@Transactional(readOnly = true) 优化只读路径。@Transactional
public Market updateStatus(Long id, MarketStatus status) {
MarketEntity entity = repo.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Market"));
entity.setStatus(status);
return Market.from(entity);
}PageRequest page = PageRequest.of(pageNumber, pageSize, Sort.by("createdAt").descending());
Page<MarketEntity> markets = repo.findByStatus(MarketStatus.ACTIVE, page);对于类似游标(Cursor)的分页,请在 JPQL 排序中包含 id > :lastId。
status、slug、外键)添加索引。status, created_at)。select *,仅投影必要的列。saveAll 和 hibernate.jdbc.batch_size 进行批量写入。推荐属性:
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.validation-timeout=5000对于 PostgreSQL 的 LOB 处理,请添加以下内容:
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true@DataJpaTest,以真实反映生产环境。logging.level.org.hibernate.SQL 设置为 DEBUG,将 logging.level.org.hibernate.orm.jdbc.bind 设置为 TRACE 以查看参数值。注意:保持实体轻量化,确保查询意图明确,并缩短事务时长。通过抓取策略(Fetch Strategy)和投影(Projection)防止 N+1 问题,并为读/写路径创建索引。
dfbf946
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.