黑马旅游网,项目思路以及源代码分享

黑马旅游网,项目思路以及源代码分享,第1张

黑马旅游网,项目思路以及源代码分享

目录

源码我已放到github上了,在此文档下方

第一步:导入

 第二步:试运行

第三步:技术选项

1. web层

1. service层

1. dao层

第四步:创建数据

第五步:功能编写

发送邮件功能

编写baseServlet

将提示信息抽取到一个RouteInfo类中

分页展示:将后端分页数据抽取到PageBean中,前台仿百度左5右4的原则展示

收藏排行榜:

首先更新收藏表的count列

获取PageBean对象

我的收藏

热门排行榜

首页真实数据填充

人气旅游

最新旅游

国内游

境外游

源码链接


源码我已放到github上了,在此文档下方 第一步:导入

        项目所需maven坐标

        工具类      

        静态页面

本项目所需依赖坐标如下

 
    
      junit
      junit
      3.8.1
      test
    
    
    
      javax.servlet
      javax.servlet-api
      3.1.0
      provided
    


    
    
      mysql
      mysql-connector-java
      8.0.23
      compile
    
    
    
      com.alibaba
      druid
      1.0.9
    
    
    
      org.springframework
      spring-core
      5.0.0.RELEASE
      compile
    
    
      org.springframework
      spring-jdbc
      5.0.0.RELEASE
      compile
    
    
      org.springframework
      spring-tx
      5.0.0.RELEASE
      compile
    
    
      org.springframework
      spring-beans
      5.0.0.RELEASE
      compile
    
    
      commons-logging
      commons-logging
      1.1.1
      compile
    
    
    
      commons-beanutils
      commons-beanutils
      1.9.2
      compile
    
    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.3.3
    
    
      com.fasterxml.jackson.core
      jackson-core
      2.3.3
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      2.3.3
    
    
    
      javax.mail
      javax.mail-api
      1.5.6
    
    
      com.sun.mail
      javax.mail
      1.5.3
    
    
    
      redis.clients
      jedis
      2.7.0
    
    
      junit
      junit
      4.13.1
      test
    
  

该项目的结构如下

在导入maven坐标的时候要注意,自己电脑上是否有本地仓库,配置文件里是否设置了中央仓库地址

找到conf个目录里的settings.xml文件设置即可

设置本地仓库路径

F:Developmvn_repository

中设置中央仓库地址

   
          alimaven  
          aliyun maven  
          http://maven.aliyun.com/nexus/content/groups/public/
          central          
    

 第二步:试运行

  配置tomcat启动配置

第三步:技术选项 1. web层

Servlet:前端的控制器,前后端交互必备

html:视图

Filter:过滤器

BeanUtils:封装数据

Jackson:json序列化工具,实现异步交互

1. service层

Javamail:java发送邮件工具

Redis:nosql内存数据库

Jedis:java的redis客户端

1. dao层

Mysql:数据库

Druid:数据库连接池

JdbcTemplate:jdbc的工具

第四步:创建数据库

sql语句我也放到github上了需要自行去取

第五步:功能编写

这里我主要介绍一下部分功能要点,需要源码的,直接在文档底部找到github链接进去获取即可

发送邮件功能

 一定要在MailUtils工具类中填写正确的授权码

授权码获取方式如下:QQ邮箱

点击设置 -->  账户     找到如图所示的服务开启即可

编写baseServlet

继承HttpServlet重写service方法

目的:简化Servlet的数量

 //重写HttpServlet中的服务方法(service方法),用于接收用户的请求用反射技术分发不同功能的方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("baseServlet被执行了!!!");

        //1.获取请求路径
        String requestURI = req.getRequestURI();    ///travel/user/add
        //System.out.println(requestURI);
        //2.获取方法名称      /user/add
        String methodName = requestURI.substring(requestURI.lastIndexOf("/") + 1);  //add
        //System.out.println(methodName);
        try {
            //谁调用的当前方法this就是谁
           // System.out.println(this);   //cn.itcast.travel.web.servlet.UserServlet@7dd86009
            //3.使用反射技术调用方法,不要使用忽略权限修饰符的方法
            Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //4.执行方法,不要使用暴力反射
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
将提示信息抽取到一个RouteInfo类中
public class ResultInfo implements Serializable {
    private boolean flag;//后端返回结果正常为true,发生异常返回false
    private Object data;//后端返回结果数据对象
    private String errorMsg;//发生异常的错误消息

    //无参构造方法
    public ResultInfo() {
    }
    public ResultInfo(boolean flag) {
        this.flag = flag;
    }
    
    public ResultInfo(boolean flag, String errorMsg) {
        this.flag = flag;
        this.errorMsg = errorMsg;
    }
    
    public ResultInfo(boolean flag, Object data, String errorMsg) {
        this.flag = flag;
        this.data = data;
        this.errorMsg = errorMsg;
    }


    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}
分页展示:将后端分页数据抽取到PageBean中,前台仿百度左5右4的原则展示

PageBean代码如下:

package cn.itcast.travel.domain;

import java.util.List;


public class PageBean {
    private int totalCount;    //总记录数
    private int totalPage;     //总页码
    private int pageSize;      //每页显示的条数
    private int currentPage;   //当前页码
    private List list;      //数据集合

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }
}

前台展示关键代码如下:

    
                    //计算循环的开始和结束索引
                    var begin;     //开始索引
                    var end;       //结束索引
                    //计算开始索引值
                    //要显示10个页码
                    if(pb.totalPage < 10){
                        //总页码不足10页
                        begin = 1;
                        end = pb.totalPage;
                    } else {
                        //总页码超过10页,左5右4
                        begin = pb.currentPage - 5;   //开始页码 = 当前页码 - 5个页码
                        end = pb.currentPage + 4;
                        //如果前边不够5个则后边补齐10个
                        //减去5个页码之后如果开始索引小于1了,那么开始索引就从1开始,结束位置就从10开始
                        if (begin < 1){
                            begin = 1;
                            end = begin + 9;  //补齐后边9个
                        }
                        //如果后边不够5个则前边补齐10个
                        //如果结束位置加上4个页码后大于总页码了,那么开始位置就要补齐10个,结束位置就等于总页码
                        if(end > pb.totalPage){
                            end = pb.totalPage;
                            begin = end - 9;  //补齐前边10个
                        }
                    }
收藏排行榜:

RouteServlet中的favoriteRank代码如下

 
    public void favoriteRank(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String currentPageStr = request.getParameter("currentPage");
        String pageSizeStr = request.getParameter("pageSize");
        //2.将获取到的值转为int类型
        int pageSzie;
        if(pageSizeStr != null && pageSizeStr.length() > 0){   //非空验证
            pageSzie = Integer.parseInt(pageSizeStr);
        } else {
            pageSzie = 8;
        }
        int currentPage;
        if(currentPageStr != null && currentPageStr.length() > 0 ){   //非空验证
            currentPage = Integer.parseInt(currentPageStr);
        } else {
            currentPage = 1;
        }
        Map parameterMap = request.getParameterMap();  //获取模糊查询参数
        PageBean pageBean = routeService.findRouteByCount(currentPage,pageSzie,parameterMap);
        //将获取到的pageBean对象数据序列化为json发送到前台
        writevalue(pageBean,response);
    }
首先更新收藏表的count列

我的思路是:查询tab_favorite获得rid封装到类型为Route的list集合当中

FavoriteDao代码如下

 public List groupRid() {
        String sql = "SELECt f.`rid`,COUNT(*) count FROM tab_favorite f WHERe f.`rid` = rid GROUP BY rid";
        List query = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Route.class));
        return query;
    }

RouteDao代码如下

  public void updateRouteCount(List routes) {
        String sql = "update tab_route set count = ?  where rid = ?";
        for (int i = 0; i < routes.size(); i++) {
            jdbcTemplate.update(sql,routes.get(i).getCount(),routes.get(i).getRid());
        }
    }
获取PageBean对象

RouteService代码如下

 public PageBean findRouteByCount(int currentPage, int pageSzie, Map parameterMap) {
        //创建PageBean对象
        PageBean pageBean = new PageBean<>();
        //向pageBean添加现有数据
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSzie);
        //获取总记录数
        int totalCount = routeDao.findTotalCount(parameterMap);
        //计算开始索引
        int start = (currentPage -1) * pageSzie;
        List dataByPage = routeDao.findDataByPage(start, pageSzie, parameterMap);
        //计算总页码
        int totalPage = totalCount % pageSzie == 0 ? totalCount / pageSzie : (totalCount / pageSzie) + 1;
        //向pageBean中添加获取到的数据
        pageBean.setTotalPage(totalPage);
        pageBean.setTotalCount(totalCount);
        pageBean.setList(dataByPage);
        return pageBean;
    }

RouteDao代码如下

 @Override
    public int findTotalCount(Map parameterMap) {
        String sql = "select count(*) from tab_route where count > 0";
        StringBuilder sb = new StringBuilder(sql);
        List parameter = creteSql(sb, parameterMap);
        sql = sb.toString();
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class,parameter.toArray());
        return count;
    }
    private List creteSql(StringBuilder sb ,Map parameterMap){
        List parameter = new ArrayList<>();  //用于存储参数
        parameterMap.forEach(new BiConsumer() {
            @Override
            public void accept(String key, String[] values) {
                if("currentPage".equals(key) || "".equals(key)){ //过滤当前页码参数
                    return;
                }

                if("rname".equals(key)){  //线路名称

                    String value = values[0];

                    if(value != null && !"".equals(value)){   //参数必须部位空
                        if(!(Charset.forName("GBK").newEncoder().canEncode(value))){  //如果该字符串乱码就重新编码该字符串
                            try {
                                value = new String(value.getBytes("iso-8859-1"),"utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                        sb.append(" and "+key+" like ? ");
                        if (parameter != null) {    //防止空指针
                            parameter.add("%"+value+"%");
                        }
                    }
                }
                if("priceBefore".equals(key)){  //开始金额
                    String value = values[0];
                    if(value != null && !"".equals(value)){   //参数必须不位空
                        sb.append(" and price between ? and ? ");
                        if (parameter != null) {    //防止空指针
                            parameter.add(value);
                        }
                    }
                }
                if("priceEnd".equals(key)){   //结束金额
                    String value = values[0];
                    if(value != null && !"".equals(value) ){   //参数必须部位空
                        if (parameter != null) {    //防止空指针
                            parameter.add(value);
                        }
                    }
                }
            }
        });
        return parameter;
    }


    @Override
    public List findDataByPage(int start, int pageSzie, Map parameterMap) {
       String sql = "select * from tab_route where count>0 ";
       StringBuilder sb = new StringBuilder(sql);
       //调用createSql动态拼接模糊查询参数
        List parameter = creteSql(sb, parameterMap);
        sb.append(" order by count desc");
        sb.append(" limit ? , ?");
        parameter.add(start);
        parameter.add(pageSzie);
        sql = sb.toString();
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper(Route.class),parameter.toArray());
    } 
我的收藏 

关键代码如下

 @Override
    public PageBean myFavorite(int uid, int currentPage, int pageSize) {
        //1.创建PageBean对象
        PageBean pageBean = new PageBean<>();
        //添加现有数据到pageBean中
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSize);
        //2.调用FavoriteDao中的findRidByUid方法
        List rids = favoriteDao.findRidByUid(uid);
        if(rids == null){  //如果线路id集合为空,则直接返回null
            return null;
        }
        int totalCount = routeDao.findTotalCount(rids);
        //计算开始位置
        int start = (currentPage - 1) * pageSize;
        //3.获得route对象数据集合
        List routes = routeDao.gainRoutes(rids,start,pageSize);
        //4.计算总页码
        int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : (totalCount / pageSize) + 1;
        //5.向PageBean中添加数据
        pageBean.setTotalPage(totalPage);
        pageBean.setList(routes);
        pageBean.setTotalCount(totalCount);

        return pageBean;
    }
热门排行榜

查询收藏次数降序排列后的前五条记录

关键代码如下

    public List findRouteByCid(int cid) {
        List routes = null;
        try {
            String sql = "SELECt * FROM tab_route WHERe cid = ? ORDER BY COUNT DESC LIMIT 5";
            routes = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Route.class), cid);
        } catch (DataAccessException e) {

        }
        return routes;
    }
首页真实数据填充

主题旅游关键代码如下

@Override
    public List findThemeTop4() {
        String parameter = "%佛%";
        List routes = null;
        try {
            String sql = "SELECt * FROM tab_route WHERe rname like ? ORDER BY COUNT DESC LIMIT 4";
            routes = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Route.class), parameter);
        } catch (DataAccessException e) {

        }
        return routes;
    }
人气旅游

查询收藏次数降序排列后的前4条记录

最新旅游

查询上架时间降序排列后的前4条记录

国内游

查询route表的cid=5的记录6条即可

境外游

查询route表的cid=4的记录6条即可


源码链接

https://github.com/520study520/heima_travel


我的这些思路和作品可能有很多不足,望大家在评论区指点一下我!!!感谢Thanks♪(・ω・)ノ

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5718382.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)