黑马旅游网编写练习(7)–某一旅游线路详情展示
在分页展示的页面中,我们点击某一个旅游,想要查看详细信息,则点击了查看详情后,会跳转到该旅游路线对应的详细信息页面。接下来对该详细信息页面的查询与展示。
想要查看不同旅游线路对应相应的详细界面,我们首先观看一下数据库中两个数据表之间的关系。如下图所示:
旅游页面对应的表格内容是tab_route;详细页面中的一些信息(标题,价格)也在这个表格中;详情页面中的图片位于tab_route_img表格中,该表格与tab_route表格通过rid关联;详情页面中的商家信息位于tab_seller表格中,该表格通过sid与tab_route关联。
分析
当点击了查看详情后,会跳转到route_detail.html页面。若要该页面的内容是那一条旅游路相对应的内容,则首先需要通过一个参数来联系这三张表格;通过对这三个表格关系的分析,我们只有两个选择,第一个选择是传递sid,第二个选择是传递rid;接下来我们详细分析这两个选择方案。
方案1:选择传递sid
若传递sid。则我们可以通过sid直接查询表格tab_seller,从而获取商家信息;但是我们不能通过sid获取tab_route_img表格的信息;所以需要通过sid获取rid,再通过rid获取tab_route_img表格信息;但是由于sid有很多个,而rid只有1个,也就是说在表格中,一个sid,可能获取到很多个rid;(一个商家可能有多条旅游路线),那么就不能准确地获取到该线路对应的图片了;所以传递sid参数不行。
方案2:选择传递rid
若传递rid。一个rid可以查询到该路线对应的多张图片;同样也可以查询到该线路对应的一个商家sid;根据该商家的sid可以查询到商家的所有信息。所以传递rid参数可以实现三张表格数据的对应关系。
参数rid传递的前端实现
首先在前端点击产看详情按钮处添加rid参数的传递;具体实现代码如下:
// 在route_list.html拼接字符串处添加rid参数<p><a href="route_detail.html?rid='+route.rid+'">查看详情</a></p>\n' +
接下来在route_detail.html中编写入口函数,接收rid参数,并向服务器发送Ajax请求:
$(function () {// 获取rid参数var rid = getParameter("rid");// 向服务器发送Ajax请求;获取Route对象;并将对应数据展示到页面中。$.post("route/findOne",{rid:rid},function (route) {// 将响应的数据展示到页面中});});
接下来编写后端查询数据,并返回Route对象的代码。
后端查询旅游路线的详细信息
首先我们在与Route相关的Servlet,service,dao中添加方法;先来实现servlet的findOne方法,代码的主要内容如下:
/*** 根据rid查询旅游路线的详细信息,响应Route对象给客户端* @param request* @param response* @throws IOException*/public void findOne(HttpServletRequest request, HttpServletResponse response) throws IOException {// 接收ridString rid_str = request.getParameter("rid");// 判断rid是否为空if(rid_str == null || rid_str.length() == 0){System.out.println("rid为空,请求错误");return;}int rid = Integer.parseInt(rid_str);// 调用service层方法获取Route对象Route route = service.findOne(rid);// 将Route对象序列化为json,并响应给客户端responseJson(response,route);}
接下来编写service层的代码,service层需要通过rid去查询数据库中的三个表,并将表中的信息封装到Route对象中;对于数据库中三张表的查询,需要分别用三个dao对象进行查询,保持良好的对应关系。每张表都是通过id查询表中的全部内容,只不过有些内容是很多行,需要用集合存储,而有些数据是单独的一行,只需要用一个对象存储即可。首先编写三张表的查询代码。
先为图片查询创建一个RouteImgDao对象,在其中编写查询方法,具体代码如下:
// 定义jdbc连接对象private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 通过rid查询route_img表中该路线的图片信息* @param rid* @return*/@Overridepublic List<RouteImg> findRouteImgByRid(int rid) {// 定义存储旅游路线的详细图片集合List<RouteImg> list = null;// 定义sqlString sql = "select * from tab_route_img where rid = ? ";try {// 执行sqllist = template.query(sql, new BeanPropertyRowMapper<RouteImg>(RouteImg.class), rid);} catch (DataAccessException e) {//e.printStackTrace(); // 查询图片数据失败System.out.println("RouteImgdao查询图片数据出错!");}return list;}
然后为商家查询定义一个SellerDao对象,在其中编写查询方法,具体代码如下:
// 定义jdbc连接对象private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 通过sid查询seller表中该路线的商家信息,返回Seller对象* @param sid* @return*/@Overridepublic Seller findSellerBySid(int sid) {// 定义存储旅游路线的商家对象Seller seller = null;// 定义sqlString sql = "select * from tab_seller where sid = ? ";try {// 执行sqlseller = template.queryForObject(sql, new BeanPropertyRowMapper<Seller>(Seller.class), sid);} catch (DataAccessException e) {//e.printStackTrace(); // 查询页面数据失败System.out.println("Sellerdao中通过sid查询商家的信息出错!");}return seller;}
最后在已经编写过的RouteDao中加入通过rid查询方法,方法具体代码如下:
/*** 根据rid查询route表中该路线的信息,返回Route对象* @param rid* @return*/@Overridepublic Route findRouteByRid(int rid) {// 定义存储旅游路线的记录对象Route route = null;// 定义sqlString sql = "select * from tab_route where rid = ? ";try {// 执行sqlroute = template.queryForObject(sql,new BeanPropertyRowMapper<Route>(Route.class),rid);} catch (DataAccessException e) {//e.printStackTrace(); // 查询页面数据失败System.out.println("Routedao中通过rid查询route表中该路线的信息出错!");}return route;}
dao层编写完毕后,我们在service层调用相应的方法,完成三张表的查询,最后将查询的数据全部封装到Route对象中返回即可;该方法具体代码如下:
/*** 查询旅游详细信息方法,将数据封装到Route对象中返回* @param rid* @return*/@Overridepublic Route findOne(int rid) {// 调用dao层RouteImgDao对象方法,通过rid查询route_img表中该路线的图片信息RouteImgDao routeImgDao = new RouteImgDaoImpl();List<RouteImg> routeImgList = routeImgDao.findRouteImgByRid(rid);// 调用dao层根据rid查询route表中该路线的信息Route route = dao.findRouteByRid(rid);// 获取route中商家标识sidint sid = route.getSid();// 调用dao层SellerDao对象方法,通过sid查询seller表中该路线的商家信息SellerDao sellerDao = new SellerDaoImpl();Seller seller = sellerDao.findSellerBySid(sid);// 封装Route对象route.setRouteImgList(routeImgList);route.setSeller(seller);return route;}
至此,后端的数据查询代码已经编写完毕,接下来需要完成的是前端将响应的json数据填充到相应的位置即可。
前端数据信息的展示
前端一些静态信息的展示不难,只要取出数据放到对应标签体中即可;然而页面中有一个图片的轮播;该方法是动态的,而在页面代码中,是在加载时执行该方法;而我们所编写的入口函数,是在页面加载完毕,最后才执行的,所以存在一个方法执行的先后问题,我们需要将图片轮播代码封装为一个函数,在我们的入口函数中进行一下调用;该方法我们将其封装为goImg方法,其具体内容如下:
function goImg() {//点击图片切换图片$('.little_img').on('mousemove', function() {$('.little_img').removeClass('cur_img');var big_pic = $(this).data('bigpic');$('.big_img').attr('src', big_pic);$(this).addClass('cur_img');});//上下切换var picindex = 0;var nextindex = 4;$('.down_img').on('click',function(){var num = $('.little_img').length;if((nextindex + 1) <= num){$('.little_img:eq('+picindex+')').hide();$('.little_img:eq('+nextindex+')').show();picindex = picindex + 1;nextindex = nextindex + 1;}});$('.up_img').on('click',function(){var num = $('.little_img').length;if(picindex > 0){$('.little_img:eq('+(nextindex-1)+')').hide();$('.little_img:eq('+(picindex-1)+')').show();picindex = picindex - 1;nextindex = nextindex - 1;}});}
然后是在入口函数中将Ajax请求相应的数据进行展示,具体代码如下:
$(function () {// 获取rid参数var rid = getParameter("rid");// 向服务器发送Ajax请求;获取Route对象;并将对应数据展示到页面中。$.post("route/findOne",{rid:rid},function (route) {// 将响应的数据展示到页面中// 展示标题和详细介绍$(".pros_title").html(route.rname);$(".hot").html(route.routeIntroduce);// 展示商家信息var seller = route.seller;$("#sname").html(seller.sname);$("#consphone").html(seller.consphone);$("#address").html(seller.address);// 展示价格$("#price").html(route.price);// 展示图片var routeImgList = route.routeImgList;// 展示大图$(".big_img").attr("src",routeImgList[0].bigPic);var dd_img = '<a class="up_img up_img_disable"></a>';// 遍历图片,只展示4张,多余的设为隐藏for (var i = 0; i < routeImgList.length; i++) {var img;if(i < 4){img = ' <a title="" class="little_img" data-bigpic="'+routeImgList[i].bigPic+'">\n' +' <img src="'+routeImgList[i].smallPic+'">\n' +' </a>';}else{img = '<a title="" class="little_img" data-bigpic="'+routeImgList[i].bigPic+'" style="display:none;">\n' +' <img src="'+routeImgList[i].smallPic+'">\n' +' </a>';}dd_img += img;}dd_img += '<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';$("#route_img").html(dd_img);//调用图片展示和切换goImg();});});
至此,某一个旅游线路的详细数据查询与展示页面已经实现了。