欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

黑马旅游网编写练习(7)--某一旅游线路详情展示

程序员文章站 2022-04-03 18:33:52
...

黑马旅游网编写练习(7)–某一旅游线路详情展示

在分页展示的页面中,我们点击某一个旅游,想要查看详细信息,则点击了查看详情后,会跳转到该旅游路线对应的详细信息页面。接下来对该详细信息页面的查询与展示。
想要查看不同旅游线路对应相应的详细界面,我们首先观看一下数据库中两个数据表之间的关系。如下图所示:
黑马旅游网编写练习(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 {
        // 接收rid
        String 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
     */
    @Override
    public List<RouteImg> findRouteImgByRid(int rid) {

        // 定义存储旅游路线的详细图片集合
        List<RouteImg> list = null;

        // 定义sql
        String sql = "select * from tab_route_img where rid = ? ";

        try {
            // 执行sql
            list = 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
     */
    @Override
    public Seller findSellerBySid(int sid) {

        // 定义存储旅游路线的商家对象
        Seller seller = null;

        // 定义sql
        String sql = "select * from tab_seller where sid = ? ";

        try {
            // 执行sql
            seller = 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
     */
    @Override
    public Route findRouteByRid(int rid) {

        // 定义存储旅游路线的记录对象
        Route route = null;

        // 定义sql
        String sql = "select * from tab_route where rid = ? ";

        try {
            // 执行sql
            route = 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
     */
    @Override
    public 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中商家标识sid
        int 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();
        });
    });

至此,某一个旅游线路的详细数据查询与展示页面已经实现了。