一键导入
database-patterns
Database patterns for JPA/Spring Data. Schema naming, Flyway migrations, N+1 prevention, transaction boundaries, indexing strategy.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Database patterns for JPA/Spring Data. Schema naming, Flyway migrations, N+1 prevention, transaction boundaries, indexing strategy.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Planning Mode skill for guided execution of large tasks. Provides structured task decomposition, user confirmation, per-task verification, retry logic, and quality summary.
Git 工作流 — 版本控制、提交规范、分支管理、.gitignore 治理
Structured bug diagnosis and repair workflow using the 5-Whys root cause analysis method. Ensures fixes include tests, documentation, and knowledge capture.
Generates structured documents including architecture diagrams (Mermaid), usage manuals, progress reports, and API documentation from code analysis.
Extracts reusable patterns and lessons from execution history and project experience. Generates structured knowledge entries for the knowledge base.
Evaluates project progress by analyzing workspace structure, code completeness, and comparing against planned milestones. Outputs structured progress reports.
| name | database-patterns |
| description | Database patterns for JPA/Spring Data. Schema naming, Flyway migrations, N+1 prevention, transaction boundaries, indexing strategy. |
| trigger | when working with JPA, SQL, Flyway, database schemas, or repositories |
| tags | ["database","jpa","flyway","sql","schema","transactions"] |
| version | 2.0 |
| scope | platform |
| category | foundation |
snake_case for all identifiersorder, order_item (not orders){referenced_table}_id (e.g., order_id)idx_{table}_{columns} (e.g., idx_order_customer_id)created_at, updated_at, created_by, updated_byFormat: V{version}__{description}.sql
V1__create_order_table.sql
V2__add_order_status_column.sql
V3__create_payment_table.sql
Rules:
// BAD — N+1 problem
@Entity class Order(
@OneToMany(mappedBy = "order")
val items: List<OrderItem> = emptyList()
)
// Accessing order.items triggers N additional queries
// GOOD — EntityGraph
@EntityGraph(attributePaths = ["items"])
fun findByCustomerId(customerId: String): List<Order>
// GOOD — JOIN FETCH
@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.customerId = :customerId")
fun findWithItemsByCustomerId(customerId: String): List<Order>
// GOOD — batch size
@BatchSize(size = 25)
@OneToMany(mappedBy = "order")
val items: List<OrderItem> = emptyList()
@Transactional on service layer only, NEVER on controllers or repositories@Transactional(readOnly = true) for read operationsWhen a service needs to access multiple databases (e.g., primary + legacy, read replica).
@Configuration
class DataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.primary")
fun primaryDataSource(): DataSource = DataSourceBuilder.create().build()
@Bean
@ConfigurationProperties("spring.datasource.legacy")
fun legacyDataSource(): DataSource = DataSourceBuilder.create().build()
}
@Configuration
@EnableJpaRepositories(
basePackages = ["com.forge.repository.primary"],
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
class PrimaryJpaConfig {
@Bean @Primary
fun primaryEntityManagerFactory(
@Qualifier("primaryDataSource") dataSource: DataSource,
builder: EntityManagerFactoryBuilder
): LocalContainerEntityManagerFactoryBean =
builder.dataSource(dataSource)
.packages("com.forge.entity.primary")
.persistenceUnit("primary")
.build()
@Bean @Primary
fun primaryTransactionManager(
@Qualifier("primaryEntityManagerFactory") emf: EntityManagerFactory
): PlatformTransactionManager = JpaTransactionManager(emf)
}
@Configuration
@EnableJpaRepositories(
basePackages = ["com.forge.repository.legacy"],
entityManagerFactoryRef = "legacyEntityManagerFactory",
transactionManagerRef = "legacyTransactionManager"
)
class LegacyJpaConfig {
@Bean
fun legacyEntityManagerFactory(
@Qualifier("legacyDataSource") dataSource: DataSource,
builder: EntityManagerFactoryBuilder
): LocalContainerEntityManagerFactoryBean =
builder.dataSource(dataSource)
.packages("com.forge.entity.legacy")
.persistenceUnit("legacy")
.build()
@Bean
fun legacyTransactionManager(
@Qualifier("legacyEntityManagerFactory") emf: EntityManagerFactory
): PlatformTransactionManager = JpaTransactionManager(emf)
}
spring:
datasource:
primary:
url: jdbc:postgresql://primary-db:5432/forge
username: ${PRIMARY_DB_USER}
password: ${PRIMARY_DB_PASSWORD}
legacy:
url: jdbc:sqlserver://legacy-db:1433;databaseName=OldSystem
username: ${LEGACY_DB_USER}
password: ${LEGACY_DB_PASSWORD}
Rules:
@PrimaryEntityManagerFactory and TransactionManagerFlyway beans per data source with distinct migration locationsReference for teams migrating .NET Entity Framework code to Spring Data JPA.
| Entity Framework (C#) | Spring Data JPA (Kotlin) |
|---|---|
DbContext | @Configuration + EntityManagerFactory |
DbSet<Order> | JpaRepository<Order, String> |
modelBuilder.Entity<Order>() | @Entity + annotations or @EntityListeners |
HasKey(o => o.Id) | @Id |
HasOne(o => o.Customer).WithMany(c => c.Orders) | @ManyToOne / @OneToMany(mappedBy = ...) |
HasMany(o => o.Items).WithOne(i => i.Order) | @OneToMany(mappedBy = ...) / @ManyToOne |
Property(o => o.Name).IsRequired().HasMaxLength(100) | @Column(nullable = false, length = 100) |
HasIndex(o => o.Email).IsUnique() | @Table(indexes = [@Index(columnList = "email", unique = true)]) |
ToTable("orders") | @Table(name = "orders") |
HasDefaultValue(0) | @ColumnDefault("0") or Flyway migration |
IQueryable<T> LINQ queries | @Query("SELECT ...") JPQL or Criteria API |
AsNoTracking() | @Transactional(readOnly = true) |
| EF Migration | Flyway Equivalent |
|---|---|
Add-Migration CreateOrders | V1__create_orders.sql (hand-written SQL) |
Update-Database | ./gradlew flywayMigrate or auto on startup |
modelBuilder.HasData(seedData) | V999__seed_data.sql or afterMigrate.sql |
Down() method | Flyway U1__undo_create_orders.sql (Teams edition) |
| Auto-generated migration | Always hand-written — Flyway does not auto-generate |
@EntityGraph or JOIN FETCH to avoid N+1detach() / read-only transactions disable itOwnsOne() maps to JPA @Embedded / @Embeddable@Enumerated(STRING) stores as string (recommended)HasQueryFilter(e => !e.IsDeleted) → JPA @Where(clause = "is_deleted = false") (Hibernate) or @SQLRestriction