黑马旅游前端

黑马旅游

前端访问

1.注册功能

实现效果:点击注册按钮跳转到注册页面,填写完资料后跳转注册成功页面

实现步骤:

  1. 在register.html页面添加script语句,除了传递页面参数以外,还需要获取递归函数的结果,

        //TODO 1.在register.html页面上,给注册按钮绑定单击事件;请求路径;请求参数;发送ajax请求完成用户注册功能,判断是否成功
        $("#registerBtn").click(function () {
            var url = "/user";
            //获取数据
            var data = $("#registerForm").serialize();
            $.ajax({
                url: url,
                data: data,
                dataType: "json",
                success: function () {
                    location.href = "register_ok.html";
                },
                error: function (result) {
                    alert(result.errorMsg);
                }
            })
        });
    
  2. 在userServlet页面处理业务逻辑,获取参数封装到实体,调用UserService的register()方法来处理业务逻辑,生成响应信息传回register.html页面

     /**
         * 注册的方法
         */
        public void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
            ResultInfo resultInfo = null;
            try {
                //TODO 3.获取参数;将参数请求封装到user实体中;将获取到的参数打印到控制台;
                Map<String, String[]> map = request.getParameterMap();
                User user = new User();
                BeanUtils.populate(user, map);
                System.out.println("user = " + user);
                //TODO 4.调用service处理业务逻辑;判断执行结果,生成响应信息(成功或失败)
                UserService userService = new UserService();
                boolean flag = userService.register(user);
                if (flag) {
    //                response.getWriter().write("注册成功");
                    resultInfo = new ResultInfo(true, "", "");
                } else {
    //                response.getWriter().write("注册失败");
                    resultInfo = new ResultInfo(false, "服务器忙碌", "");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                // 代码异常   -1
    //            response.getWriter().print(-1);
                resultInfo = new ResultInfo(false, "当前功能正在维护...", "");
            }
            //将对象转换成json并返回给浏览器
            String s = ObjectToJsonUtils.toJson(resultInfo);
            System.out.println("s = " + s);
            response.getWriter().print(s);
        }
    
  3. 在UserService内处理业务逻辑,实现调用UserMapper接口,完成信息入录数据库操作,返回是否成功的表示

    public class UserService {
        public boolean register(User user) {
            //TODO 2.处理业务逻辑;对密码加密MD5;获取SQLSession对象;获取dao接口的实现类
            String md5 = Md5Util.getMD5(user.getPassword());
            user.setPassword(md5);
            //获取SQLSession对象
            SqlSession session = MybatisUtils.getSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            // 调用相关的方法;返回结果
            int register = mapper.register(user);
    
            return register!=0;
        }
    }
    
    
  4. 在UserMapper页面完成register方法的SQL注解

     //TODO 5.写上sql注解
        @Insert("insert into tab_user values(null,#{username},#{password},#{name},#{birthday},#{sex}" +
                ",#{telephone},#{email})")
        int register(User user);
    
    

流程:前端页面-->servlet生成响应结果-->service完成业务逻辑-->Mapper完成SQL语句

优化:为了更好的显示信息,我们创建一个实体类描述返回值信息,描述完毕后,将该对象转成json返回给浏览器即可

// 不需要添加任何访问路径,我们不希望外界直接访问
@WebServlet()
public class BaseServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // 获取请求标识(请求标识就是要执行方法的名称)
            String action = request.getParameter("action");
            // 获取调用者类的字节码对象
            Class aClass = this.getClass();
            /*
             获取要执行的方法的字节码对象(获取公共的方法的字节码)
             否则要用到暴力反射clazz.getDeclaredMethod()获取一切权限的方法
            */
            Method method = aClass.getMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            // 反射执行方法
            method.invoke(this, request, response);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("反射方法调用异常");
        }
    }
}

完善注册功能:判断用户名是否重复

实现效果:当用户名输入框时区焦点之后,完成ajax异步校验用户名的功能

步骤:

  1. 在register.html页面内添加script语句,用ajax完成异步校验,接受校验结果,正确显示对勾,错误显示红色的错误描述

     //当用户名输入框时区焦点之后,完成ajax异步校验用户名的功能
        $("#username").blur(function () {
            //获取用户名框内的值取出多余的空
            var username = $("#username").val().trim();
            var url = "findUserServlet"//请求地址
            $.ajax({
                url: url,
                data: "username=" + username,
                dataType: "text",
                success: function (result) {
                    if (result==0) {
                        //在用户名框后面添加一个span
                        //不存在就打绿色的对勾
                        $("#usernameMsg").html("<font color='green'>√</font>")
                        //且注册按钮生效
                        $("registerBtn").attr("disabled", true);
                    } else {
                        $("#usernameMsg").html("<font color='red'>用户名已存在</font>")
                        //注册按钮失效
                        $("#registerBtn").attr("disabled", false);
                    }
                }
            })
        });
    
  2. 在findUserServlet中获取来自register输入框的用户名框的参数,调用UserService中findUser的方法,返回判断结果

    @WebServlet(urlPatterns = "/findUserServlet")
    public class FindUserServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取参数
            String username = request.getParameter("username");
            //调用findUser方法
            UserService userService = new UserService();
            boolean flag = userService.findUser(username);
            if (flag) {
                response.getWriter().println(1);
            } else {
                response.getWriter().println(0);
            }
        }
    }
    
  3. 在UserService中实现业务逻辑

        public boolean findUser(String username) {
            SqlSession session = MybatisUtils.getSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            //调用findUser方法
            User user = mapper.findUser(username);
            return user != null;
        }
    
  4. 在UserMapper中写上SQL语句注解

    @Select("select * from tab_user where username=#{username}")
        User findUser(@Param("username") String username);
    

2.用户登录

实现效果:当用户在login.html页面,当用户输入完用户名,密码和验证码之后,点击登录按钮是,向服务器发送一个ajax请求,完成登录

需求:

  • 完成验证码的校验
  • 完成用户名和密码的校验
  • 登录跳转

步骤:

  1. login.html页面完成ajax的异步请求

        //完成表单信息的传递,ajax异步请求
        $("#loginBtn").click(function () {
            var data = $("#loginForm").serialize();
            var url = "/loginServlet"
            $.ajax({
                url: url,
                data:data,
                dataType:"json",
                success: function (result) {
                    //处理返回结果
                    if (result.flag) {
                        //成功返回首页
                        location.href = "index.html";
                    } else {
                        //失败说明异常
                        $("#errorMsg").html(result.errorMsg);
                    }
                }
            })
        });
    
  2. loginServlet中获取来自login.html的参数;完成验证码的校验(不可为空,不可错误);获取携带数据,判断用户名和密码,登录成功保存登录状态并相应的生成响应结果

    @WebServlet(urlPatterns = "/loginServlet")
    public class LoginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //创建一个实体类来描述信息
            ResultInfo resultInfo = null;
            //获取来自login.html的参数
            //先判断验证码
            //获取用户输入的与验证码
            String check = request.getParameter("check");
            System.out.println("check = " + check);
            //获取系统生成的验证码
            HttpSession session = request.getSession();
            String code = (String) session.getAttribute("CHECKCODE_SERVER");
            System.out.println("code = " + code);
            //验证码为空或null
            if (check == null || check.trim() == "") {
                resultInfo = new ResultInfo(false, "验证码不可为空", "");
                //转成json返回
                String s = ObjectToJsonUtils.toJson(resultInfo);
                response.getWriter().println(s);
                return;
            }
            if (!check.equalsIgnoreCase(code)) {
                resultInfo = new ResultInfo(false, "验证码错误请重新输入", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                response.getWriter().println(s);
                return;
            }
    
            //验证用户名和密码
            try {
                Map<String, String[]> map = request.getParameterMap();
                User user = new User();
                BeanUtils.populate(user, map);
                String md5 = Md5Util.getMD5(user.getPassword());
                user.setPassword(md5);
                UserService userService = new UserService();
                User user1 = userService.login(user);
                //判断是否为空
                if (user1 != null) {
                    //保存用户信息到session中
                    session.setAttribute("user", user);
                    //转成json传回去
                    resultInfo = new ResultInfo(true, "", "");
                    String s = ObjectToJsonUtils.toJson(resultInfo);
                    response.getWriter().println(s);
                } else {
                    resultInfo = new ResultInfo(false, "用户名或密码错误", "");
                    String s = ObjectToJsonUtils.toJson(resultInfo);
                    response.getWriter().println(s);
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  3. UserService完成业务逻辑,密码进行加密,对比数据库密码,调用UserMapper中的login()方法,返回结果

       public User login(User user) {
            SqlSession session = MybatisUtils.getSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            //调用login()方法
            User u = mapper.login(user);
            return u;
        }
    
  4. UserMapper中完成SQL查询用户语句通过密码和用户名

     @Select("select * from tab_user where username=#{username} and password=#{password}")
        User login(User user);
    

登录成功后显示登录状态

实现效果:在head.html页面显示当前用户的登录状态

实现步骤:

  1. 在head.html添加页面加载成功事件,发送ajax请求,查询当前的登录状态

        //页面加载成功后加载
        $(function () {
            //请求地址
            var url = "/user";
            //因为一个servlet处理多个请求,所以设置一个请求标识
            var param = {"action": "isLogin"};
            $.ajax({
                url: url,
                data: param,
                dataType:"json",
                success: function (result) {
                    if (result.flag) {
                        $(".login").html("<span>欢迎回来,"+result.successData+"</span>\n" +
                            "            <a href=\"myfavorite.html\" class=\"collection\">我的收藏</a>\n" +
                            "            <a href=\"user?action=loginOut\">退出</a>");
                    } else {
                        // 没有用户登录
                        $(".login_out").html("<a href=\"login.html\">登录</a>\n" +
                            "            <a href=\"register.html\">注册</a>");
                    }
                },
                error:function () {
                    alert("服务器异常");
                }
            });
        });
    
  2. 在UserServlet中获取登录的user信息,直接将user转成json返回给浏览器

    //判断是否登录的方法
        public void isLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
            HttpSession session = request.getSession();
            User user = (User) session.getAttribute("user");
            ResultInfo resultInfo =null;
            //判断user是否为空
            if (user != null) {
                resultInfo = new ResultInfo(true, "", user.getUsername());
                String s = ObjectToJsonUtils.toJson(resultInfo);
                response.getWriter().println(s);
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                response.getWriter().println(s);
            }
        }
    

    3.用户退出

    实现效果:当用户点击head.html中点击退出按钮是,回到首页,显示登录和注册按钮

    实现步骤:

    1. 在head.html中给退出绑定 超链接

      //页面加载成功后加载
      $(function () {
          //请求地址
          var url = "/user";
          //因为一个servlet处理多个请求,所以设置一个请求标识
          var param = {"action": "isLogin"};
          $.ajax({
              url: url,
              data: param,
              dataType:"json",
              success: function (result) {
                  if (result.flag) {
                      $(".login").html("<span>欢迎回来,"+result.successData+"</span>\n" +
                          "            <a href=\"myfavorite.html\" class=\"collection\">我的收藏</a>\n" +
                          "            <a href=\"user?action=logout\">退出</a>");
                  } else {
                      // 没有用户登录
                      $(".login_out").html("<a href=\"login.html\">登录</a>\n" +
                          "            <a href=\"register.html\">注册</a>");
                  }
              },
              error:function () {
                  alert("服务器异常");
              }
          });
      });
      
    2. 在UserSevlet中直接销毁session,重定向到首页

       //退出登录,并重定向到首页
          public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
              //销毁session
              request.getSession().invalidate();
              //重定向
              response.sendRedirect("/index.html");
          }
      

4. 查询导航条分类信息

实现效果:当head.html页面加载成功后,将查询结果展示到导航条中

需求分析:head.html加载后,向服务器发送ajax请求,查询分类表中的信息,并将结果展示到导航条汇总,

​ 分类信息的修改频率较低,但是在多个页面都需要使用,所以采用Redis作为缓存可以有效的缓解mysql服务器的压力

实现步骤:

  1. 在header.html页面中发送ajax请求,查询分类信息;请求地址,请求标识(需要用到的方法);处理返回结果,遍历(itar)查询结果,;返回的dataType类型为json;将拼接好的字符串添加到导航条中

    $(function () {
            //页面成功后加载,查询导航栏分类信息
            //请求的页面
            var url = "/category";
            var param = {"action": "findAll"};
    
            //ajax请求
            $.ajax({
                url: url,
                data: param,
                dataType: "json",
                success: function (result) {
                    console.log(result);
                    //添加分类字符串
                    var categoryStr = "<li><a href=\"route_list.html\">门票</a></li>"
                    for (var i = 0; i < result.length; i++) {
                        categoryStr += "<li><a href=\"route_list.html?" + result[i].cid + "\">" + result[i].cname + "</a></li>"
                    }
                    categoryStr += "<li><a href=\"favoriterank.html\">收藏排行榜</a></li>";
                    //将字符串添加进nav类中
                    $(".nav").html(categoryStr);
                }
            })
        });
    
  2. 在CategoryServlet中写上findAll(方法)用来查询tab_category中的信息;调用CategoryService来处理业务逻辑;将查询结果返回给浏览器

     public void findAll(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //因为不存在用户输入,所以不需要从前端获取数据
            CategoryService categoryService = new CategoryService();
            String categoryJson = categoryService.findAll();
    
            //输出语句用于测试
            System.out.println(categoryJson);
    
            //将结果转换,返回给浏览器
            response.getWriter().println(categoryJson);
        }
    
  3. 在CategoryService中的findAll()方法中;查询时优先查询Redis数据库,获取jedis对象(操作Redis的对象);用jedis查询数据;判断有没有从Redis中查到;如果没有数据,先从mysql中查找,关闭SQLSession;将结果转换成json字符串,将json字符串放到Redis数据库中;关闭Redis连接

     public String findAll() throws JsonProcessingException {
            //优先查询Redis数据库
            Jedis jedis = new Jedis();
            //从jedis中查询数据
            String categoryJson = jedis.get("categoryJson");
    
            //判断查询到的数据是否为空,为空则从mysql中查询
            if (categoryJson == null) {
                //创建SQLSession
                SqlSession session = MybatisUtils.getSession();
                CategoryMapper mapper = session.getMapper(CategoryMapper.class);
                List<Category> categories = mapper.findAll();
                //关闭资源
                MybatisUtils.closeSession(session);
    
                //将category数据转化成json字符串
                categoryJson = ObjectToJsonUtils.toJson(categories);
                //将字符串放进jedis数据库中
                jedis.set("categoryJson", categoryJson);
            }
            //Redis关闭资源
            jedis.close();
            //返回json字符串
            return categoryJson;
        }
    
  4. 在CategoryMapper中查询分类信息,写上findAll()方法,返回list集合

    @Select("select * from tab_category")
        public List<Category> findAll();
    

5.分页查询分类下的线路信息

分页技术

Mysql:
	分页查询作用:
		降低数据库的压力: 分批次将数据查询出来
		提高用户体验度: 每次传递的数据量少
	limit: 分页关键字
		格式: 
			// 分页查询所有数据信息
			select * from 表名 limit 起始索引,每页显示条数;
			// 分页查询满足条件的数据信息
			select * from 表名 where 条件 limit 起始索引,每页显示条数;
		参数解释:
			起始索引: 从哪个索引开始
			每页显示条数: 从指定的索引向后数多少条
要想完成分页查询,有些条件是必须的:
	必须条件: 根据已知条件计算
		起始索引(startIndex) = (当前页页码-1) * 每页显示条数;
		每页显示条数(pageSize) 5
	已知条件:
		当前页码(pageNumber): 来自浏览器,用户每次发送请求时需要携带此参数
		每页显示条数(pageSize): 可以是浏览器携带的,也可以在程序中定义好

---------------------例子
每页显示5条数据
1.查询第1页的数据信息
	select * from tab_route limit 0,5;
2.查询第2页的数据信息
	select * from tab_route limit 5,5;
3.查询第3页的数据信息
	select * from tab_route limit 10,5;
.....
4.查询第30页的数据信息
	select * from tab_route limit 145,5;
.....
5.查询第n页的数据信息
	select * from tab_route limit (n-1)*5,5;

实现效果:当用户点击导航条中的分类信息时,将分类下所对应的线路信息分页查询出来

需求分析:当用户点击国内游分类时,跳转到route_list.html页面上,在该页面加载成功后,向服务器发送ajax请求,分页查询国内游分类下的线路信息,并展示到route_list.html上
实现步骤:

  1. header.html页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/jquery-3.3.1.js"></script>
    </head>
    <body>
    <!-- 头部 start -->
    <header id="header">
        <div class="top_banner">
            <img src="images/top_banner.jpg" alt="">
        </div>
        <div class="shortcut">
            <!-- 未登录状态  -->
            <div class="login_out">
                <!--            <a href="login.html">登录</a>-->
                <!--            <a href="register.html">注册</a>-->
            </div>
            <!-- 登录状态  -->
            <div class="login">
                <!--            <span>欢迎回来,admin</span>-->
                <!--            <a href="myfavorite.html" class="collection">我的收藏</a>-->
                <!--            <a href="user?action=loginOut">退出</a>-->
            </div>
        </div>
        <div class="header_wrap">
            <div class="topbar">
                <div class="logo">
                    <a href="/"><img src="images/logo.jpg" alt=""></a>
                </div>
                <div class="search">
                    <input name="rname" id="rname" type="text" placeholder="请输入路线名称" class="search_input"
                           autocomplete="off">
                    <a href="javascript:searchRoute();" class="search-button">搜索</a>
                </div>
                <div class="hottel">
                    <div class="hot_pic">
                        <img src="images/hot_tel.jpg" alt="">
                    </div>
                    <div class="hot_tel">
                        <p class="hot_time">客服热线(9:00-6:00)</p>
                        <p class="hot_num">400-618-9090</p>
                    </div>
                </div>
            </div>
        </div>
    </header>
    <!-- 头部 end -->
    <!-- 首页导航 -->
    <div class="navitem">
        <ul class="nav">
     
        </ul>
    </div>
    </body>
    
    <script>
        //页面加载成功后加载,判断是否登录
        $(function () {
            //请求地址
            var url = "/user";
            //因为一个servlet处理多个请求,所以设置一个请求标识
            var param = {"action": "isLogin"};
            $.ajax({
                url: url,
                data: param,
                dataType: "json",
                success: function (result) {
                    if (result.flag) {
                        $(".login").html("<span>欢迎回来," + result.successData + "</span>\n" +
                            "            <a href=\"myfavorite.html\" class=\"collection\">我的收藏</a>\n" +
                            "            <a href=\"user?action=logout\">退出</a>");
                    } else {
                        // 没有用户登录
                        $(".login_out").html("<a href=\"login.html\">登录</a>\n" +
                            "            <a href=\"register.html\">注册</a>");
                    }
                },
                error: function () {
                    alert("服务器异常");
                }
            });
        });
        $(function () {
            //页面成功后加载,查询导航栏分类信息
            //请求的页面
            var url = "/category";
            var param = {"action": "findAll"};
    
            //ajax请求
            $.ajax({
                url: url,
                data: param,
                dataType: "json",
                success: function (result) {
                    console.log(result);
                    //添加分类字符串
                    var categoryStr = "<li><a href=\"route_list.html\">门票</a></li>"
                    for (var i = 0; i < result.length; i++) {
                        categoryStr += "<li><a href=\"route_list.html?cid=" + result[i].cid + "\">" + result[i].cname + "</a></li>"
                    }
                    categoryStr += "<li><a href=\"favoriterank.html\">收藏排行榜</a></li>";
                    //将字符串添加进nav类中
                    $(".nav").html(categoryStr);
                },
                error:function () {
                    alert("服务器异常");
                }
            })
        });
    </script>
    </html>
    

    2.RouteServlet页面

@WebServlet(urlPatterns = "/routeServlet")
public class RouteServlet extends BaseServlet {


    public void findRouteByPage(HttpServletRequest request, HttpServletResponse response) throws IOException {

        //1.获取当前页码数和类别的id
        int currentPage = Integer.parseInt(request.getParameter("currentPage"));
        int cid = Integer.parseInt(request.getParameter("cid"));

        String rname = request.getParameter("rname");


        //2.调用service查询数据
        RouteService routeService = new RouteService();
        PageBean pageBean = routeService.findRouteByPage(currentPage,cid,rname);

        //3.给出响应
        ResultInfo resultInfo = new ResultInfo();
        resultInfo.setSuccessData(pageBean);
        String jsonStr = new ObjectMapper().writeValueAsString(resultInfo);

        response.getWriter().write(jsonStr);
    }
}

3.RouteService页面

public class RouteService  {

    public PageBean findRouteByPage(int currentPage, int cid, String rname) {

        PageBean pageBean = new PageBean();
        //1.当前页面数
        pageBean.setCurrentPage(currentPage);

        //2.上一页
        pageBean.setPrePage(currentPage-1);

        //3.下一页
        pageBean.setNextPage(currentPage+1);

        //4.数据的总数量
//        RouteMapper routeMapper = MybatisUtils.getProxyMapper(RouteMapper.class);
        SqlSession session = MybatisUtils.getSession();
        RouteMapper mapper = session.getMapper(RouteMapper.class);
        int totalCount = mapper.findTotalCountByCid(cid,rname);
        pageBean.setTotalCount(totalCount);
        //5.定义默认每页显示的数量  pageSize
        int pageSize = 6;

        //6.总页码数
        /**
         *  100   10    10
         *  101   10    11
         *
         */
        int totalPage = totalCount%pageSize==0?totalCount/pageSize:(totalCount/pageSize+1);
        pageBean.setTotalPage(totalPage);


        //7.分页页面需要的旅游线路信息
     /*   -- 每页查询5条数据
                -- 第一页  1,2,3,4,5
        select * from tab_route  limit 0,5
                -- 第二页  6,7,8,9,0
        select * from tab_route  limit  5,5
                -- 第三页   11,12,13,14,15
        select * from tab_route  limit  10,5

                -- 第currentPage页
        select * from tab_route  limit   (currentPage-1)*pageSize,pageSize
        */
        int start = (currentPage-1)*pageSize;
        List<Route> routeList = mapper.findRouteByPage(start, pageSize,cid,rname);
        pageBean.setRouteList(routeList);

        return pageBean;
    }
}

4.RouteMapper页面

public interface RouteMapper {

    @SelectProvider(type = RouteSql.class,method = "findTotalCountByCid")
    public int findTotalCountByCid(@Param("cid") int cid, @Param("rname") String rname);

    @SelectProvider(type = RouteSql.class,method ="findRouteByPage")
    public List<Route> findRouteByPage(@Param("start") int start, @Param("pageSize") int pageSize, @Param("cid") int cid, @Param("rname") String rname);

}

5.RouteSQL页面

public class RouteSql {

    public String findTotalCountByCid(@Param("cid") int cid, @Param("rname") String rname){

        String sql = "select count(*) from tab_route where cid=#{cid} ";
        if(rname!=null&&rname.length()>0){
            sql+=" and rname like concat('%',#{rname},'%')";
        }
        return sql;
    }


    public String findRouteByPage(@Param("start") int start, @Param("pageSize") int pageSize, @Param("cid") int cid, @Param("rname") String rname){
        String sql = "select * from tab_route where cid=#{cid} ";
        if(rname!=null&&rname.length()>0){
            sql+=" and rname like concat('%',#{rname},'%') ";
        }
        sql+=" limit #{start},#{pageSize} ";
        return sql;
    }
}

6.查询旅游线路的详情

  1. route_detail.html页面

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8">
        <title>路线详情</title>
        <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" type="text/css" href="css/route-detail.css">
    </head>
    
    <body>
    <!--引入头部-->
    <div id="header"></div>
    <!-- 详情 start -->
    <div class="wrap">
        <div class="bread_box">
    <!--        <a href="/">首页</a>-->
    <!--        <span> &gt;</span>-->
    <!--        <a href="#">国内游</a><span> &gt;</span>-->
    <!--        <a href="#">全国-曼谷6-7天自由行 泰国出境旅游 特价往返机票自由行二次确认</a>-->
        </div>
        <div class="prosum_box">
            <dl class="prosum_left">
                <dt>
                    <img alt="" class="big_img" >
                </dt>
                <dd>
                    <a class="up_img up_img_disable" id="picture"></a>
    <!--                <a title="" class="little_img" data-bigpic="img/product/size4/m42bdf1849b307712c4a0843b89ed83b5f.jpg">-->
    <!--                    <img src="img/product/size2/m22bdf1849b307712c4a0843b89ed83b5f.jpg">-->
                    </a>
    
                    <a class="down_img down_img_disable" style="margin-bottom: 0;"></a>
                </dd>
            </dl>
            <div class="prosum_right">
                <p class="pros_title"></p>
                <p class="hot"></p>
                <div class="pros_other">
    <!--                <p>经营商家  :黑马国旅</p>-->
    <!--                <p>咨询电话 : 400-618-9090</p>-->
    <!--                <p>地址 : 传智播客黑马程序员</p>-->
                </div>
                <div class="pros_price">
                    <p class="price"><strong></strong><span>起</span></p>
                    <p class="collect">
                        <a class="btn"><i class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>
                        <a  class="btn already" disabled="disabled"><i class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>
                        <span id="collecting"></span>
                    </p>
                </div>
            </div>
        </div>
        <div class="you_need_konw">
            <span>旅游须知</span>
            <div class="notice">
                <p>1、旅行社已投保旅行社责任险。建议游客购买旅游意外保险 <br>
    
                <p>2、旅游者参加打猎、潜水、海边游泳、漂流、滑水、滑雪、滑草、蹦极、跳伞、滑翔、乘热气球、骑马、赛车、攀岩、水疗、水上飞机等属于高风险性游乐项目的,敬请旅游者务必在参加前充分了解项目的安全须知并确保身体状况能适应此类活动;如旅游者不具备较好的身体条件及技能,可能会造成身体伤害。</p>
    
                <p>3、参加出海活动时,请务必穿着救生设备。参加水上活动应注意自己的身体状况,有心脏病、冠心病、高血压、感冒、发烧和饮酒及餐后不可以参加水上活动及潜水。在海里活动时,严禁触摸海洋中各种鱼类,水母,海胆,珊瑚等海洋生物,避免被其蛰伤。老人和小孩必须有成年人陪同才能参加合适的水上活动。在海边游玩时,注意保管好随身携带的贵重物品。</p>
    
                <p>4、根据中国海关总署的规定,旅客在境外购买的物品,在进入中国海关时可能需要征收关税。详细内容见《中华人民共和国海关总署公告2010年第54号文件》。</p>
    
                <p>5、建议出发时行李托运,贵重物品、常用物品、常用药品、御寒衣物等请随身携带,尽量不要托运。行李延误属于不可抗力因素,我司将全力协助客人跟进后续工作,但我司对此不承担任何责任。</p>
                <p>1、旅行社已投保旅行社责任险。建议游客购买旅游意外保险 <br>
    
                <p>2、旅游者参加打猎、潜水、海边游泳、漂流、滑水、滑雪、滑草、蹦极、跳伞、滑翔、乘热气球、骑马、赛车、攀岩、水疗、水上飞机等属于高风险性游乐项目的,敬请旅游者务必在参加前充分了解项目的安全须知并确保身体状况能适应此类活动;如旅游者不具备较好的身体条件及技能,可能会造成身体伤害。</p>
    
                <p>3、参加出海活动时,请务必穿着救生设备。参加水上活动应注意自己的身体状况,有心脏病、冠心病、高血压、感冒、发烧和饮酒及餐后不可以参加水上活动及潜水。在海里活动时,严禁触摸海洋中各种鱼类,水母,海胆,珊瑚等海洋生物,避免被其蛰伤。老人和小孩必须有成年人陪同才能参加合适的水上活动。在海边游玩时,注意保管好随身携带的贵重物品。</p>
    
                <p>4、根据中国海关总署的规定,旅客在境外购买的物品,在进入中国海关时可能需要征收关税。详细内容见《中华人民共和国海关总署公告2010年第54号文件》。</p>
    
                <p>5、建议出发时行李托运,贵重物品、常用物品、常用药品、御寒衣物等请随身携带,尽量不要托运。行李延误属于不可抗力因素,我司将全力协助客人跟进后续工作,但我司对此不承担任何责任。</p>
            </div>
        </div>
    </div>
    <!-- 详情 end -->
    
    <!--引入头部-->
    <div id="footer"></div>
    <script src="js/jquery-3.3.1.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    <script src="js/getParameter.js"></script>
    <script>
        $(function () {
            var rid = getParameter("rid");
            $.ajax({
                url: "routeServlet",
                data: {
                    "action":"findRouteDetailByRid",
                    "rid":rid
                },
                dataType: "json",
                success: function (result) {
                    //首页/国内游/旅游路线名称
                    $(".bread_box").html("<a href=\"/\">首页</a>\n" +
                        "        <span> &gt;</span>\n" +
                        "        <a href=\"#\">"+result.successData.category.cname+"</a><span> &gt;</span>\n" +
                        "        <a href=\"#\">"+result.successData.rname+"</a>");
                    //图片
                    var routeImgList = result.successData.routeImgList;
                    for (var i = 0; i < routeImgList.length; i++) {
                        var $p=$("<a title=\"\" class=\"little_img\" data-bigpic=\""+routeImgList[i].bigPic+"\">\n" +
                            "                    <img src=\""+routeImgList[i].smallPic+"\">")
                        $("#picture").after($p);
                    };
                    //旅游线路信息
                    $(".pros_title").html(result.successData.rname);
                    $(".hot").html(result.successData.routeIntroduce);
                    $("strong").html(result.successData.price);
                    $(".big_img").attr("src", result.successData.rimage);
                    $("#collecting").html("已收藏" + result.successData.count + "次");
    
                    //商家信息
                    $(".pros_other").html(" <p> 经营商家 : "+result.successData.seller.sname+"</p>\n" +
                        "                <p>咨询电话 : "+result.successData.seller.consphone+"</p>\n" +
                        "                <p>地址 : "+result.successData.seller.address+"</p>")
    
                },
                error: function () {
                    alert("服务器内部异常")
                }
            });
        });
    
    
    
    
        $(function() {
            //前端的轮播图代码
            lunbotu();
        });
    
    
        //轮播图效果函数
        function lunbotu() {
            //焦点图效果
            //点击图片切换图片
            $('.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;
                }
            });
            //自动播放
            var timer = setInterval("auto_play()", 2000);
        }
    
        //自动轮播方法
        function auto_play() {
            var cur_index = $('.prosum_left dd').find('a.cur_img').index();
            cur_index = cur_index - 1;
            var num = $('.little_img').length;
            var max_index = 3;
            if ((num - 1) < 3) {
                max_index = num - 1;
            }
            if (cur_index < max_index) {
                var next_index = cur_index + 1;
                var big_pic = $('.little_img:eq(' + next_index + ')').data('bigpic');
                $('.little_img').removeClass('cur_img');
                $('.little_img:eq(' + next_index + ')').addClass('cur_img');
                $('.big_img').attr('src', big_pic);
            } else {
                var big_pic = $('.little_img:eq(0)').data('bigpic');
                $('.little_img').removeClass('cur_img');
                $('.little_img:eq(0)').addClass('cur_img');
                $('.big_img').attr('src', big_pic);
            }
        }
    </script>
    </body>
    </html>
    
  2. RouteServlet

    //localhost:8080/routeServlet?action=findRouteDetailByRid&rid=1
        //查询线路具体详情信息
        public void findRouteDetailByRid(HttpServletRequest request,HttpServletResponse  response) throws IOException {
            //获取来自route_list.html的rid
            int rid = Integer.parseInt(request.getParameter("rid"));
    
            //调用service查询数据
            RouteService routeService = new RouteService();
            Route routeDetail=routeService.findRouteDetailByRid(rid);
    
            //给出响应
            ResultInfo resultInfo = new ResultInfo();
            resultInfo.setSuccessData(routeDetail);
            String s = JSON.toJSONString(resultInfo);
    
            response.getWriter().write(s);
    
  3. RouteService

    public Route findRouteDetailByRid(int rid) {
            //使用MyBatis的主要Java接口session
            SqlSession session = MybatisUtils.getSession();
            RouteMapper mapper = session.getMapper(RouteMapper.class);
            Route route = mapper.findRouteDetailByRid(rid);
            return route;
        }
    
  4. RouterMapper

    @Results({
            @Result(property = "category", column = "cid", one = @One(select = "com.evilposeidon.dao.CategoryMapper.findCategoryByCid", fetchType = FetchType.LAZY)),
            @Result(property = "seller", column = "sid", one = @One(select = "com.evilposeidon.dao.SellerMapper.findSellerBySid", fetchType = FetchType.LAZY)),
            @Result(property = "routeImgList",column = "rid",many =@Many(select = "com.evilposeidon.dao.RouteImgMapper.findRouteImgByRid",fetchType = FetchType.LAZY))
    })
    @Select("select * from tab_route where rid=#{rid}")
    Route findRouteDetailByRid(@Param("rid") int rid);
    
  5. CategoryMapper

    @Select("select * from tab_category where cid=#{cid}")
    Category findCategoryByCid(int cid);
    
  6. SellerMapper

    public interface SellerMapper {
        @Select("select * from tab_seller where sid=#{sid}")
        public Seller findSellerBySid(int sid);
    
    }
    
  7. RouteImgMappep

    public interface RouteImgMapper {
    
        @Select("select * from tab_route_img where rid=#{rid}")
        List<RouteImg> findRouteImgByRid(int rid);
    
    }
    

7.收藏按钮实现

  1. route_detail.html

    //查看是否收藏
        $(function () {
            var rid = getParameter("rid");
            $.ajax({
                url: "favorite",
                data:{"action": "isFavorite","rid":rid},
                dataType:"json",
                success:function (result) {
                    if (result.successData) {
                        $("#collecting").before("<a  class=\"btn already\" disabled=\"disabled\"><i class=\"glyphicon glyphicon-heart-empty\"></i>点击收藏</a>");
                    } else {
                        $("#collecting").before("<a class=\"btn\" href=\"javaScript:click()\"><i class=\"glyphicon glyphicon-heart-empty\"></i>点击收藏</a>")
                    }
                },
                error: function () {
                    alert("服务器内部异常")
                }
            })
        })
    
  2. FavoriteServlet

    //判断是否登录
        public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //创建一个结果信息
            ResultInfo resultInfo = null;
    
            //判断是否登录
            User user = (User) request.getSession().getAttribute("user");
            System.out.println("user = " + user);
            if (user != null) {
                //获取参数
                int rid = Integer.parseInt(request.getParameter("rid"));
                int uid = user.getUid();
    
                //调用service
                FavoriteService favoriteService = new FavoriteService();
                //返回true意味着存在收藏
                boolean flag = favoriteService.isFavorite(rid, uid);
    
                resultInfo = new ResultInfo(true, "", flag);
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            }
        }
    
  3. FavoriteService

    //判断是否登录
        public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //创建一个结果信息
            ResultInfo resultInfo = null;
    
            //判断是否登录
            User user = (User) request.getSession().getAttribute("user");
            System.out.println("user = " + user);
            if (user != null) {
                //获取参数
                int rid = Integer.parseInt(request.getParameter("rid"));
                int uid = user.getUid();
    
                //调用service
                FavoriteService favoriteService = new FavoriteService();
                //返回true意味着存在收藏
                boolean flag = favoriteService.isFavorite(rid, uid);
    
                resultInfo = new ResultInfo(true, "", flag);
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            }
        }
    
  4. FavoriteMapper

    @Select("select * from tab_favorite where rid=#{rid} and uid=#{uid}")
        Favorite isFavorite(@Param("rid") int rid, @Param("uid") int uid);
    

8.收藏功能实现

image-20200729203200118

  1. route_detail.html页面内

     //点击收藏功能
        function click() {
            var rid = getParameter("rid");
            $.ajax({
                url: "favorite",
                data: {"action": "addFavorite", "rid": rid},
                dataType: "json",
                success: function (result) {
                    if (result.flag) {
                        if (result.successData != 0) {
                            $("#collecting").html("已收藏" + result.successData + "次");
                            $(".btn").remove();
                            $("#collecting").before("<a  class=\"btn already\" disabled=\"disabled\"><i class=\"glyphicon glyphicon-heart-empty\"></i>点击收藏</a>")
                            alert("收藏成功");
                        } else {
                            alert("收藏失败");
                        }
                    } else {
                        alert("用户未登录")
                        location.href = "login.html";
                    }
                },
                error: function () {
                    alert("服务器内部异常");
                }
            })
        }
    
  2. FavoriteServlet页面

    public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //创建结果信息
        ResultInfo resultInfo = null;
    
        //判断是否登录
        User user = (User) request.getSession().getAttribute("user");
        System.out.println("user = " + user);
    
        if (user != null) {
            //获取参数
            int rid = Integer.parseInt(request.getParameter("rid"));
            int uid = user.getUid();
            System.out.println("uid = " + uid);
    
            //调用service
            FavoriteService favoriteService = new FavoriteService();
            int count = favoriteService.addFavorite(rid, uid);
    
            //判断返回的数据是否为0,为0则收藏失败
            if (count != 0) {
                //给出响应
                resultInfo = new ResultInfo(true, "", count);
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //给出响应
                response.getWriter().println(s);
            } else {
                //给出响应
                resultInfo = new ResultInfo(true, "用户收藏失败", "");
            }
    
        } else {
            resultInfo = new ResultInfo(false, "用户未登录", "");
            String s = ObjectToJsonUtils.toJson(resultInfo);
            //给出响应
            response.getWriter().println(s);
        }
    }
    
  3. FavoriteService页面

    public int addFavorite(int rid, int uid) {
            SqlSession session = MybatisUtils.getSession2();
            //路线的收藏数
            int count = 0;
            try {
                //开启事务
                RouteMapper routeMapper = session.getMapper(RouteMapper.class);
                FavoriteMapper favoriteMapper = session.getMapper(FavoriteMapper.class);
                //保存数据
                favoriteMapper.safeData(rid, uid);
                //更新路线表中的count数据
                routeMapper.updateRouteCountByRid(rid);
                //查询路线表中的数据
                count = routeMapper.findRouteCountByRid(rid);
    
                //成功之后提交数据,关闭连接
                MybatisUtils.closeSession2(session);
                return count;
            } catch (Exception e) {
                //回滚事务
                MybatisUtils.rollback(session);
                e.printStackTrace();
            }
    
            return count;
        }
    
  4. RouteMapper

     @Update("update tab_route set count=count+1 where rid=#{rid}")
        void updateRouteCountByRid(@Param("rid")int rid);
    
        @Select("select count from tab_route where rid=#{rid}")
        int findRouteCountByRid(@Param("rid") int rid);
    
  5. FavoriteMapper

    @Insert("insert into tab_favorite values(#{rid},now(),#{uid})")
        void safeData(@Param("rid")int rid,@Param("uid") int uid);
    

9.查看我的收藏 功能与收藏排行榜功能

  1. myfavorite.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>黑马旅游网-我的收藏</title>
        <link href="css/bootstrap.min.css" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" href="css/index.css">
        <link rel="stylesheet" href="css/skin/laypage.css">
        <style>
            .tab-content .row > div {
                margin-top: 16px;
            }
    
            .tab-content {
                margin-bottom: 36px;
            }
        </style>
        <script src="js/jquery-3.3.1.js"></script>
    </head>
    <body>
    <!--引入头部-->
    <div id="header"></div>
    <!-- 排行榜 start-->
    <section id="content">
        <section class="hemai_jx">
            <div class="jx_top">
                <div class="jx_tit">
                    <img src="images/icon_5.jpg" alt="">
                    <span>我的收藏</span>
                </div>
            </div>
            <div class="jx_content">
                <!-- Tab panes -->
                <div class="tab-content">
                    <div role="tabpanel" class="tab-pane active" id="home">
                        <div class="row">
                            <!--                                <div class="col-md-3">-->
                            <!--                                    <a href="route_detail.html">-->
                            <!--                                        <img src="images/collection_pic.jpg" alt="">-->
                            <!--                                        <div class="has_border">-->
                            <!--                                            <h3>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</h3>-->
                            <!--                                            <div class="price">网付价<em>¥</em><strong>889</strong><em>起</em></div>-->
                            <!--                                        </div>-->
                            <!--                                    </a>-->
                            <!--                                </div>-->
                        </div>
                    </div>
                </div>
            </div>
            <div class="pageNum">
                <ul id="laypage">
    
                </ul>
            </div>
        </section>
    </section>
    <!-- 排行榜 end-->
    
    <!--引入尾部-->
    <div id="footer"></div>
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    <script type="text/javascript" src="js/getParameter.js"></script>
    <script type="text/javascript" src="js/laypage.js"></script>
    </body>
    <script>
        var currentPage = 1
    
        //页面加载完
        $(function () {
            findMyFavorite(currentPage);
        });
    
    
        function findMyFavorite(currentPage) {
            var url = "favorite";
            var action = "findMyFavorite";
            var pageSize = 2;//当前页显示的条数
    
            $.ajax({
                url: url,
                data: {"action": action, "currentPage": currentPage, "pageSize": pageSize},
                dataType: "json",
                success: function (result) {
                    if (result.flag) {
    
                        //清空
                        $(".row").empty();
                        var successData = result.successData.list;
                        var totalSize = successData.length;
                        var count = result.successData.count;
                        //总页数
                        var totalPage = count / pageSize;
                        //输出总页数
                        console.log(totalPage)
    
    
                        for (var i = 0; i < totalSize; i++) {
                            var data = successData[i];
                            var jsonStr = "<div class=\"col-md-3\">\n" +
                                "              <a href=\"route_detail.html?rid=" + data.rid + "\">\n" +
                                "                  <img src=\"" + data.rimage + "\" alt=\"\">\n" +
                                "                  <div class=\"has_border\">\n" +
                                "                      <h3>" + data.rname + "</h3>\n" +
                                "                      <div class=\"price\">网付价<em>¥</em><strong>" + data.price + "</strong><em>起</em>" + data.date + "</div>\n" +
                                "                  </div>\n" +
                                "              </a>\n" +
                                "          <div class=\"col-md-3\">";
                            $(".row").append(jsonStr);
                        }
                        //2.分页工具栏
                        //调用分页插件(简洁方式)
                        laypage({
                            cont: "laypage", //用于展现分页信息数据的容器标签id名
                            pages: totalPage,    //通过后台拿到的总页数
                            curr: currentPage,    //当前页
                            skin: '#ffc900', //设置当前页样式,可以使用内置皮肤(yahei),也可以直接赋值16进制颜色值,如:#c00
                            groups: 10,//设置连续显示分页数字的页码的个数
                            jump: function (obj, first) { //第一次执行插件代码和用户点击不同页码时候触发运行的函数
                                //参数1:obj,这个参数有个属性curr,也就是obj.curr是用户点击要访问的页码
                                //参数2:first,当第一次运行插件代码时first为true,页面上就有分页信息了。
                                //       以后用户通过分页信息点击不同页码时会触发这个函数运行到这里first为false
                                if (!first) {
                                    //用户点击不同页码时调用服务器端获取obj.curr指定页码数据更新页面上的数据
                                    findMyFavorite(obj.curr);
                                }
                            }
                        });
    
    
                    } else {
                        alert(result.errorMsg);
                        location.href = "login.html?backUrl=" + location.href;
                    }
                },
                error: function () {
                    alert("服务器内部异常");
                }
            });
        }
    
    </script>
    </html>
    
  2. favorite.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>收藏排行榜</title>
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" type="text/css" href="css/ranking-list.css">
        <link rel="stylesheet" href="css/skin/laypage.css">
        <script src="js/jquery-3.3.1.js"></script>
    </head>
    <body>
    <!--引入头部-->
    <div id="header"></div>
    <div class="contant">
        <div class="shaixuan">
            <span>线路名称</span>
            <input id="rname2" type="text">
            <span>金额</span>
            <input type="text" id="minPrice">~<input type="text" id="maxPrice">
            <button type="button" onclick="searchRankData();">搜索</button>
        </div>
        <div class="list clearfix">
            <ul id="favoriteRank">
                <!--            <li>-->
                <!--                <span class="num one">1</span>-->
                <!--                <a href="route_detail.html"><img src="images/jiangxuan_4.jpg" alt=""></a>-->
                <!--                <h4><a href="route_detail.html">【尾单特卖】全国-曼谷6-7天自由行 泰国出境旅游 特价往6-7天自由行 泰国出境旅游 特价往..</a></h4>-->
                <!--                <p>-->
                <!--                    <b class="price">&yen;<span>899</span>起</b>-->
                <!--                    <span class="shouchang">已收藏450次</span>-->
                <!--                </p>-->
                <!--            </li>-->
            </ul>
        </div>
        <div class="pageNum">
            <ul id="laypage">
                <!--                    <li><a href="">首页</a></li>-->
                <!--                    <li class="threeword"><a href="#">上一页</a></li>-->
                <!--                    <li><a href="#">1</a></li>-->
                <!--                    <li><a href="#">2</a></li>-->
                <!--                    <li><a href="#">3</a></li>-->
                <!--                    <li><a href="#">4</a></li>-->
                <!--                    <li><a href="#">5</a></li>-->
                <!--                    <li><a href="#">6</a></li>-->
                <!--                    <li><a href="#">7</a></li>-->
                <!--                    <li><a href="#">8</a></li>-->
                <!--                    <li><a href="#">9</a></li>-->
                <!--                    <li><a href="#">10</a></li>-->
                <!--                    <li class="threeword"><a href="javascript:;">下一页</a></li>-->
                <!--                    <li class="threeword"><a href="javascript:;">末页</a></li>-->
            </ul>
        </div>
    </div>
    
    <!--导入底部-->
    <div id="footer"></div>
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    <script type="text/javascript" src="js/getParameter.js"></script>
    <script type="text/javascript" src="js/laypage.js"></script>
    </body>
    <script>
        //初始页面为1
        var currentPage = 1;
        var rname = "";
        var minPrice = "";
        var maxPrice = "";
        var pageSize = 12;
    
        function searchRankData() {
            //获取用户输入的搜索内容
            rname=$("#rname2").val();
            minPrice=$("#minPrice").val();
            maxPrice=$("#maxPrice").val();
            favoriteRank(currentPage);
        }
    
        //页面加载完
        $(function () {
            favoriteRank(currentPage);
        });
    
        function favoriteRank(currentPage) {
            $.ajax({
                url: "favorite",
                data: {
                    "action": "favoriteRank",
                    "rname": rname,
                    "maxPrice": maxPrice,
                    "minPrice": minPrice,
                    "currentPage": currentPage,
                    "pageSize": pageSize
                },
                dataType: "json",
                success: function (res) {
    
                    //清空数据
                    $("#favoriteRank").empty();
    
                    var data = res.successData.routeList;
                    var count = res.successData.totalCount;
                    var pageNumber = res.successData.currentPage;
                    var totalPage = res.successData.totalPage;
    
                    //序号
                    for (var i = 0; i < data.length; i++) {
                        var number = (currentPage - 1) * 12 + 1 + i;
                        var route = data[i];
                        var jsonStr = "<li>\n" +
                            "                <span class=\"num one\">" + number + "</span>\n" +
                            "                <a href=\"route_detail.html?rid=" + route.rid + "\"><img src=\"" + route.rimage + "\" alt=\"\"></a>\n" +
                            "                <h4><a href=\"route_detail.html?rid=" + route.rid + "\">" + route.rname + "</a></h4>\n" +
                            "                <p>\n" +
                            "                    <b class=\"price\">&yen;<span>" + route.price + "</span>起</b>\n" +
                            "                    <span class=\"shouchang\">已收藏" + route.count + "次</span>\n" +
                            "                </p>\n" +
                            "            </li>";
                        $("#favoriteRank").append(jsonStr);
                    }
    
                    //2.分页工具栏
                    //调用分页插件(简洁方式)
                    laypage({
                        cont: "laypage", //用于展现分页信息数据的容器标签id名
                        pages: totalPage,    //通过后台拿到的总页数
                        curr: pageNumber,    //当前页
                        skin: '#ffc900', //设置当前页样式,可以使用内置皮肤(yahei),也可以直接赋值16进制颜色值,如:#c00
                        groups: 10,//设置连续显示分页数字的页码的个数
                        jump: function (obj, first) { //第一次执行插件代码和用户点击不同页码时候触发运行的函数
                            //参数1:obj,这个参数有个属性curr,也就是obj.curr是用户点击要访问的页码
                            //参数2:first,当第一次运行插件代码时first为true,页面上就有分页信息了。
                            //       以后用户通过分页信息点击不同页码时会触发这个函数运行到这里first为false
                            if (!first) {
                                //用户点击不同页码时调用服务器端获取obj.curr指定页码数据更新页面上的数据
                                favoriteRank(obj.curr);
                            }
                        }
                    });
                }
            });
        }
    </script>
    
    
    </html>
    
  3. FavoriteServlet

    package com.evilposeidon.web;
    
    import com.alibaba.fastjson.JSON;
    import com.evilposeidon.pojo.*;
    import com.evilposeidon.service.FavoriteService;
    import com.evilposeidon.utils.ObjectToJsonUtils;
    import com.evilposeidon.web.base.BaseServlet;
    import redis.clients.jedis.Jedis;
    
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    
    @WebServlet(urlPatterns = "/favorite")
    public class FavoriteServlet extends BaseServlet {
        public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //创建结果信息
            ResultInfo resultInfo = null;
    
            //判断是否登录
            User user = (User) request.getSession().getAttribute("user");
            System.out.println("user = " + user);
    
            if (user != null) {
                //获取参数
                int rid = Integer.parseInt(request.getParameter("rid"));
                int uid = user.getUid();
                System.out.println("uid = " + uid);
    
                //调用service
                FavoriteService favoriteService = new FavoriteService();
                int count = favoriteService.addFavorite(rid, uid);
    
                //判断返回的数据是否为0,为0则收藏失败
                if (count != 0) {
                    //给出响应
                    resultInfo = new ResultInfo(true, "", count);
                    String s = ObjectToJsonUtils.toJson(resultInfo);
                    //给出响应
                    response.getWriter().println(s);
                } else {
                    //给出响应
                    resultInfo = new ResultInfo(true, "用户收藏失败", "");
                }
    
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //给出响应
                response.getWriter().println(s);
            }
        }
    
        //判断是否登录
        public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //创建一个结果信息
            ResultInfo resultInfo = null;
    
            //判断是否登录
            User user = (User) request.getSession().getAttribute("user");
            System.out.println("user = " + user);
            if (user != null) {
                //获取参数
                int rid = Integer.parseInt(request.getParameter("rid"));
                int uid = user.getUid();
    
                //调用service
                FavoriteService favoriteService = new FavoriteService();
                //返回true意味着存在收藏
                boolean flag = favoriteService.isFavorite(rid, uid);
    
                resultInfo = new ResultInfo(true, "", flag);
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                //返回响应
                response.getWriter().println(s);
            }
        }
    
        public void findMyFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //创建信息集
            ResultInfo resultInfo = null;
    
            //获取参数,当前页面数和用户
            int currentPage = Integer.parseInt(request.getParameter("currentPage"));
            int pageSize=Integer.parseInt(request.getParameter("pageSize"));
            User user = (User) request.getSession().getAttribute("user");
    
            //判断是否登录
            if (user != null) {
                FavoriteService favoriteService = new FavoriteService();
                PageBean2 pageBean2 = favoriteService.findMyFavorite(user, currentPage,pageSize);
    
                //响应数据
                resultInfo = new ResultInfo(true, "", pageBean2);
                String s = JSON.toJSONString(resultInfo);
                response.getWriter().println(s);
            } else {
                resultInfo = new ResultInfo(false, "用户未登录", "");
                String s = ObjectToJsonUtils.toJson(resultInfo);
                response.getWriter().println(s);
            }
        }
    
        //最喜爱排行榜
        public void favoriteRank(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
            //创建结果信息返回前端
            ResultInfo resultInfo = null;
            //从前端获取参数
            String rname = request.getParameter("rname");
            String maxPrice = request.getParameter("maxPrice");
            String minPrice = request.getParameter("minPrice");
            int currentPage = Integer.parseInt(request.getParameter("currentPage"));
            int pageSize = Integer.parseInt(request.getParameter("pageSize"));
    
            //创建favoriteService
            FavoriteService favoriteService = new FavoriteService();
            PageBean3 pageBean3 = favoriteService.findFavoriteRank(rname,minPrice,maxPrice,currentPage,pageSize);
    
            //把消息装进结果信息中
            resultInfo = new ResultInfo(true, "", pageBean3);
            String s = JSON.toJSONString(resultInfo);
            response.getWriter().println(s);
        }
    
    }
    
    
  4. FavoriteService

    package com.evilposeidon.service;
    
    import com.evilposeidon.dao.FavoriteMapper;
    import com.evilposeidon.dao.RouteMapper;
    import com.evilposeidon.pojo.*;
    import com.evilposeidon.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    
    import java.util.List;
    
    public class FavoriteService {
    
        public int addFavorite(int rid, int uid) {
            SqlSession session = MybatisUtils.getSession2();
            //路线的收藏数
            int count = 0;
            try {
                //开启事务
                RouteMapper routeMapper = session.getMapper(RouteMapper.class);
                FavoriteMapper favoriteMapper = session.getMapper(FavoriteMapper.class);
                //保存数据
                favoriteMapper.safeData(rid, uid);
                //更新路线表中的count数据
                routeMapper.updateRouteCountByRid(rid);
                //查询路线表中的数据
                count = routeMapper.findRouteCountByRid(rid);
    
                //成功之后提交数据,关闭连接
                MybatisUtils.closeSession2(session);
                return count;
            } catch (Exception e) {
                //回滚事务
                MybatisUtils.rollback(session);
                e.printStackTrace();
            }
    
            return count;
        }
    
        public boolean isFavorite(int rid, int uid) {
            //获取session
            SqlSession session = MybatisUtils.getSession();
    
            FavoriteMapper mapper = session.getMapper(FavoriteMapper.class);
            Favorite favorite=mapper.isFavorite(rid,uid);
    
            //返回true意味着存在收藏
            return favorite != null;
        }
    
        public PageBean2 findMyFavorite(User user, int currentPage, int pageSize) {
    
            //获取session
            SqlSession session = MybatisUtils.getSession();
            FavoriteMapper mapper = session.getMapper(FavoriteMapper.class);
            int uid = user.getUid();
            int start=(currentPage-1)*pageSize;
            List<FavoritePage> favoritePageList=mapper.findMyFavorite(uid,start,pageSize);
            int favoriteCount = mapper.findFavoriteCount();
    
            PageBean2 pageBean2 = new PageBean2(favoriteCount, favoritePageList);
    
            //返回数据
            return pageBean2;
        }
    
        public PageBean3 findFavoriteRank(String rname, String minPrice, String maxPrice, int currentPage, int pageSize) {
            //获取session
            SqlSession session = MybatisUtils.getSession();
            FavoriteMapper mapper = session.getMapper(FavoriteMapper.class);
    
            //调用方法
            int start = (currentPage - 1) * pageSize;
            int count = mapper.findTotalCount(rname, minPrice, maxPrice);
            //用来存放收藏排行榜的数据
            List<Route> data=mapper.findFavoriteRankData(rname, minPrice, maxPrice, start, pageSize);
    
            PageBean3 pageBean3 = new PageBean3();
            pageBean3.setTotalCount(count);
            pageBean3.setCurrentPage(currentPage);
            pageBean3.setRouteList(data);
            int totalPage = (int) Math.ceil((count * 1.0) / pageSize);
            pageBean3.setTotalPage(totalPage);
    
            return pageBean3;
        }
    }
    
    
  5. FavoriteMapper

    package com.evilposeidon.dao;
    
    import com.evilposeidon.pojo.Favorite;
    import com.evilposeidon.pojo.FavoritePage;
    import com.evilposeidon.pojo.Route;
    import com.evilposeidon.sql.FavoriteSql;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.SelectProvider;
    
    import java.util.List;
    
    public interface FavoriteMapper {
        @Insert("insert into tab_favorite values(#{rid},now(),#{uid})")
        void safeData(@Param("rid") int rid, @Param("uid") int uid);
    
        @Select("select * from tab_favorite where rid=#{rid} and uid=#{uid}")
        Favorite isFavorite(@Param("rid") int rid, @Param("uid") int uid);
    
        //查询favorite.html需要用到的数据
        @Select("select date,rname,price,rimage,r.rid \n" +
                "from tab_favorite f,\n" +
                "     tab_route r,\n" +
                "     tab_user u\n" +
                "where r.rid = f.rid and f.uid =u.uid limit #{start},#{pageSize}")
        List<FavoritePage> findMyFavorite(@Param("uid") int uid, @Param("start") int start, @Param("pageSize") int pageSize);
    
        //查询收藏到的数量
        @Select("select count(*) \n" +
                "from tab_favorite f,\n" +
                "     tab_route r,\n" +
                "     tab_user u\n" +
                "where r.rid = f.rid and f.uid =u.uid")
        int findFavoriteCount();
    
        @SelectProvider(type = FavoriteSql.class,method = "findTotalCount")
        int findTotalCount(@Param("rname") String rname, @Param("minPrice") String minPrice, @Param("maxPrice") String maxPrice);
    
        @SelectProvider(type = FavoriteSql.class,method = "findFavoriteRankData")
        List<Route> findFavoriteRankData(@Param("rname") String rname, @Param("minPrice") String minPrice, @Param("maxPrice") String maxPrice, @Param("start") int start, @Param("pageSize") int pageSize);
    }
    
    
  6. FavoriteSql

    package com.evilposeidon.sql;
    
    import org.apache.ibatis.annotations.Param;
    
    public class FavoriteSql {
        public String findTotalCount(@Param("rname") String rname, @Param("minPrice") String minPrice, @Param("maxPrice") String maxPrice) {
            StringBuilder sb = new StringBuilder();
            sb.append("select count(*) from tab_route where 1=1 ");
            if (rname != null && rname.trim().length() > 0) {
                sb.append("and rname like concat ('%',#{rname},'%') ");
            }
            if (minPrice != null && minPrice.trim().length() > 0) {
                sb.append("and price>=#{minPrice} ");
            }
            if (maxPrice != null && maxPrice.trim().length() > 0) {
                sb.append("and price<=#{maxPrice} ");
            }
            return String.valueOf(sb);
        }
    
        public String findFavoriteRankData(@Param("rname") String rname, @Param("minPrice") String minPrice, @Param("maxPrice") String maxPrice, @Param("start") int start, @Param("pageSize") int pageSize) {
            StringBuilder sb = new StringBuilder();
            sb.append("select * from tab_route where 1=1 ");
            if (rname != null && rname.trim().length() > 0) {
                sb.append("and rname like concat ('%',#{rname},'%') ");
            }
            if (minPrice != null && minPrice.trim().length() > 0) {
                sb.append("and price>=#{minPrice} ");
            }
            if (maxPrice != null && maxPrice.trim().length() > 0) {
                sb.append("and price<=#{maxPrice} ");
            }
            sb.append("order by count desc limit #{start},#{pageSize}");
            return String.valueOf(sb);
        }
    }
    
    
posted @ 2020-08-04 15:37  evilposeidon  阅读(181)  评论(0)    收藏  举报