一、設計實體類時比較原來學校學到的知識:
原有的設計都是數據庫存什麼字段,就在實體類裏生成相應的字段。由於本人的mybatis也只是僅僅會用的菜鳥水平,並不沒有用過manyToOne、oneToOne、oneToMany等,使用的還是之前學到的知識與思路。
Eg:
關聯表
對應實體類的字段
紅色的爲外鍵,而藍色的就是爲了後期傳數據方便添加的外鍵實體
這樣的設計導致每次查詢時候想要獲得Scored這個實體,項目需要經過的操作有2步,
①、從scored表中查出數據
②、遍歷所有的scored對象,對於每個timuId,userId,去相應表中取出相應記錄並賦給相應Timu,User實體。並塞到Scored的timu與user對象中。
這樣雖然可以獲得所有的數據,但必然會造成查詢時間增加。
對比最近剛接觸的hibernate註解:
數據庫設計,依然是填入id
但對應的實體類就直接使用了對應外鍵的實體
具體代碼如下:
@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserHome.class)
@JoinColumn(name = "user_id")
public UserHome getUserHome() {
return userHome;
}
public void setUserHome(UserHome userHome) {
this.userHome = userHome;
}
@ManyToOne指明瞭這個ScoreAllLogs類對於UserHome類是多對一的關係,目標實體是UserHome.class。注意是要放在get方法上,我最早直接放在了實體申明上,結果就是什麼奇蹟都沒有發生。
@JoinColumn則指明瞭本表中什麼字段用於關聯外表
這樣Hibernate在我們存儲實體的時候,就會自動將實體的Id存入ScoreAllLogs表了。
在取出數據的時候,又會根據id自動將實體關聯好並傳入ScoreAllLogs實體中。
這樣做的好處是避免了代碼的冗餘,並減少了與數據庫交互的次數,直接提升操作的速度。
二、實體類中get的巧用
這是我目前這個階段沒有見過的騷操作,當四哥把這方法教我的時候我都震驚了!
具體過程是這樣的:我的項目在與客戶溝通之後,原有的考試時間取配置文件的方法他們要求改成每題可以設置不同的時間,然後我就從數據改起啊,想着所有的後臺要改以及前端都要換頁面,多麼浩大的工程!按照原來的思路,這一塊基本是等於重做了吧。
這時候四哥給我說了一個思路,
1、對於所有的題目,都一個時間這個需求是不變的,只是時間的來源變了而已(來自配置文件或者本題的時間),不管如何時間都是附屬於這個實體類的。那我們的對於時間的操作就可以在實體類中進行,而set方法我們盡少用,處理的話多在get方法上。
2、實體類也是一個java類,也可以寫java代碼。如果有關實體類屬性的邏輯判斷,方法等,都可以寫在實體類中,減少在service中再次處理實體類,造成代碼的冗餘。
那麼是不是可以做一個開關,分別對應是取配置文件還是取本題時間。那麼對於後期如果用戶又想用統一考試時間的時候,數據庫我就不用再做更改了,前端配合EL表達式來控制時間框的顯隱就行。
配置文件如下:
源碼:Timu實體類,改寫getTime的內部,根據配置文件中的開關來決定時間的來源。
public Integer getTimuTime() {
try {
//時間開關 取配置文件的時間 or 取本題的時間
Integer open = Integer.parseInt(GetProperty.getPropertyByName2("setTime.properties", "simpleTimer.switch"));
if (open == 1 || timuTime == null) {//如果開關打開或者題目時間未填寫 取配置文件的時間
String timer = GetProperty.getPropertyByName2("setTime.properties", "simpleTimer.timer");
return Integer.parseInt(timer);
} else {
return timuTime;
}
} catch (Exception e) {
System.out.println("取題目時間出錯:"+e.getMessage());
return timuTime;
}
}
效果(此時是使用題目自帶的時間):
此時使用統一時間:
更改配置文件中的開關:
再來看這時候題目的時間(使用統一的時間):
清一色的變成了配置文件中設置的時間,這樣對於用戶的需求變更,只需要改一個數字就可以達成,無需再費時費力的將代碼從頭改到尾了。
另一個巧妙的用法:
前臺EL需要一個標誌來判斷一個輸入框是否展示,則用這種get,加上@Transient的意思是不加入實體中,也就是不生成屬性。
/**
*
* @author xuexy
* @Title: isOtherMajor
* @Description: 判斷用戶的專業是否是其他
* @return 是返回true 不是返回false
* @return Boolean
* @throws
*
*/
@Transient
public Boolean getOtherMajor() {
boolean flag = true;
List<MajorList> list= Constants.MajorList.getList();
List<MajorList> listForBL=list.subList(0,10);//判斷是否在給定範圍中 0~9 不包括10
for (MajorList li:listForBL) {
if(li.getFriendlyType().equals(this.getMajor())){//如果在在給定範圍中 則置否 不是其他項
flag=false;
}
}
return flag;
}
前臺可以這樣取值:
這樣就可以在不添加屬性的前提下,增加判斷的方法了。
這些思想在我一個菜鳥看來十分好用,於是做了這篇筆記。