zoukankan      html  css  js  c++  java
  • 仿9GAG制作过程(五)

    有话要说:

    在做完了数据展示功能之后,就想着完善整个APP。发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子、评论、点赞应该联动起来,段子应该有创建时间等。

    于是就重新设计了数据库,重新爬取了数据,重新设计了后台接口。

    这次主要讲这次重构的主要内容。

    数据库设计:

     

    一共设计了六张表,分别为

    1. 段子表,主要存放每一个段子的图片等信息
    2. 评论表,主要存放评论信息,评论可以上传图片
    3. 用户表
    4. 标签表,每条段子发表之前会自定义标签,该表存放的就是这些标签
    5. 点赞记录表,因为用户点赞与段子之间是多对多的关系,因此要加一张表用来存放点赞记录
    6. 段子标签关联表,因为段子和标签是多对多的,因此需要多一张表存放关联关系

    接口设计:

    橙色的为表,咖啡色为接口。

    目前设计了十四个接口,上图写明了各接口和相关的表之间的关系。

    后台结构:

    bean包下为基本实体类;

    implement包下为消息实体类的子类;

    dao包为涉及到数据库的具体实现类;

    servlet为接口类;

    util为过程中用到的工具类。

    具体例子:

    下面以查询段子接口为例,介绍具体的结构。

    bean类:

    消息实体类:

     1 public class MessageEntity {
     2 
     3     // 返回信息描述
     4     private String reason;
     5     // 返回码
     6     private int errorCode;
     7 
     8     public String getReason() {
     9         return reason;
    10     }
    11 
    12     public void setReason(String reason) {
    13         this.reason = reason;
    14     }
    15 
    16     public int getErrorCode() {
    17         return errorCode;
    18     }
    19 
    20     public void setErrorCode(int errorCode) {
    21         this.errorCode = errorCode;
    22     }
    23 
    24 }

    段子消息实体类:

     1 public class TopicMessageEntity extends MessageEntity {
     2 
     3     // 获取段子的结果
     4     private List<TopicEntity> result;
     5 
     6     public List<TopicEntity> getResult() {
     7         return result;
     8     }
     9 
    10     public void setResult(List<TopicEntity> result) {
    11         this.result = result;
    12     }
    13 
    14 }

     段子实体类:

     1 public class TopicEntity {
     2 
     3     // 段子标识
     4     private int id;
     5     // 段子作者
     6     private String author = "";
     7     // 段子标题
     8     private String title = "";
     9     // 段子点赞数
    10     private int upvote;
    11     // 段子评论数
    12     private int commentCount;
    13     // 段子略缩图地址
    14     private String thumbNail = "";
    15     // 段子原图地址
    16     private String orgPicture = "";
    17     // 段子发表时间
    18     private String postTime = "";
    19     
    20     // 点的是赞还是踩,0代表没点,1代表赞,-1代表踩
    21     private int like = 0;
    22 
    23     public int getId() {
    24         return id;
    25     }
    26 
    27     public void setId(int id) {
    28         this.id = id;
    29     }
    30 
    31     public String getAuthor() {
    32         return author;
    33     }
    34 
    35     public void setAuthor(String author) {
    36         this.author = author;
    37     }
    38 
    39     public String getTitle() {
    40         return title;
    41     }
    42 
    43     public void setTitle(String title) {
    44         this.title = title;
    45     }
    46 
    47     public int getUpvote() {
    48         return upvote;
    49     }
    50 
    51     public void setUpvote(int upvote) {
    52         this.upvote = upvote;
    53     }
    54 
    55     public int getCommentCount() {
    56         return commentCount;
    57     }
    58 
    59     public void setCommentCount(int commentCount) {
    60         this.commentCount = commentCount;
    61     }
    62 
    63     public String getThumbNail() {
    64         return thumbNail;
    65     }
    66 
    67     public void setThumbNail(String thumbNail) {
    68         this.thumbNail = thumbNail;
    69     }
    70 
    71     public String getOrgPicture() {
    72         return orgPicture;
    73     }
    74 
    75     public void setOrgPicture(String orgPicture) {
    76         this.orgPicture = orgPicture;
    77     }
    78 
    79     public String getPostTime() {
    80         return postTime;
    81     }
    82 
    83     public void setPostTime(String postTime) {
    84         this.postTime = postTime;
    85     }
    86 
    87     public int getLike() {
    88         return like;
    89     }
    90 
    91     public void setLike(int like) {
    92         this.like = like;
    93     }
    94 
    95 }

    这里和数据库表略有不同,主要是like字段。

    like字段代表的是当前获取数据的人对该段子是否点了赞。

    dao层:

    查询段子方法:

     1 public List<TopicEntity> query(int topicId, int count, boolean after) {
     2         List<TopicEntity> topicList = new ArrayList<TopicEntity>();
     3 
     4         if (topicId <= 0) {
     5             topicId = 0;
     6         }
     7 
     8         if (count <= 0) {
     9             count = 10;
    10         }
    11 
    12         if (after) {
    13             queryAfter(topicId, count, topicList);
    14         } else {
    15             queryBefore(topicId, count, topicList);
    16         }
    17 
    18         return topicList;
    19     }
     1 private void queryAfter(int topicId, int count, List<TopicEntity> topicList) {
     2         String queryAfter = "SELECT * FROM 9gag_topics WHERE id > ? LIMIT ?";
     3 
     4         Connection conn = DatabaseUtil.getConnection();
     5         PreparedStatement pstmt = null;
     6         ResultSet rs = null;
     7 
     8         try {
     9             pstmt = conn.prepareStatement(queryAfter);
    10             pstmt.setInt(1, topicId);
    11             pstmt.setInt(2, count);
    12             rs = pstmt.executeQuery();
    13 
    14             while (rs.next()) {
    15                 TopicEntity topicEntity = new TopicEntity();
    16                 topicEntity.setId(rs.getInt("id"));
    17                 topicEntity.setAuthor(rs.getString("author"));
    18                 topicEntity.setTitle(rs.getString("title"));
    19                 topicEntity.setUpvote(rs.getInt("upvote"));
    20                 topicEntity.setCommentCount(rs.getInt("commentcount"));
    21                 topicEntity.setThumbNail(rs.getString("thumbnail"));
    22                 topicEntity.setOrgPicture(rs.getString("orgpicture"));
    23                 topicEntity.setPostTime(rs.getString("posttime"));
    24                 topicList.add(topicEntity);
    25             }
    26         } catch (SQLException e) {
    27             e.printStackTrace();
    28         } finally {
    29             DatabaseUtil.close(conn, pstmt, rs);
    30         }
    31     }
     1 private void queryBefore(int topicId, int count, List<TopicEntity> topicList) {
     2         String queryBefore = "SELECT * FROM 9gag_topics WHERE id < ? ORDER BY id DESC LIMIT ?";
     3 
     4         Connection conn = DatabaseUtil.getConnection();
     5         PreparedStatement pstmt = null;
     6         ResultSet rs = null;
     7 
     8         try {
     9             pstmt = conn.prepareStatement(queryBefore);
    10             pstmt.setInt(1, topicId);
    11             pstmt.setInt(2, count);
    12             rs = pstmt.executeQuery();
    13 
    14             while (rs.next()) {
    15                 TopicEntity topicEntity = new TopicEntity();
    16                 topicEntity.setId(rs.getInt("id"));
    17                 topicEntity.setAuthor(rs.getString("author"));
    18                 topicEntity.setTitle(rs.getString("title"));
    19                 topicEntity.setUpvote(rs.getInt("upvote"));
    20                 topicEntity.setCommentCount(rs.getInt("commentcount"));
    21                 topicEntity.setThumbNail(rs.getString("thumbnail"));
    22                 topicEntity.setOrgPicture(rs.getString("orgpicture"));
    23                 topicEntity.setPostTime(rs.getString("posttime"));
    24                 topicList.add(topicEntity);
    25             }
    26         } catch (SQLException e) {
    27             e.printStackTrace();
    28         } finally {
    29             DatabaseUtil.close(conn, pstmt, rs);
    30         }
    31 
    32         // 获取完数据之后逆序,因为查找的时候是逆序
    33         Collections.reverse(topicList);
    34     }

    这三个方法实现了查询指定段子前(或者后)count条记录。

     servlet层:

     1 protected void doPost(HttpServletRequest request, HttpServletResponse response)
     2             throws ServletException, IOException {
     3         response.setContentType("text/json; charset=utf-8");
     4         PrintWriter out = response.getWriter();
     5 
     6         TopicMessageEntity message = new TopicMessageEntity();
     7         TopicDAO topicDao = new TopicDAO();
     8         UpvoteDAO upvoteDao = new UpvoteDAO();
     9         Gson gson = GsonUtil.getGson();
    10 
    11         request.setCharacterEncoding("utf-8");
    12         response.setCharacterEncoding("utf-8");
    13 
    14         int topicId = Integer.parseInt(request.getParameter("topicId"));
    15         int count = Integer.parseInt(request.getParameter("count"));
    16         boolean after = Boolean.parseBoolean(request.getParameter("after"));
    17         String author = request.getParameter("author");
    18 
    19         if (count <= 0) {
    20             message.setErrorCode(-1);
    21             message.setReason("count值不能为负数!");
    22             out.print(gson.toJson(message));
    23             return;
    24         }
    25 
    26         try {
    27             List<TopicEntity> topics = topicDao.query(topicId, count, after);
    28             
    29             // 判断作者是否点过赞
    30             if (author != null) {
    31                 List<UpvoteEntity> upvoteList = upvoteDao.findUpvoteByAuthor(author, true);
    32                 if (upvoteList != null) {
    33                     for (TopicEntity topic : topics) {
    34                         for (UpvoteEntity upvote : upvoteList) {
    35                             if (upvote.getLikedId() == topic.getId()) {
    36                                 int like = upvote.isLiked() ? 1 : -1;
    37                                 topic.setLike(like);
    38                             }
    39                         }
    40                     }                    
    41                 }
    42             }
    43             
    44             Collections.reverse(topics);
    45             message.setErrorCode(0);
    46             message.setReason("success");
    47             message.setResult(topics);
    48         } catch (Exception e) {
    49             message.setErrorCode(-1);
    50             message.setReason(e.getMessage());
    51         } finally {
    52             out.print(gson.toJson(message));
    53         }
    54 
    55     }

    主要逻辑:查找到需要的段子→遍历段子→如果段子被点过赞或者踩,就把段子相应字段更改为赞或者踩→由于查出来的数据时顺序的,要改为逆序展示。

    反思:

    这次主要重构了后台的设计逻辑,其实还有好多不完备的地方。

    通过这次重构,明白了一个要点。要做一件事情首先要规划好,首先是设计,把一切的流程,框架设计好之后按部就班的做。这样做出来的东西才会比较好。

    否则在过程中会很混乱,严重影响效率。

    预告:

    下一章准备讲述点赞的逻辑,因为点赞的逻辑比较复杂。

    大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~

  • 相关阅读:
    mysql 索引
    redis持久化
    redis发布订阅
    django 信号
    paramiko模块
    23种设计模式python实现
    几种浏览器存储数据的方式
    关于传参
    对字符串里的四则运算进行计算2020/10/12
    动手动脑2020/10/9
  • 原文地址:https://www.cnblogs.com/lanxingren/p/9231243.html
Copyright © 2011-2022 走看看