黑马旅游网_后端总结

Maven 项目启动,我们可以通过配置 Tomcat 插件来启动



    org.apache.tomcat.maven
    
    tomcat7-maven-plugin
    2.1
    
        
        8080
        
        /travel
    

黑马旅游网_后端总结_第1张图片

为了不每次启动项目都要去找这个命令,我们可以配置一下。后面我们启动直接点击启动的那个按钮即可 

黑马旅游网_后端总结_第2张图片


各个表的解释

tab_user 

用户表,存储的和用户相关的信息

黑马旅游网_后端总结_第3张图片

/**
 * 用户实体类
 */
public class User implements Serializable {
    private int uid;//用户id
    private String username;//用户名,账号
    private String password;//密码
    private String name;//真实姓名
    private String birthday;//出生日期
    private String sex;//男或女
    private String telephone;//手机号
    private String email;//邮箱
    private String status;//激活状态,Y代表激活,N代表未激活
    private String code;//激活码(要求唯一)
    
    //省略 get set toString 构造函数等方法
}

 

tab_category(分类表)

黑马旅游网_后端总结_第4张图片

/**
 * 分类实体类
 */
public class Category implements Serializable {

    private int cid;//分类id
    private String cname;//分类名称

    //省略 get set toString 构造函数
}

tab_category 存储的就是上面导航栏里面的信息,这里我们是从数据库里面去取出来,而不是写死,返回的是 json 数据

[{"cid":8,"cname":"全球自由行"},{"cid":5,"cname":"国内游"},{"cid":4,"cname":"处境游"},{"cid":7,"cname":"抱团定制"},{"cid":6,"cname":"港澳游"},{"cid":2,"cname":"酒店"},{"cid":1,"cname":"门票"},{"cid":3,"cname":"香港车票"}]
//重数据库(tab_category)里面查询分类信息,填充到页面
$.get("category/findAll", {}, function (data) {
    console.log(data);
    //[{"cid":8,"cname":"全球自由行"},{"cid":5,"cname":"国内游"},{"cid":4,"cname":"处境游"},{"cid":7,"cname":"抱团定制"},{"cid":6,"cname":"港澳游"},{"cid":2,"cname":"酒店"},{"cid":1,"cname":"门票"},{"cid":3,"cname":"香港车票"}]
    //收尾的两个 li 是固定的
    var first = '';
    var end = '
  • 收藏排行榜
  • '; var lis = first; //遍历 数组 for (var i = 0; i < data.length; i++) { var li = '
  • ' + data[i].cname + '
  • '; lis += li; } lis+=end; //将lis字符串,设置到ul的html内容中 $("#category").html(lis); })
    
    

    tab_route(旅游线路表)

    tab_route 存储的就是点击不同的类别后,后面显示的数据信息

    tab_category 和 tab_route  表是一对多的关系

    黑马旅游网_后端总结_第5张图片

    通过tab_category表我们可以得到cid,然后通过cid我们就可以查询tab_route表里面的信息

    黑马旅游网_后端总结_第6张图片

    黑马旅游网_后端总结_第7张图片


    根据cid查询不同类别的旅游线路数据

    前期分析很重要,我们先把后台代码写通了前台代码自然就简单多了

    黑马旅游网_后端总结_第8张图片

     

    其实就是用户点击了不同类别的旅游景点信息后,就有一个cid,通过cid我们就可以去查询具体是那个类别的旅游信息,这个时候我们前头可以给服务器说我们需要哪些信息,服务器就返回什么样的信息

    黑马旅游网_后端总结_第9张图片

     服务端:

    1. int totalCount  //总记录数
    2. int totalPage  //总页数
    3. int currentPage  //当前页码
    4. int pageSize  //每页显示条数

    客户端:(发送ajax请求)

    1. currentPage  //当前页码
    2. pageSize  //每页显示条数
    3. cid //分页id

    当前页码 每页显示条数,可以不通过服务器返回,应为这些信息是我们客服端发过去的,但是为了统一操作我们还是通过服务器返回,应为这些信息都是在一个json里面。当我们客服端不给这些信息的时候服务端还可以给默认的值

    每次服务端返回的数据只有一页的数据量,但是还包含中的页码、种记录数 、每页显示条数。种页码种记录数是为了填写网页最下面的导航信息

    每个旅游景点的详细信息我们封装在 Route  类里面

    /**
     * 旅游线路商品实体类
     * 每一个项目的具体信息
     */
    public class Route implements Serializable {
    
        private int rid;//线路id,必输
        private String rname;//线路名称,必输
        private double price;//价格,必输
        private String routeIntroduce;//线路介绍
        private String rflag;   //是否上架,必输,0代表没有上架,1代表是上架
        private String rdate;   //上架时间
        private String isThemeTour;//是否主题旅游,必输,0代表不是,1代表是
        private int count;//收藏数量
        private int cid;//所属分类,必输
        private String rimage;//缩略图
        private int sid;//所属商家
        private String sourceId;//抓取数据的来源id
    
        private Category category;//所属分类
        private Seller seller;//所属商家
        private List routeImgList;//商品详情图片列表
        //...
    }

    黑马旅游网_后端总结_第10张图片

    我们用另外一个类(PageBean)来封装所有的信息,不仅包含具体的景点信息还包含有多少个景点,多少页等记录

    /**
     * 分页对象
     * 存储了各种页面信息
     */
    public class PageBean {
        private int totalCount;//总记录数
        private int totalPage;//总页数
        private int currentPage;//当前页码
        private int pageSize;//每页显示的条数
        private List list;//每页显示的数据集合
        //...
    }

    黑马旅游网_后端总结_第11张图片


    整加模糊查询功能

    在前台代码框里面有一个根据线路查询旅游景点的搜索框,我们需要完善这个搜索框

     黑马旅游网_后端总结_第12张图片

     这里的查询和前面的根据cid查询不同类别的旅游线路数据 代码是一模一样的,我们只需要在原来的代码上修改一下即可,增加一个模糊查询,如果我们传给后台的代码中后 cname 我们就模糊查询,否则就是正常的查询即可

     我们给搜索按钮绑定一个点击事件,然后获取输入的值,直接修改游览器的地址栏发送请求给 route_list.html 页面即可

    //给搜索框绑定单击事件,获取搜索输入框的内容
    $("#search-button").click(function () {
        //线路名称
        var rname = $("#search_input").val();
        //alert(rname);
        var cid = getParameter("cid")
        //alert(cid);
        //跳转路径 http://localhost:8080/travel_ssm/route_list.html?cid=5,拼接上 rname=xxx
        location.href = "http://localhost:8080/travel_ssm/route_list.html?cid=" + cid + "&rname=" + rname;
    })

     

     我这里的查询,是通过MyBatis的动态SQL 写的,当然你也可以拼接字符串执行

    
    
    
    
    
    
    
    
    
    
    

     

    /**
     * 分页查询
     * 如果有 rname 这个时候我们就需要模糊查询
     */
    @RequestMapping("/pageQuery")
    @ResponseBody
    public PageBean pageQuery(HttpServletRequest request) throws UnsupportedEncodingException {
        //1.接受参数
        String currentPageStr = request.getParameter("currentPage");//当前页数
        String pageSizeStr = request.getParameter("pageSize");//查询多少页
        String cidStr = request.getParameter("cid");//
    
    
        //接受rname 线路名称
        String rname = request.getParameter("rname");//m
    //        System.out.println("rname:\t"+rname);
    //        rname = new String(rname.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); //rname 是中文,发送的还是get请求可能乱码  又有我配置了字符编码过滤器,这里是不可以使用的,不然正常的就会变成乱码
    //        System.out.println("rname:\t"+rname);
    
        System.out.println("rname:\t"+rname);
        System.out.println("rname 是不是为空:\t"+(rname == null));
        if (rname == null || rname.equals("null")) {//没有给他一个空字符串
            rname = null;
        }
        System.out.println("rname 是不是为空:\t"+(rname == null));
    
    
        int cid = 0;//类别id
        //2.处理参数
        //在首页 搜索 cid = "null" 会发生类型转换异常
        //http://localhost:8080/travel_ssm/route_list.html?cid=null&rname=西安
        if (cidStr != null && cidStr.length() > 0 && !cidStr.equals("null")) {
            cid = Integer.parseInt(cidStr);
        }
        int currentPage = 0;//当前页码,如果不传递,则默认为第一页
        if (currentPageStr != null && currentPageStr.length() > 0) {
            currentPage = Integer.parseInt(currentPageStr);
        } else {
            currentPage = 1;
        }
    
        int pageSize = 0;//每页显示条数,如果不传递,默认每页显示5条记录
        if (pageSizeStr != null && pageSizeStr.length() > 0) {
            pageSize = Integer.parseInt(pageSizeStr);
        } else {
            pageSize = 5;
        }
    
        //3. 调用service查询PageBean对象
        //4. 将pageBean对象序列化为json,返回
        return routeService.pageQuery(cid, currentPage, pageSize, rname);
    }
    

    详情页面展示功能 

    分析:

    黑马旅游网_后端总结_第13张图片

    黑马旅游网_后端总结_第14张图片

     

    黑马旅游网_后端总结_第15张图片


    点击收藏功能实现

    黑马旅游网_后端总结_第16张图片


    所有表的关系 

    黑马旅游网_后端总结_第17张图片 


    使用反射减少代码量

    我们抽象了一个 BaseServlet 类,让这个类继承HttpServlet,然后让其他类继承这个类

    虽然我是使用的SpringMVC来做的,但是这个方法是一种很好的方法

    程序中的 this 的指向是,谁调用就指向的就是谁,看下面的演示代码

    父类: 

    public class Father{
        
        public void service(){
            System.out.println(this);
        }
    }
    

    子类: 

    public class Son extends Father{
    
    }

    测试:

    @Test
    public void test() {
        Son son = new Son();
        son.service();
    }

    输出:

    com.bug.service.impl.Son@3d012dd

    通过上面的代码我们可以定义一个基础的类(BaseServlet ),让他去基础HttpServlet,其他类继承这个类,这个时候当程序调用 service 方法的时候我们就可以通过反射来执行响应的代码

    BaseServlet 

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("baseServlet的service方法被执行了...");
        //完成方法分发
        //1.获取请求路径
        String uri = req.getRequestURI(); //   /travel/user/add
        System.out.println("请求uri:" + uri);//  /travel/user/add
        //2.获取方法名称
        String methodName = uri.substring(uri.lastIndexOf('/') + 1);
        System.out.println("方法名称:" + methodName);
        //3.获取方法对象Method
        //谁调用我?我代表谁
        System.out.println(this);//UserServlet的对象cn.itcast.travel.web.servlet.UserServlet@4903d97e
        try {
            //获取方法
            Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //4.执行方法
            //暴力反射
            //method.setAccessible(true);
            method.invoke(this, req, resp);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    
    }

    解释:上面这个类由于子类没有重写父类的service方法,所有程序会首先执行父类的service方法,这个时候我们可以把请求参数提取出来,this.getClass() 的到的是子类对象,这个时候我们就通过反射的方式去执行子类相应的请求方法

    这样做的好处是,当我们的请求参数是什么程序实际上就执行的是什么方法,应为我们子类没有重写父类的service方法,这个时候我们会执行父类的service方法,我们请求的参数是什么最后就会动态的执行子类的什么方法。

    这个时候我们就可以把同一个操作放在同一类里面了,如果不这样做的话,下面的每个方法我们都需要写一个类来处理

    @WebServlet("/user/*") // /user/add /user/find
    public class UserServlet extends BaseServlet {
    
        /**
         * 注册功能
         */
        public void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 省略业务代码  
        }
    
        /**
         * 查询单个对象
         */
        public void findOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             // 省略业务代码  
        }
    
        /**
         * 退出功能
         */
        public void exit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 省略业务代码  
        }
    
        /**
         * 激活功能
         */
        public void active(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 省略业务代码    
        }
    }
    

    收藏功能实现

    客户端传递一个 rid 然后重服务器的Session域中取出用户的 uid (没有的话我们uid置为-1反正不可能有这个人),然后在 tab_favorite 表中查询

    黑马旅游网_后端总结_第18张图片

     

    黑马旅游网_后端总结_第19张图片


     

    定义一个过滤器解决全站乱码问题

    /**
     * 解决全站乱码问题,处理所有的请求
     */
    @WebFilter("/*")
    public class CharchaterFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse rep, FilterChain filterChain) throws IOException, ServletException {
            //将父接口转为子接口
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) rep;
            //获取请求方法
            String method = request.getMethod();
            //解决post请求中文数据乱码问题
            if(method.equalsIgnoreCase("post")){
                request.setCharacterEncoding("utf-8");
            }
            //处理响应乱码
            response.setContentType("text/html;charset=utf-8");
            filterChain.doFilter(request,response);
        }
    
        @Override
        public void destroy() {
    
        }
    }
    

    我是使用的SpringMVC 这个时候我只需要在 web.xml 里面配置过滤器即可

    
    
        CharacterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
        
            forceRequestEncoding
            true
        
        
            forceResponseEncoding
            true
        
    
    
        CharacterEncodingFilter
        /*
    
    

     

    你可能感兴趣的:(项目实战)