使 DAO class 可比较类型是一个好习惯吗
Is it a good practice to make a DAO class Comparable type
这是我在休眠模式下的示例映射
class ApplnDoc {
AdmAppln admAppln;
// getters and setters
}
class AdmAppln {
Set<Student> student;
// getters and setters
}
class Student {
int id;
String registerNo;
AdmAppln admAppln;
// getters and setters
}
在 ApplnDoc
table 中,我们正在存储所有候选人的图像。 AdmAppln
用于存储录取信息,Student
用于存储学生信息。即使 AdmAppln
的 Set
为 Student
,对于特定的 AdmAppln
id
(在一个AdmAppln 只有一名学生)。
现在我想将这些 table 中的少量数据写入一个 Excel
文件,其记录必须按 registerNo
的顺序排序(如果存在),否则使用 Student
的 id
。我们使用 org.apache.poi.xssf.usermodel
包下的 XSSFWorkbook
class 对 Excel
sheet 进行操作。 Here 我找到了一种对 excel sheet 进行排序的方法,但我尝试使用 Comparable
接口在代码本身中找到了一种方法。
这就是我在 ApplnDoc
class
中所做的
public int compareTo(ApplnDoc otherData) {
if(new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo() != null &&
!new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo().isEmpty() &&
new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo() != null &&
!new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo().isEmpty()) {
return new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo()
.compareTo
(new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo());
} else {
return new ArrayList<Student>(this.admAppln.getStudents()).get(0).getId() -
new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getId();
}
}
由于 Set
接口中没有 get()
方法,从 AdmAppln
获取 Student
的 registerNo
的唯一方法是将其转换为一个列表。然后我对列表进行排序,然后迭代生成excel文件。
上述比较机制是否合适,或者有更好的方法吗?为什么我要问这个问题,因为当 Hibernate 会话关闭时,在我的 compareTo
中,如果我正在访问子 table 列,那么我将得到 Invocation
异常。
您需要在关闭会话之前加载整个对象树,否则您将获得异常。顺便说一句,您始终可以使用查询本身对记录进行排序。
这里有一些值得讨论的地方:
1-
Even if AdmAppln is having a Set of Student, only one record of
Student will be present for a particular AdmAppln
为什么?
这是您无法控制的事情,还是有任何特殊原因在不需要的地方保留一套? (我还假设 @OneToMany
而不是 @OneToOne
映射)
2-
这导致子对象被延迟获取(N.B 这是一个假设,因为您没有 post 有关映射的相关代码或如何你从数据库中获取实体)。
这意味着您必须切换到实体中的预先获取(不推荐)或在获取实体时指定它
3-
另外请重构 compareTo 并使用变量
public int compareTo(ApplnDoc otherData) {
Student thisStudent = new ArrayList<>(this.admAppln.getStudents()).get(0);
Student otherStudent = new ArrayList<>(otherData.admAppln.getStudents()).get(0);
if(thisStudent.getRegisterNo() != null &&
!thisStudent.getRegisterNo().isEmpty() &&
otherStudent.getRegisterNo() != null &&
!otherStudent.getRegisterNo().isEmpty()) {
return thisStudent.getRegisterNo().compareTo(otherStudent.getRegisterNo());
} else {
return thisStudent.getId() - otherStudent.getId();
}
}
虽然该比较机制没有任何问题(如果您有一个空的 Set
学生,则 NullPointer 除外)您应该在查询时使用数据库排序。
如果您仍想以这种方式进行比较,您只需确保在关闭会话之前已获取所需的所有内容。
这是我在休眠模式下的示例映射
class ApplnDoc {
AdmAppln admAppln;
// getters and setters
}
class AdmAppln {
Set<Student> student;
// getters and setters
}
class Student {
int id;
String registerNo;
AdmAppln admAppln;
// getters and setters
}
在 ApplnDoc
table 中,我们正在存储所有候选人的图像。 AdmAppln
用于存储录取信息,Student
用于存储学生信息。即使 AdmAppln
的 Set
为 Student
,对于特定的 AdmAppln
id
(在一个AdmAppln 只有一名学生)。
现在我想将这些 table 中的少量数据写入一个 Excel
文件,其记录必须按 registerNo
的顺序排序(如果存在),否则使用 Student
的 id
。我们使用 org.apache.poi.xssf.usermodel
包下的 XSSFWorkbook
class 对 Excel
sheet 进行操作。 Here 我找到了一种对 excel sheet 进行排序的方法,但我尝试使用 Comparable
接口在代码本身中找到了一种方法。
这就是我在 ApplnDoc
class
public int compareTo(ApplnDoc otherData) {
if(new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo() != null &&
!new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo().isEmpty() &&
new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo() != null &&
!new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo().isEmpty()) {
return new ArrayList<Student>(this.admAppln.getStudents()).get(0).getRegisterNo()
.compareTo
(new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getRegisterNo());
} else {
return new ArrayList<Student>(this.admAppln.getStudents()).get(0).getId() -
new ArrayList<Student>(otherData.admAppln.getStudents()).get(0).getId();
}
}
由于 Set
接口中没有 get()
方法,从 AdmAppln
获取 Student
的 registerNo
的唯一方法是将其转换为一个列表。然后我对列表进行排序,然后迭代生成excel文件。
上述比较机制是否合适,或者有更好的方法吗?为什么我要问这个问题,因为当 Hibernate 会话关闭时,在我的 compareTo
中,如果我正在访问子 table 列,那么我将得到 Invocation
异常。
您需要在关闭会话之前加载整个对象树,否则您将获得异常。顺便说一句,您始终可以使用查询本身对记录进行排序。
这里有一些值得讨论的地方:
1-
Even if AdmAppln is having a Set of Student, only one record of Student will be present for a particular AdmAppln
为什么?
这是您无法控制的事情,还是有任何特殊原因在不需要的地方保留一套? (我还假设 @OneToMany
而不是 @OneToOne
映射)
2-
这导致子对象被延迟获取(N.B 这是一个假设,因为您没有 post 有关映射的相关代码或如何你从数据库中获取实体)。
这意味着您必须切换到实体中的预先获取(不推荐)或在获取实体时指定它
3-
另外请重构 compareTo 并使用变量
public int compareTo(ApplnDoc otherData) {
Student thisStudent = new ArrayList<>(this.admAppln.getStudents()).get(0);
Student otherStudent = new ArrayList<>(otherData.admAppln.getStudents()).get(0);
if(thisStudent.getRegisterNo() != null &&
!thisStudent.getRegisterNo().isEmpty() &&
otherStudent.getRegisterNo() != null &&
!otherStudent.getRegisterNo().isEmpty()) {
return thisStudent.getRegisterNo().compareTo(otherStudent.getRegisterNo());
} else {
return thisStudent.getId() - otherStudent.getId();
}
}
虽然该比较机制没有任何问题(如果您有一个空的 Set
学生,则 NullPointer 除外)您应该在查询时使用数据库排序。
如果您仍想以这种方式进行比较,您只需确保在关闭会话之前已获取所需的所有内容。