黑馬旅遊網編寫練習(9)–旅遊線路收藏功能
旅遊線路收藏功能分析
在旅遊詳情頁面,用戶點擊收藏按鈕後,我們向服務器發送Ajax請求;然後查詢用戶是否登錄;若用戶已登錄,則需要查詢數據庫表格判斷該用戶是否收藏了該線路;若收藏成功,則返回標記,前端根據該標記修改收藏按鈕的樣式。
數據庫表格關係分析
用戶收藏線路,涉及到三個表格;一個是用戶的表格tab_user;一個是旅遊線路tab_route;還有一個是用戶收藏表格tab_favorite。先來觀察這三個表格之間的關係。
tab_favorite表格中rid代表某一條旅遊線路;uid代表用戶信息。所以在前臺向服務器發送Ajax請求時,需要傳遞的參數是rid;uid可以通過查詢當前登錄用戶來查詢。而用戶是否收藏該線路則只需要查詢tab_favorite表格中是否存在滿足rid和uid的信息。
接下來先開始編寫後臺信息
首先開始編寫web層,在RouteServlet中編寫一個查詢是否收藏的方法;該方法主要代碼如下:
/**
* 判斷用戶是否已經收藏了該線路
* @param request
* @param response
* @throws IOException
*/
public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 獲取線路的rid參數
String rid_str = request.getParameter("rid");
if(rid_str == null || rid_str.length() == 0 || rid_str.equals("null")){
// rid_str爲空
System.out.println("rid_str爲空");
return;
}
int rid = Integer.parseInt(rid_str);
// 判斷用戶是否登錄
User user = (User) request.getSession().getAttribute("user");
int uid = 0;
if(user == null){
// 用戶未登錄
System.out.println("用戶未登錄,請先登錄");
return;
}else{
// 用戶已登錄,獲取用戶的uid
uid = user.getUid();
}
// 調用FavoriteService查詢線路rid是否被用戶uid收藏
boolean flag = favoriteService.isFavorite(rid, uid);
// 將該收藏標誌信息返回給客戶端
responseJson(response,flag);
}
接下來開始編寫service層,該層實現一個判斷線路rid是否被用戶uid收藏的方法,主要代碼如下:
// 創建FavoriteDao對象
FavoriteDao favoriteDao = new FavoriteDaoImpl();
/**
* 判斷線路rid是否被用戶uid收藏
* @param rid
* @param uid
* @return
*/
@Override
public boolean isFavorite(int rid, int uid) {
// 創建一個favorite對象,存儲查詢結果
Favorite favorite = null;
// 調用FavoriteDao,查詢tab_favorite表
favorite = favoriteDao.findByRidAndUid(rid, uid);
if(favorite == null){
// 查詢失敗
return false;
}else{
// 查詢成功
return true;
}
}
最後編寫dao層,創建一個FavoriteDao對象。該對象中通過rid和uid查詢tab_favorite表。主要代碼如下:
// 定義數據庫連接對象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 通過rid和uid查詢tab_favorite表格,返回Favorite對象
* @param rid
* @param uid
* @return
*/
@Override
public Favorite findByRidAndUid(int rid, int uid) {
Favorite favorite = null;
// 定義sql
String sql = "select * from tab_favorite where rid = ? and uid = ? ";
try {
// 執行sql
favorite = template.queryForObject(sql,new BeanPropertyRowMapper<Favorite>(Favorite.class),rid,uid);
} catch (DataAccessException e) {
//e.printStackTrace(); //查詢失敗
System.out.println("favorite查詢失敗");
}
return favorite;
}
前臺完成數據的傳遞以及收藏按鈕樣式的展示
用戶瀏覽線路詳情時,需要自動向後臺發送Ajax請求;根據響應結果爲收藏按鈕展示不同的樣式。
在前臺向服務器發送Ajax請求時,需要傳遞的參數是rid;服務器響應的是用戶是否收藏的標誌。若用戶已經收藏,則設置收藏按鈕的樣式爲已收藏,並且不可點擊。
收藏按鈕設置的主要代碼如下:
// 向服務器發送Ajax請求,獲取是否收藏標誌,若已收藏,則設置收藏按鈕爲已收藏狀態
$.post("route/isFavorite",{rid:rid},function (flag) {
alert(flag);
if(flag){
// 如果當前登錄用戶已經收藏了此線路
// <!--<a class="btn already" disabled="disabled"><i class="glyphicon glyphicon-heart-empty"></i>點擊收藏</a>-->
$("#favorite").addClass("already");
$("#favorite").attr("disabled","disabled");
$("#favorite").text("已收藏");
// 刪除按鈕的點擊事件
$("#favorite").removeAttr("onclick");
}
});
前臺完成收藏次數的展示
用戶瀏覽線路詳情時,需要自動向後臺發送Ajax請求;獲取當前線路的收藏次數,將收藏次數展示到頁面中相應位置。
同樣,我們在routeServlet中添加一個favoriteCount方法來完成此功能;在favoriteDao中添加一個通過線路rid來查詢tab_favorite表格的方法;同樣在favoriteService中也增加一個方法。
首先來寫dao的代碼,favoriteDao中查詢方法如下:
/**
* 通過rid查詢該線路被收藏的次數
* @param rid
* @return
*/
@Override
public int findByRid(int rid) {
int favoriteCount = -1;
// 定義sql
String sql = "select count(*) from tab_favorite where rid = ? ";
try {
// 執行sql
favoriteCount = template.queryForObject(sql,Integer.class,rid);
} catch (DataAccessException e) {
//e.printStackTrace(); // 查詢失敗
System.out.println("FavoriteDao查詢收藏次數失敗");
}
return favoriteCount;
}
接下來編寫service層的代碼,favoriteService中查詢方法如下:
/**
* 判斷線路rid的收藏次數
* @param rid
* @return
*/
@Override
public int favoriteCount(int rid) {
// 調用dao層方法查詢線路rid的收藏次數
return favoriteDao.findByRid(rid);
}
接下來在routeServlet中添加一個favoriteCount方法,該方法具體如下:
/**
* 查詢線路rid的收藏次數
* @param request
* @param response
* @throws IOException
*/
public void favoriteCount(HttpServletRequest request, HttpServletResponse response) throws IOException{
// 獲取線路rid
String rid_str = request.getParameter("rid");
if(rid_str == null || rid_str.length() == 0 || rid_str.equals("null")){
// rid_str爲空
System.out.println("rid爲空,請求錯誤");
return;
}
int rid = Integer.parseInt(rid_str);
// 調用favoriteService層方法查詢線路的收藏次數
int favoriteCount = favoriteService.favoriteCount(rid);
// 將收藏次數響應給客戶端
responseJson(response,favoriteCount);
}
最後完成前臺收藏次數的展示,展示的主要代碼如下:
// 向服務器發送Ajax請求,獲取線路收藏次數,並將收藏次數展示到頁面
$.post("route/favoriteCount",{rid:rid},function (count){
$("#favoriteCount").html("已收藏"+count+"次");
});
點擊收藏按鈕,完成線路的收藏
分析
首先要爲該收藏按鈕添加點擊事件,當用戶點擊該按鈕後;向服務器發送Ajax請求;服務器判斷用戶是否登錄;若用戶未登錄,則提示用戶還沒有登陸,然後跳轉到登陸頁面。若用戶已經登陸,則設置將該線路rid和用戶的uid,保存到tab_favorite表中;若保存成功,則再將頁面中點擊收藏按鈕和收藏次數進行刷新。
首先完成後臺代碼的編寫,在routeServlet中添加一個方法,該方法結合favoriteService和favoriteDao實現將收藏路線添加到tab_favorite中
在routeServlet中添加的方法如下:
/**
* 爲登錄用戶添加線路rid的收藏
* @param request
* @param response
* @throws IOException
*/
public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException{
// 獲取線路rid
String rid_str = request.getParameter("rid");
if(rid_str == null || rid_str.length() == 0 || rid_str.equals("null")){
// rid_str爲空
System.out.println("rid爲空,請求錯誤");
return;
}
int rid = Integer.parseInt(rid_str);
// 獲取登錄用戶
User user = (User) request.getSession().getAttribute("user");
if(user == null){
info.setFlag(false);
info.setErrorMsg("用戶尚未登陸,請先登錄");
// 將錯誤信息對象響應給客戶端
responseJson(response,info);
return;
}
// 獲取用戶的uid
int uid = user.getUid();
// 調用favoriteService對象,添加用戶uid的收藏線路rid
boolean flag = favoriteService.addFavorite(rid, uid);
if(flag){
// 收藏成功
info.setFlag(true);
}
// 將錯誤信息對象響應給客戶端
responseJson(response,info);
}
service層添加用戶uid的收藏線路rid的方法如下所示
/**
* 爲用戶uid添加收藏線路rid
* @param rid
* @param uid
* @return
*/
@Override
public boolean addFavorite(int rid, int uid) {
// 調用favoriteDao層的添加收藏線路方法
boolean flag = favoriteDao.addByRidAndUid(rid, uid);
return flag;
}
favoriteDao層的添加收藏線路方法如下所示
/**
* 爲用戶uid添加收藏線路rid
* @param rid
* @param uid
* @return
*/
@Override
public boolean addByRidAndUid(int rid, int uid) {
// 定義sql
String sql = "insert into tab_favorite values(?, ?, ?) ";
try {
//執行sql
template.update(sql, rid, new Date(), uid);
} catch (DataAccessException e) {
//e.printStackTrace(); // 收藏失敗
System.out.println("用戶收藏線路失敗");
return false;
}
return true;
}
至此收藏線路功能的後臺代碼已經完成,接下來完成前端的收藏功能
前端收藏旅遊線路的方法如下:
// 添加收藏線路方法
function addFavorite() {
// 獲取rid
var rid = getParameter("rid");
// 向服務器發送Ajax請求,添加收藏線路rid
$.post("route/addFavorite",{rid:rid},function (info) {
if(info.flag){
// 收藏成功
// 重新調用已收藏按鈕的方法,並重新展示已收藏次數
favorite(rid);
}else{
// 用戶尚未登陸
alert(info.errorMsg);
// 跳轉到登陸頁面
location.href="http://localhost/travel/login.html";
}
});
}
我們在這裏將之前所寫的收藏查詢的功能,以及收藏次數查詢的功能整理爲一個方法,稱爲favorite方法,其主要內容如下:
// 收藏線路並重新展示收藏次數方法
function favorite(rid) {
// 向服務器發送Ajax請求,獲取是否收藏標誌,若已收藏,則設置收藏按鈕爲已收藏狀態
$.post("route/isFavorite",{rid:rid},function (flag) {
if(flag == true){
// 如果當前登錄用戶已經收藏了此線路
// <!--<a class="btn already" disabled="disabled"><i class="glyphicon glyphicon-heart-empty"></i>點擊收藏</a>-->
$("#favorite").addClass("already");
$("#favorite").attr("disabled","disabled");
$("#favorite").text("已收藏");
// 刪除按鈕的點擊事件
$("#favorite").removeAttr("onclick");
}
});
// 向服務器發送Ajax請求,獲取線路收藏次數,並將收藏次數展示到頁面
$.post("route/favoriteCount",{rid:rid},function (count){
$("#favoriteCount").html("已收藏"+count+"次");
});
}
至此,便可以完成用戶的收藏功能了。