Allra database schema
Skill ComeOnOliver/skillshub/skills/aiskillstore/marketplace/allra-fintech/allra-database-schema
๐ง The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.
npx -y skills add ComeOnOliver/skillshub --skill allra-database-schemaAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Allra ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ๋ฐ QueryDSL ์ฌ์ฉ ๊ท์น. Use when creating JPA entities, writing QueryDSL queries, or adding @Transactional annotations.
SKILL.md
8.0 KB, as published. Nobody here has run it
Allra Database ์ค๊ณ ๋ฐ QueryDSL ๊ท์น
Allra ๋ฐฑ์๋ ํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ, JPA, QueryDSL, ํธ๋์ญ์ ๊ด๋ฆฌ ํ์ค์ ์ ์ํฉ๋๋ค.
ํ๋ก์ ํธ ๊ธฐ๋ณธ ์ ๋ณด
์ด ๊ฐ์ด๋๋ ๋ค์ ํ๊ฒฝ์ ๊ธฐ์ค์ผ๋ก ์์ฑ๋์์ต๋๋ค:
- Java: 17 ์ด์
- Spring Boot: 3.2 ์ด์
- ORM: JPA/Hibernate
- Query Library: QueryDSL (์ ํ ์ฌํญ)
- Testing: Testcontainers (์ ํ ์ฌํญ)
์ฐธ๊ณ : ํ๋ก์ ํธ๋ณ๋ก ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค(MariaDB, PostgreSQL, MySQL ๋ฑ)์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค.
QueryDSL ์ฌ์ฉ ๊ท์น
1. Repository ๊ตฌ์กฐ (Allra ๊ถ์ฅ ํจํด)
JPA Repository์ Support ์ธํฐํ์ด์ค๋ฅผ ํจ๊ป ์ฌ์ฉ:
// JPA Repository ์ธํฐํ์ด์ค
public interface UserRepository extends JpaRepository<User, Long>, UserRepositorySupport {
}
// QueryDSL Support ์ธํฐํ์ด์ค
public interface UserRepositorySupport {
List<UserSummaryDto> findUserSummaries(UserSearchCondition condition);
}
// QueryDSL Support ๊ตฌํ์ฒด
@Repository
public class UserRepositoryImpl implements UserRepositorySupport {
private final JPAQueryFactory queryFactory;
@Override
public List<UserSummaryDto> findUserSummaries(UserSearchCondition condition) {
return queryFactory
.select(new QUserSummaryDto(
user.id,
user.email,
user.name
))
.from(user)
.where(
emailContains(condition.email()),
nameContains(condition.name())
)
.fetch();
}
private BooleanExpression emailContains(String email) {
return email != null ? user.email.contains(email) : null;
}
}
์ฐธ๊ณ : Support ํจํด์ ์ ํ ์ฌํญ์
๋๋ค. ํ๋ก์ ํธ์ ๋ฐ๋ผ @Query ์ด๋
ธํ
์ด์
์ด๋ ๋ค๋ฅธ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
2. QueryDSL DTO Projection
Record์ @QueryProjection ์ฌ์ฉ:
public record UserSummaryDto(
Long id,
String email,
String name
) {
@QueryProjection
public UserSummaryDto {}
}
๋น๋ ์ค์ :
Gradle:
annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta"
Maven:
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
3. From ์ ์ ๋ง๋ Repository ์์น
From์ ์ ํด๋นํ๋ Repository์ ์ ์ํ๋ ๊ฒ์ ๊ถ์ฅ:
// โ ํผํ๊ธฐ: Order์์ User๋ฅผ ์กฐํ
public interface OrderRepositorySupport {
List<UserDto> findUsersByOrderDate(LocalDate date); // From user
}
// โ
๊ถ์ฅ: User์์ Order๋ฅผ ์กฐ์ธ
public interface UserRepositorySupport {
List<UserOrderDto> findUsersWithOrders(LocalDate date); // From user
}
4. ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธํ์ฑ
QueryDSL ์์ฑ ์ ์ฌ์ฉ ์ค์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํน์ฑ์ ๊ณ ๋ ค:
// ์ผ๋ฐ์ ์ธ ์ฟผ๋ฆฌ
queryFactory
.selectFrom(user)
.where(user.createdAt.between(startDate, endDate))
.fetch();
// LIMIT/OFFSET
queryFactory
.selectFrom(user)
.limit(10)
.offset(0)
.fetch();
์ฐธ๊ณ : ์๋์ฐ ํจ์๋ ํน์ DB ํจ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฒ์ ์ ๋ฐ๋ผ ์ง์ ์ฌ๋ถ๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค.
5. xxxRepositorySupport ์ง์ ์์กด ๊ธ์ง
๋ฐ๋์ JPA Repository ์ธํฐํ์ด์ค๋ฅผ ํตํด ์ฌ์ฉ:
// โ ์๋ชป๋ ์
@Service
public class UserService {
private final UserRepositoryImpl userRepositoryImpl; // ๊ตฌํ์ฒด ์ง์ ์ฃผ์
}
// โ
์ฌ๋ฐ๋ฅธ ์
@Service
public class UserService {
private final UserRepository userRepository; // ์ธํฐํ์ด์ค ์ฃผ์
}
@Transactional ์ฌ์ฉ ๊ฐ์ด๋
ํ์ ๊ท์น
๊ฐ ์๋น์ค ๋ฉ์๋์ ๋ช ์์ ์ผ๋ก ์ ์ธ:
- ์กฐํ ์ฟผ๋ฆฌ๋ง:
@Transactional(readOnly = true) - ๋ณ๊ฒฝ ์ฟผ๋ฆฌ ํฌํจ:
@Transactional
์์
@Service
public class UserService {
private final UserRepository userRepository;
// ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์
@Transactional(readOnly = true)
public List<User> findAllUsers() {
return userRepository.findAll();
}
// ์ฐ๊ธฐ ํธ๋์ญ์
@Transactional
public User createUser(SignUpRequest request) {
User user = User.create(request.email(), request.password());
return userRepository.save(user);
}
// ์กฐํ + ๋ณ๊ฒฝ
@Transactional
public User activateUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
user.activate(); // ๋ณ๊ฒฝ
return user;
}
}
์ฐธ๊ณ : ํธ๋์ญ์
์ ํ(Propagation)๋ ๊ธฐ๋ณธ๊ฐ(REQUIRED)์ ์ฌ์ฉํ๋ฉฐ, ํน์ํ ๊ฒฝ์ฐ์๋ง ๋ช
์ํฉ๋๋ค.
JPA Entity ์ค๊ณ ๊ฐ์ด๋
๊ธฐ๋ณธ ๊ตฌ์กฐ
@Entity
@Table(name = "users")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 100)
private String email;
@Column(nullable = false, length = 100)
private String name;
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 20)
private UserStatus status;
@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column(nullable = false)
private LocalDateTime updatedAt;
// ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋
public static User create(String email, String password, String name) {
User user = new User();
user.email = email;
user.password = password;
user.name = name;
user.status = UserStatus.ACTIVE;
return user;
}
// ๋น์ฆ๋์ค ๋ฉ์๋
public void activate() {
this.status = UserStatus.ACTIVE;
}
}
์ฐ๊ด๊ด๊ณ ๋งคํ
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ManyToOne - ์ง์ฐ ๋ก๋ฉ ๊ถ์ฅ
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
// OneToMany - ์ง์ฐ ๋ก๋ฉ, Cascade ์ค์
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items = new ArrayList<>();
// ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋
public void addItem(OrderItem item) {
items.add(item);
item.setOrder(this);
}
}
์ฐธ๊ณ : ์ฐ๊ด๊ด๊ณ๋ ์ง์ฐ ๋ก๋ฉ(LAZY)์ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
When to Use This Skill
์ด skill์ ๋ค์ ์ํฉ์์ ์๋์ผ๋ก ์ ์ฉ๋ฉ๋๋ค:
- JPA Entity ์์ฑ ๋ฐ ์์
- QueryDSL ์ฟผ๋ฆฌ ์์ฑ
- Repository ์ธํฐํ์ด์ค ๋ฐ ๊ตฌํ์ฒด ์์ฑ
- Service ๋ฉ์๋์ @Transactional ์ถ๊ฐ
- DTO Projection ์์ฑ
Checklist
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์ฝ๋ ์์ฑ ์ ํ์ธ์ฌํญ:
- QueryDSL Support๊ฐ JPA Repository์ ์์๋์ด ์๋๊ฐ? (Support ํจํด ์ฌ์ฉ ์)
- QueryDSL ๊ตฌํ์ฒด๊ฐ From์ ์ ๋ง๋ Repository์ ์๋๊ฐ?
- DTO Projection์ @QueryProjection์ด ์ ์ฉ๋์๋๊ฐ? (QueryDSL ์ฌ์ฉ ์)
- Service์ ๋ชจ๋ public ๋ฉ์๋์ @Transactional์ด ๋ช ์๋์๋๊ฐ?
- ์ฝ๊ธฐ ์ ์ฉ ๋ฉ์๋์ readOnly = true๊ฐ ์ ์ฉ๋์๋๊ฐ?
- MariaDB ํธํ์ฑ์ ๊ณ ๋ คํ๋๊ฐ?
- Entity์ ์ฐ๊ด๊ด๊ณ๊ฐ ์ง์ฐ ๋ก๋ฉ(LAZY)์ผ๋ก ์ค์ ๋์๋๊ฐ?
- xxxRepositorySupport ๊ตฌํ์ฒด๋ฅผ ์ง์ ์ฃผ์ ํ์ง ์์๋๊ฐ?