背景:私は教育環境で働いており、昨年の夏、開発者の 1 人が Spring MVC と Hibernate を使用して Java Web アプリケーションを設計および構築しました。ほこりだらけの古い Blackboard プラグインに取って代わったので、9 月に新しい用語で開始され、ユーザーから大きな喜びを得ました。アプリケーションの主な機能は、生徒の目標を設定し、メッセージを残し、生徒へのレポートを作成するために使用されます。
数か月早送りすると、元の開発者は別の場所に移動し、アプリケーションはいくつかの成長痛を抱えています。
ユース ケース シナリオ:教師がログインすると、現在選択されているコースのターゲット、メッセージ、およびレポートの概要と、現在選択されているコースの学生登録のリストとともに、彼らが教えるコースのリストを含むホーム画面が表示されます。コース。コースに含まれるターゲットの数が少ない場合などは、情報をすばやく返すことができます。しかし、情報量が増えるにつれて、読み込みにかかる時間は指数関数的に増加するようです。
調べてみると、その理由が分かった気がします。私はサンプル コースを受講し、レポートを見て何が起こっているかを確認しました。データベースは関連データをミリ秒単位で返し、ブラウザはそれをミリ秒単位でレンダリングしましたが、ブラウザがデータが返されるのを待っている間に12秒ありました。データベース クエリが終了してからフロント エンドが応答を受信するまでの間にオブジェクトに対して行われる唯一のことは、DTO への変換です。
コード:これは、レポート オブジェクトが DAO レイヤーでどのように見えるかです。
@Entity
@Table(name = "REPORTS")
public class Report implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -7659637777880535914L;
@Id
@GeneratedValue
@Column(name = "REPORT_ID", insertable = true, updatable = false, nullable = false, unique=true)
private Integer reportID;
@Column(name = "DATE_CREATED", insertable = true, updatable = false, nullable = false)
private GregorianCalendar dateCreated;
@Column(name = "DATE_MODIFIED", insertable = true, updatable = true, nullable = true)
private GregorianCalendar dateModified;
@Column(name = "TITLE", insertable = true, updatable = true, nullable = false, length=1000)
private String title;
@Column(name = "CURRENT_PERFORMANCE_GRADE", insertable = true, updatable = true, nullable = false)
private String currentPerformanceGrade;
@Column(name = "TARGET_GRADE", insertable = true, updatable = true, nullable = false)
private String targetGrade;
//VARCHAR(MAX) as this is the main body of the tutor report comments. Here the tutor can write as much content as they like.
@Column(name = "TUTOR_COMMENTS", insertable = true, updatable = true, nullable = false, columnDefinition="VARCHAR(MAX)")
private String tutorComments;
//getters and setters below
}
そこには、レポートがリンクされているユーザー、コース、それを書いたチューターなどの他のフィールドもありますが、ここでは簡単にするためにそれらを省略しました。
public class ReportDTO implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 2795129355073929139L;
private Integer reportID;
private String dateCreated;
private String dateModified;
private String title;
private String currentPerformanceGrade;
private String targetGrade;
private String tutorComments;
//getters and setters below
}
したがって、主な違いは、日付オブジェクトが GregorianCalendar オブジェクトではなく日付形式の文字列になり、日付のフロントエンド表示が読みやすい形式になっていることです。DTO への変換に含まれる例を次に示します。DAO オブジェクトを受け取り、そこから関連するフィールドを取得し、新しく構築された DTO オブジェクトにそれらを設定し、必要に応じて変換し (グレゴリオ暦を日付形式の文字列に変換するなど)、DTO を返すサービス層の Single メソッド:
public ReportDTO convertToDto(Report daoReport) throws Exception
{
ReportDTO dtoReport = new ReportDTO();
try
{
if(daoReport.getReportID() != null)
{
dtoReport.setReportID(daoReport.getReportID());
}
if(daoReport.getDateCreated() != null)
{
dtoReport.setDateCreated(ReportServiceImpl.ISO_DATE_TIME_FORMAT.format(daoReport.getDateCreated().getTime()));
}
if(daoReport.getDateModified() != null)
{
dtoReport.setDateModified(ReportServiceImpl.ISO_DATE_TIME_FORMAT.format(daoReport.getDateModified().getTime()));
}
if(daoReport.getTitle() != null)
{
dtoReport.setTitle(daoReport.getTitle());
}
if(daoReport.getCurrentPerformanceGrade() != null)
{
dtoReport.setCurrentPerformanceGrade(daoReport.getCurrentPerformanceGrade());
}
if(daoReport.getTargetGrade() != null)
{
dtoReport.setTargetGrade(daoReport.getTargetGrade());
}
if(daoReport.getTutorComments() != null)
{
dtoReport.setTutorComments(daoReport.getTutorComments());
}
return dtoReport;
}
catch(Exception e)
{
Exception myException = new Exception("Exception was thrown while converting a persistent Report object to it's data transport equivalent", e);
throw myException;
}
質問:結局のところ、私の質問は、DAO から DTO に変換する正しい方法ですか? 彼が去って以来、私は彼のコードに従っており、新しく追加されたものはすべて同じ方法で行われました。オブジェクトを変換せずにフロントエンドに返すと、結果が 12 秒ではなく 300 ミリ秒を超えて表示されます。
私は彼がプロジェクトのためにここから Spring MVC を学んだことを知っているので、彼は経験豊富な Spring 開発者ではありませんでした。