文章目录

  • 一.业务需求分析
  • 二.数据库的设计
  • 三.代码实现
    • 1. `pojo`类的实现
      • 1.1设计原则
      • 1.2可能的异常
    • 2. `dao`类
    • 3. `service`类
      • 3.1 接口
      • 3.2 接口的实现类
    • 4. `controller`类
      • 4.1`UserController`
      • 4.2`TopicController`
    • 5.`HTML`的设计
      • 4.1可能的异常`
      • 4.2`login`登录界面
      • 4.3`index`展示界面
        • 4.3.1`top`页面信息
        • 4.3.2`left`好友列表
        • 4.3.3`main`日志显示列表
        • 4.3.4`detial`日志详情
  • 四.开发套路总结
    • 1.拷贝`myssm`包
    • 2.新建配置文件`applicationContext.xml`或者其他名字,在`web.xml`中指定文件名
    • 3.在`web.xml`文件中配置:
    • 4.开发具体的业务模块:
    • 5.数据库连接异常

一.业务需求分析

  1. 用户登录
  2. 登陆成功,显示主界面。左侧显示好友列表;上端显示欢迎词。如果不是自己空间,显示超链接:返回我主页
  3. 查看日志详情:
    • 日志本身的信息(作者头像,昵称,日志标题,日志内容,日志的日期)
    • 回复列表(回复作者的头像,昵称,回复内容,回复日期)
    • 主人回复信息
  4. 删除日志
  5. 删除特定的回复
  6. 删除特定主人的回复
  7. 添加日志、添加回复、添加主人回复
  8. 点击左侧好友,进入好友的空间

二.数据库的设计

  1. 抽取实体:用户登录信息、用户详情信息、日志、回帖、主人回帖
  2. 属性分析
  3. 实体之间的关系

三.代码实现

1. pojo类的实现

1.1设计原则

  1. 主键应该是没有实际意义的列,不要和业务由关联。因为将来可能涉及两表合并,主键将无法合并。

  2. 设计时间类型时:

    –年月日时分秒(java.util.Date),

    –年月日(java.sql.Date),时分秒(java.sql.TIme

  3. 类与类之间的关系也要建立

    public class UserBasic {private Integer id;private String loginId;private String nickName;private String pwd;private String headImg;//类与类之间的关系private UserDetail userDetail;  //1:1private List<Topic> topicList;  //1:Nprivate List<UserBasic> friendList; //M:Npublic UserBasic() {}
    }
    

1.2可能的异常

  1. 查询好友列表时,查询到的rsmd.getColumnNamefid,而UserBasic中的属性为id。可以在sql语句中使用别名代替,并rsmd.getColumnName替代
  2. 数据库连接失败:1.驱动是否导入,2.数据库选择,3.用户名和密码。
  3. 获取Topic列表时调用setValue(entity,columnName,columnValue)设置UserBasic author属性,但是数据库中返回的类型是Integer

2. dao

3. service

3.1 接口

3.2 接口的实现类

4. controller

4.1UserController

4.2TopicController

需要根据topicId获取对应的topic信息

5.HTML的设计

4.1可能的异常`

  1. 页面无法渲染。

    原因:没有经过processTemplate(methodReturnStr,req,resp);语句的渲染,而是直接跳转到静态页面

    解决:通过PageController控制渲染,调用PageController中的page方法跳转到Page参数对应的页面。

     iframe th:src="@{/page.do?operate=page&page=frames/left}"
    
    public class PageController {protected String page(String page){return page;}
    }
    
  2. 点击好友名称时,在iframe中刷新整个页面。

    原因:target没有设置

    解决:超链接后添加 target="_top"语句,使得新页面在顶层显示。

  3. 访问动态页面时,一定要经过渲染。案例使用PageController渲染

  4. return语句的使用:

4.2login登录界面

  1. 静态页面:可以直接用地址访问。本案例使用page.do?operate=page&page=login渲染得到。

  2. 启动时,访问的页面是:

    http:// localhost :8080 /pro23 /page.do ?operate=page&page=login

    协议 ServerIP port context root request.getPath query String

4.3index展示界面

4.3.1top页面信息

  1. 显示欢迎进入好友页面:th:text="|欢迎进入${session.friend.nickName}的空间!|"

  2. 如果不是在自己空间,显示连接返回自己空间(即将friend更新为当前userBasic

    <span th:if="${session.userBasic.id!=session.friend.id}"><a th:href="@{|/user.do?operate=friend&id=${session.userBasic.id}|}" target="_top">返回自己的空间!</a>
    </span>
    

4.3.2left好友列表

  1. 点击好友时,页面刷新为好友的日志列表。

    • 根据id查询好友的userBasic信息,覆盖session.friend
    • main页面展示friend的topicList,而不是userBasic中的topicList。方法:给连接添加target="_top"

4.3.3main日志显示列表

  1. 日期显示的格式化与解析

    java

    //解析:看的懂 ---> 看不懂
    String dateStr = "2022-04-11 12:58:13";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try{Date date = sdf.parse(dateStr);
    }catch (ParseException e){e.printStackTrance();
    }
    //格式化:看不懂 ---> 看得懂
    Date date = new Date();
    String dateStr = sdf.format(date);
    

    thymeleaf

    #dates.format(topic.topicDate,'yyyy-MM-dd HH:mm:ss')
    

4.3.4detial日志详情

  1. 一句里面不能有两个style

  2. 配置thymeleaf文件

    @{}:表示省略了pro21/的绝对路径

    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" th:href="@{css/common.css}"><link rel="stylesheet" th:href="@{css/main.css}">
    </head>
    
  3. 需要获取主人日志,回复列表(每个回复对应的主人日志)。

  4. 日志中的主人回复没有显示

    <!--head中-->
    <script language="JavaScript">function showDelImg(imgId){document.getElementById(imgId).style.display='inline';}function hiddenDelImg(imgId){document.getElementById(imgId).style.display='none';}</script>
    <!--body中-->
    <td  th:onmouseover="|showDelImg('a${reply.id}')|" th:onmouseout="|hiddenDelImg('a${reply.id}')|">
    <a th:unless="${reply.hostReply!=null}" th:id="|a${reply.id}|" th:href="#" style="float: right;display: inline;">主人回复</a>
    </td>
    
  5. 可以删除的条件

    • 在我自己的空间
    • 这条评论是我发表的
  6. 异常:删除父表时,需要保证没有子表在引用父表

    MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`qqzonedb`.`t_host_reply`, CONSTRAINT `FK_host_reply` FOREIGN KEY (`reply`) REFERENCES `t_reply` (`id`))
    

四.开发套路总结

1.拷贝myssm

2.新建配置文件applicationContext.xml或者其他名字,在web.xml中指定文件名

3.在web.xml文件中配置:

  1. 配置前缀和后缀,这样thtmeleaf引擎就可以根据我们返回的字符串进行拼接,再跳转

    <context-param><param-name>view-prefix</param-name><param-value>/</param-value>
    </context-param>
    <context-param><param-name>view-suffix</param-name><param-value>.html</param-value>
    </context-param>
    
  2. 配置监听器要读取的参数,目的是加载IOC容器的配置文件(applicationContext.xml

    <context-param><param-name>contextConfigLocation</param-name><param-value>applicationContext</param-value>
    </context-param>
    

4.开发具体的业务模块:

  1. 一个具体的业务模块的纵向结构:

    • html页面
    • POJO
    • DAO接口和实现类
    • Service接口和实现类
    • Controller控制器组件
  2. 如果html页面有thymeleaf表达式,一定不能够直接访问,必须要经过PageController

  3. applicationContext.xml中配置DAO,Service,Controller,以及三者之间的依赖关系

  4. DAO实现类中,继承BaseDAO,然后实现具体的接口,注意泛型不能写错,例如:

    public class UserDAOImpl extends BaseDAO<User> implements UserDAO{}

  5. Service是业务控制类,需要注意

    • 业务逻辑封装在Service这一层,不要分散在Controller层。也不要出现在DAO层(需要保证DAO方法的单精度特性)
    • 当需要使用其他模块的功能的时候,尽量调用别人的service,而不是深入到其他模块的DAO细节
  6. Controller类的编写规则

    • applicationContext.xml中来配置Controller

      <bean id="user" class="com.atlff.qqzone.controllers.UserController">

      那么,用户在前端发请求时,对应的servletPath就是/User.do,其中“user”就是此处beanid

    • Controller中设计的方法名需要和operate的值一致

      public String login(String loginId, String pwd, HttpSession session){return "index";
      }
      

      此时验登录的表单如下:

      <form th:action="@{/user.do}" method="post"><input type="hidden" name="operate" value="login">
      </form>
      
    • 在表单中,组件的name属性和Controller中的方法参数名一致

      <input type="text" name="loginId">

      public String login(String loginId, String pwd, HttpSession session)

    • 另外,Controller中的方法不一定都是通过请求参数获取

      if("request".equals...) else if("resqonse".equals...) else if("session".equals...){//直接赋值
      }else{//此处才是从request的请求参数中获取request.getParameter("loginId")...
      }
      
    • DispatcherServlet中步骤的分类:

      0.从application作用域获取IOC容器

      1.解析servletPath,在IOC容器中寻找对应的Controlelr组件

      2.准备operate指定的方法所要求的参数

      3.调用operate指定的方法

      4.接收到执行operate指定的方法的返回值,对返回值进行处理 ----视图处理

    • 为什么DispatcherServlet能够从application作用域获取到IOC容器?

      ContextLoaderListener在容器启动时会执行初始化任务,而他的操作是:

      1.解析IOC的配置文件,创建一个一个的组件,并完成组件之间的依赖注入关系

      2.将IOC容器保存到application作用域

5.数据库连接异常

  1. 数据库连接失败

    原因:druid没有添加到部署包

    解决:在项目结构中的ProjectStructure中将jar包添加部署

  2. 数据库报错连接太多

    Data source rejected establishment of connection, message from server:"Too many connections"

    原因:DruidDataSourceFactory.createDataSource(properties);出现在createConnection中,导致创建多个连接池.

    解决:将连接池放置在初始化的代码段,而不是出现在方法中.

  3. 数据库连接失败

    原因:druid没有添加到部署包

    解决:在项目结构中的ProjectStructure中将jar包添加部署

  4. 数据库报错连接太多

    Data source rejected establishment of connection, message from server:"Too many connections"

    原因:DruidDataSourceFactory.createDataSource(properties);出现在createConnection中,导致创建多个连接池.

    解决:将连接池放置在初始化的代码段,而不是出现在方法中.

案例2:qqZone相关推荐

  1. 爬虫(11) selenium(下) 行为链 登录qq空间案例

    文章目录 第十一章 selenium(下)行为链登录qq空间 1. 行为链 2. selenium操作cookie 2.1 获取cookie 2.2 登录QQ空间 2.3 自己的方法登录QQ空间 2. ...

  2. python 网络编程之Socket通信案例消息发送与接收

    背景 网络编程是python编程中的一项基本技术.本文将实现一个简单的Socket通信案例消息发送与接收 正文 在python中的socket编程的大致流程图如上所示 我们来首先编写客户端的代码: # ...

  3. 2021年大数据ELK(十七):Elasticsearch SQL 订单统计分析案例

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 订单统计分析案例 一.案例介绍 二.创建索引 三.导入测试数据 四.统计不同支 ...

  4. 2021年大数据ELK(十六):Elasticsearch SQL(职位查询案例)

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 职位查询案例 一.查询职位索引库中的一条数据 二.将SQL转换为DSL 三.职 ...

  5. 2021年大数据ELK(四):Lucene的美文搜索案例

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 美文搜索案例 一.需求 二.准备工作 1.创建IDEA项目 2. ...

  6. ❤️让人心跳加速的陌陌案例,大数据必需学会的基础案例!❤️ 【推荐收藏】

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 已列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 陌陌案例 一.陌陌案例的需求说明 二.陌陌案例中表设计内容 1. ...

  7. 2021年大数据Hive(十二):Hive综合案例!!!

    全网最详细的大数据Hive文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 Hive综合案例 一.需求描述 二.项目表的字段 三.进 ...

  8. 2021年大数据Flink(三十八):​​​​​​​Table与SQL ​​​​​​案例五 FlinkSQL整合Hive

    目录 案例五 FlinkSQL整合Hive 介绍 集成Hive的基本方式 准备工作 1.添加hadoop_classpath 2.下载jar并上传至flink/lib目录 3.修改hive配置 4.启 ...

  9. 2021年大数据Flink(三十七):​​​​​​​Table与SQL ​​​​​​案例四

    目录 案例四 需求 代码实现 案例四 需求 从Kafka中消费数据并过滤出状态为success的数据再写入到Kafka {"user_id": "1", &qu ...

最新文章

  1. 中医研究登上Nature
  2. LINUX文件、目录权限及相关操作命令
  3. Struts2学习总结二
  4. 遍历Windows系统的内核模块(源码)
  5. ABAP应用服务器的HTTP响应状态码(Status Code)
  6. IdentityServer4-前后端分离的授权验证(六)
  7. 远控免杀专题(23)-SharpShooter免杀
  8. 前端学习(1780):前端调试之快速转存站点的方法
  9. idea的plugins无法使用marketplace plugins are not loaded
  10. Java事务管理之Hibernate
  11. Mac效率工具:Mosaic 1.3.3
  12. 方法、hadoop源码之JobQueueTaskScheduler-by小雨
  13. matlab计算涡度的函数_流函数涡量法的二维方腔流数值模拟matlab编程.doc
  14. 个人微信api接口调用,微信好友收发消息
  15. select设置默认的option
  16. html5 斜边,css斜切角 斜边 倒角
  17. 虚拟机设置BT4上网
  18. java百万级大数据量导出
  19. letcode 715
  20. 国内三大B2C网站首页的信息架构【收集整理,本人非原作者】

热门文章

  1. linux实现毛玻璃窗口,给Ubuntu 安装透明水晶毛玻璃效果主题[组图]
  2. 前端用队列实现击鼓传花游戏
  3. 在动态规划的海洋中遨游(一)
  4. com.alibaba.fastjson.JSONException: can not cast to JSONObject.
  5. Tachiyomi 使用指南:一款开源的聚合漫画阅读软件
  6. 4K激光电视进入万元时代,极米引领新一轮客厅革命
  7. 学习UI设计怎么样?为什么有人觉得UI设计找工作难?
  8. Jmeter用户自定义变量
  9. xboxone硬盘坏的表现_直视问题,教你怎么正确判断自己的移动硬盘出了什么故障...
  10. U盘怎么调整分区大小?u盘分区工具推荐