我有一个应用程序需要使用许多重复的行来建模一些现有的数据库表(我无法更改它们)。我试图找出一个好的设计来尽可能多地重用映射代码,所以我不必复制一堆set调用。
以下是两个表的示例。
TIME_AND_EXPENSE_STAGING
Name Null Type
------------------ -------- --------------
SEQ_NUM NOT NULL NUMBER(31)
DATETIME_STAMP TIMESTAMP(6)
DEPT_ID NOT NULL VARCHAR2(10)
EMPL_ID NOT NULL VARCHAR2(11)
JOB_CODE NOT NULL VARCHAR2(6)
REGULAR_HRS NOT NULL NUMBER(4,2)
OVERTIME_HRS NOT NULL NUMBER(4,2)
MILES NOT NULL NUMBER(8,2)
COMMENTS VARCHAR2(4000)
TIME_AND_EXPENSE_APPROVED
Name Null Type
------------------ -------- --------------
SEQ_NUM NOT NULL NUMBER(31)
DATETIME_STAMP TIMESTAMP(6)
DEPT_ID NOT NULL VARCHAR2(10)
EMPL_ID NOT NULL VARCHAR2(11)
JOB_CODE NOT NULL VARCHAR2(6)
REGULAR_HRS NOT NULL NUMBER(4,2)
OVERTIME_HRS NOT NULL NUMBER(4,2)
MILES NOT NULL NUMBER(8,2)
COMMENTS VARCHAR2(4000)
APPROVE_TIME NOT NULL TIMESTAMP(6)
APPROVER_ID NOT NULL VARCHAR2(11)
我使用Spring框架和Spring RowMapper来填充数据对象。我觉得应该有一些优雅的方式来使用继承或多态或一些设计模式,这将阻止我复制和粘贴一堆set语句。
请告知。
答案 0 :(得分:1)
我个人倾向于在处理这类数据时使用不可变对象。想象一下下面的课程:
public class TimeAndExpense {
private final String jobCode;
// and a bunch of other attributes such as department...
// Then the additional data (approval data)
private final Optional<String> approverId;
private final Optional<Timestamp> approveTime;
public TimeAndExpense(final String jobCode) {
this(jobCode, null, null);
}
public TimeAndExpense(
final String jobCode,
final Timestamp approveTime,
final String approverId) {
this.jobCode = jobCode;
// And the rest of the attributes...
this.approveTime = Optional.ofNullable(approveTime);
this.approverId = Optional.ofNullable(approverId);
}
public Optional<Timestamp> getApproveTime() {
return approveTime;
}
public Optional<String> getApproverId() {
return approverId;
}
public String getJobCode() {
return jobCode;
}
public boolean isApproved() {
return approverId.isPresent();
}
// Creates a new object with the approval data (immutable)
public TimeAndExpense withApprovalData(final Timestamp approveTime, final String approverId) {
return new TimeAndExpense(this.getJobCode(), approveTime, approverId);
}
}
方法withApprovalData
可用于创建具有其他批准数据的TimeAndExpense
- 对象。以这种方式使用时,您可以像这样设置RowMapper
:
// The RowMapper for the table TIME_AND_EXPENSE_STAGING
// More columns than JOB_CODE exists but are not part of the example
private final RowMapper<TimeAndExpense> timeAndExpenseRowMapper =
(rs, rowNum) -> new TimeAndExpense(rs.getString("JOB_CODE"));
// The RowMapper for the table TIME_AND_EXPENSE_APPROVED
// Reuse the timeAndExpenseRowMapper's mapping, then add additional approval data
private final RowMapper<TimeAndExpense> timeAndExpenseApprovedRowMapper =
(rs, rowNum) -> timeAndExpenseRowMapper
.mapRow(rs, rowNum) // use the timeAndExpenseRowMapper
.withApprovalData( // and add the additional approval data
rs.getTimestamp("APPROVE_TIME"),
rs.getString("APPROVER_ID"));
当表非常相似并且允许大量代码重用时,此委托(一个RowMapper
使用另一个RowMapper
)很有效。
我个人尝试尽可能少地使用继承in favour of composition。但是,对于域模型,拥有某种基础对象(例如Identifiable
)可能是有意义的。一个id(因为例如Department
,Employee
和TimeAndExpense
个对象似乎都包含一个id甚至可能是一个时间戳。)