如何解决有没有更好的方法来使用 Java Spring Boot 和 JPA 编写这个练习?
我正在从我的 Spring Boot 课程中构建作业,到目前为止我做了 JPA 层并希望在开始业务规则之前获得一些反馈,关于我是否可以改进某些东西或改变我的关系类型应用程序。 任何建议都会受到欢迎。
这是练习:
“假设我们有一个很大的遗留系统,其中一个部分是提款处理(允许将资金从公司转移到员工账户的过程)。现在我们有机会完全重写系统,包括 API 更改(端点、 DTO 等)作为技术挑战,我们建议您接受它。您可以按照验收标准做任何想做的事情:
- 使用您喜欢的任何架构
- 使用现代 Java 或 Kotlin
- 使用 Spring Boot
- 使用任何数据库 sql/Nosql(请使用嵌入式)
- 必须对代码进行测试
- 服务应该易于运行(例如 docker-compose)
以下是处理的一些业务规则:
- 我们有一个用户列表(/v1/users 端点)
- 一个用户有多种付款方式
- 用户可以使用其中一种付款方式执行提款请求
- 提款可以尽快执行或安排稍后执行
- 服务收到请求后,它会在我们的数据库中存储一个取款对象,并向支付提供商异步发送请求。注意:对于此任务,我们不关心事务完成
- 我们必须 100% 发送有关任何提款状态(事件、电子邮件等)的通知”
这是我对带有 JPA 的模型的解决方案:
-
@Entity(name = "User") @Table(name = "user",uniqueConstraints = {@UniqueConstraint(name= "user_email_unique",columnNames = "email")}) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id",updatable=false) private Long id; @OnetoMany(mappedBy="user") @Column(name = "payment_methods") private List<PaymentMethod> paymentMethods; @OnetoOne(mappedBy = "user") @JoinColumn(name = "account_id",nullable = false) private Account account; @Column(name = "first_name",nullable = false,columnDeFinition = "TEXT") private String firstName; @Column(name = "last_name",columnDeFinition = "TEXT") private String lastName; @Column(name = "email",nullable = false) private String email; @Column(name = "max_withdrawal_amount",columnDeFinition = "DOUBLE") private Double maxWithdrawalamount; }
-
账户:
@Entity(name = "Account") @Table(name = "account",uniqueConstraints = { @UniqueConstraint(name = "account_account_number_unique",columnNames = "account_number") }) public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "account_id") private Long id; @OnetoOne(fetch = FetchType.LAZY) @MapsId private User user; @OnetoMany(mappedBy = "account",cascade = CascadeType.ALL,fetch = FetchType.EAGER) private List<Transaction> transactionList = new ArrayList<>(); @Column(name = "account_number",nullable = false) private Integer accountNumber; @Column(name = "balance",nullable = false) private double balance;
}
-
付款方式
@Entity(name = "PaymentMethod") @Table(name = "payment_methods") public class PaymentMethod { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "payment_methods_id") private Long id; @ManyToOne @JsonIgnore @JoinColumn(name = "user_id",nullable = false) private User user; @Column(name = "payment_name",columnDeFinition = "TEXT") private String paymentName;
}
-
交易
@Entity(name = "Transaction") @Table(name = "transaction") public class Transaction { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "transaction_id",updatable = false) private Long id; @Column(name = "comment",columnDeFinition = "TEXT") private String comment; @ManyToOne @JoinColumn(name = "accountNumber") private Account account;
}
-
提款
@Entity(name = "Withdrawal") @Table(name = "withdrawal") public class Withdrawal { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "withdrawals_id") private Long id; @OnetoOne(fetch = FetchType.LAZY) @MapsId private Transaction transaction; @ManyToOne @JsonIgnore @JoinColumn(name = "payment_methods_id",nullable = false) private PaymentMethod paymentMethod; @Column(name = "amount",columnDeFinition = "DOUBLE") private Double amount; @Column(name = "created_at",columnDeFinition = "DATE DEFAULT CURRENT_DATE") private Instant createdAt; @Column(name = "execute_at",columnDeFinition = "DATE DEFAULT CURRENT_DATE") private Instant executeAt; @Enumerated(EnumType.STRING) @Column(name = "withdrawal_status",columnDeFinition = "TEXT") private WithdrawalStatus status;
}
解决方法
看起来已经很安静了。我有一些建议。
-
您将 Amounts 存储在 Double 中,这可能会导致计算时出现问题。通常的做法是使用以美分为单位的数量并使用整数/长,这样您就不会遇到这些问题。 java afaik 中还有一个货币类。
-
提款难道不是从一个账户到另一个账户的交易吗?为什么你甚至需要 Withdrawal 类? PaymentMethod、Amount 等也可以在交易中。我知道它说明了任务中的提款和交易,但从设计的角度考虑它是否有意义
-
在 PaymentMethod 类中,PaymentName 可以是一个 Enum,所以它不是一个自由文本,而是一个定义好的支付提供商,很容易进行 switch/case on
我会按照其他用户的要求在 Stack Exchange 上发帖。非常感谢您的帮助,这篇文章就到此为止。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。