小言_互联网的博客

SSM框架实战-搭建自己的个人博客1

407人阅读  评论(0)

前言

本系列文章主要通过从零开始搭建自己的个人博客,来加深对SSM框架的学习与使用,了解一个系统从提出到设计-到开发-到测试-部署运行的过程,并记录在搭建过程中的学习心得、遇见的错误及解决方式。

个人博客的主要功能有:

  1. 博客列表展示:文章按照时间顺序(时间倒序:最新最先展示)列表展示
  2. 博客文章详情展示:展示文章全部内容,包含:作者、创建时间、所属目录、标签、文章标题、内容
  3. 用户权限管理:游客只能浏览文章、管理员可以发布文章、文章下线处理
  4. 添加文章功能:支持富文本编辑。可以调整字体大小、样式、键入代码等功能

界面展示:

前台博客列表界面

博客详情页面

后台管理页面 

 

登录页面

 

项目技术简介

系统实现的功能点

  1. 用户权限管理:普通的用户(游客)只能浏览文章、管理员用户可以发布文章、文章管理
  2. 博客列表展示:文章按照发布时间顺序(按照时间倒叙)展示 :博客类别、标签、博客名称、作者名、发布时间、阅读数量、博客的内容概括
  3. 博客详情页面:博客名称、作者、时间、博客内容、标签
  4. 博客后台列表:博客检索(类别、标签、博客名称)、博客列表(博客id、博客类别、标签、时间)、博客操作
  5. 新增博客功能:支持富文本编辑:可以调整大小、样式等

服务端技术

核心框架:Spring:5.2.8.RELEASE

web框架:SpringMVC:5.2.8.RELEASE

持久层框架:Mybatis 3.2.4

数据库连接池:阿里druid:0.2.6

数据库:MySQL5.XX

JSON数据处理:谷歌gson 2.3

前端技术

jsp

Ajax

前端框架:bootstrap

富文本编辑器:百度UEditor

数据库的设计

  • 用户表:账号id、账号名称、账号密码
  • 博客表:博客id、博客名称、博客内容、发布时间、阅读量、类别id、状态
  • 博客/标签对应表:博客id、标签的id
  • 标签表:标签id、标签名称(博客和标签:一对多:一个博客可以对应多个标签)
  • 类别表:类别ID、类别名称(博客和类别:一对一:一个博客对应一个类别)

创建SQL语句:


  
  1. DROP TABLE IF EXISTS `t_article`;
  2. CREATE TABLE `t_article` (
  3. `id` int( 11) NOT NULL AUTO_INCREMENT,
  4. `categoryId` int( 11) NOT NULL COMMENT '分类Id',
  5. `title` varchar( 40) NOT NULL COMMENT '标题',
  6. `content` blob NOT NULL COMMENT '内容',
  7. `description` varchar( 500) NOT NULL COMMENT '文章简介 用于列表显示',
  8. `statue` int( 11) NOT NULL DEFAULT '0' COMMENT '状态 0:正常 1:不可用',
  9. `author` varchar( 15) DEFAULT 'tulun' COMMENT '作者',
  10. `createTime` datetime NOT NULL COMMENT '发表时间',
  11. `showCount` int( 11) NOT NULL DEFAULT '0' COMMENT '浏览量',
  12. PRIMARY KEY ( `id`),
  13. ) ENGINE= InnoDB DEFAULT CHARSET=utf8 COMMENT= '文章表';
  14. -- ----------------------------
  15. -- Table structure for t_article_image
  16. -- ----------------------------
  17. DROP TABLE IF EXISTS `t_article_image`;
  18. CREATE TABLE `t_article_image` (
  19. `id` int( 11) NOT NULL AUTO_INCREMENT,
  20. `imageUrl` varchar( 100) NOT NULL COMMENT '图片地址',
  21. `articleId` int( 11) NOT NULL COMMENT '文章Id',
  22. PRIMARY KEY ( `id`, `articleId`),
  23. ) ENGINE= InnoDB DEFAULT CHARSET=utf8 COMMENT= '文章图 主要用于列表浏览';
  24. -- ----------------------------
  25. -- Table structure for t_tag
  26. -- ----------------------------
  27. DROP TABLE IF EXISTS `t_tag`;
  28. CREATE TABLE `t_tag` (
  29. `id` int( 11) NOT NULL AUTO_INCREMENT,
  30. `tagName` varchar( 25) NOT NULL COMMENT '标签名称 唯一',
  31. PRIMARY KEY ( `id`),
  32. UNIQUE KEY `tagName_UNIQUE` ( `tagName`)
  33. ) ENGINE= InnoDB AUTO_INCREMENT= 23 DEFAULT CHARSET=utf8 COMMENT= '标签表';
  34. -- ----------------------------
  35. -- Table structure for t_article_tag
  36. -- ----------------------------
  37. DROP TABLE IF EXISTS `t_article_tag`;
  38. CREATE TABLE `t_article_tag` (
  39. `articleId` int( 11) NOT NULL COMMENT '文章Id',
  40. `tagId` int( 11) NOT NULL COMMENT '标签Id',
  41. PRIMARY KEY ( `articleId`, `tagId`),
  42. ) ENGINE= InnoDB DEFAULT CHARSET=utf8 COMMENT= '文章标签中间表';
  43. -- ----------------------------
  44. -- Table structure for t_category
  45. -- ----------------------------
  46. DROP TABLE IF EXISTS `t_category`;
  47. CREATE TABLE `t_category` (
  48. `id` int( 11) NOT NULL AUTO_INCREMENT,
  49. `categoryName` varchar( 20) NOT NULL COMMENT '分类名称 唯一',
  50. `iconClass` varchar( 45) NOT NULL COMMENT '图标样式',
  51. `aliasName` varchar( 20) NOT NULL COMMENT '别名 唯一 比如新闻 就用News 代替 栏目Id不显示在url中',
  52. `sort` int( 11) NOT NULL DEFAULT '0' COMMENT '排序 (0-10)',
  53. PRIMARY KEY ( `id`),
  54. UNIQUE KEY `aliasName_UNIQUE` ( `aliasName`),
  55. UNIQUE KEY `categoryName_UNIQUE` ( `categoryName`)
  56. ) ENGINE= InnoDB DEFAULT CHARSET=utf8 COMMENT= '分类表 只支持一级分类 如果需要分多个层次 用标签来协助实现';
  57. -- ----------------------------
  58. -- Table structure for t_manager
  59. -- ----------------------------
  60. DROP TABLE IF EXISTS `t_manager`;
  61. CREATE TABLE `t_manager` (
  62. `id` int( 11) NOT NULL AUTO_INCREMENT,
  63. `userName` varchar( 25) NOT NULL COMMENT '用户名',
  64. `password` varchar( 45) NOT NULL,
  65. PRIMARY KEY ( `id`)
  66. ) ENGINE= InnoDB DEFAULT CHARSET=utf8;

框架结构搭建

SSM项目脚手架搭建

搭建如下框架结构:

目录说明:


  
  1. 目录说明:
  2. |-src
  3. | --mian
  4. | ---java JAVA源代码根目录
  5. | ----com
  6. | -----tulun
  7. | ------model 存放pogo类:基本基本的getter和setter方法
  8. | ------controller 展示层类包路径:前端用户请求映射到该包路径下类的实现
  9. | ------service 业务逻辑层包路径:业务逻辑实现,调用dao层服务
  10. | ------dao 数据库操作层包路径:提供对数据库的操作类与方法
  11. | ------util 工具类包路径
  12. | ---resource 配置文件根目录
  13. | ----myatis mybatis接口对应配置文件目录
  14. | ----spring-XXX.xml SSM中mybatis、spring核心、springMVC的全局配置文件
  15. | --webapp 前端页面内容根目录
  16. | ---WEB-INF
  17. | ----web.xml 前端页面必要配置文件
  18. |-pom.xml maven的配置文件

测试Demo

主要完成各个层之间的连接映射,完成从t_manager表中读取数据并进行回显

 

POJO类

根据数据库表t_manager,创建User类


  
  1. package com.tulun.model;
  2. /**
  3. * Description :
  4. * Created by Resumebb
  5. * Date :2021/4/17
  6. */
  7. public class User {
  8. private Integer id;
  9. private String name;
  10. private String passwd;
  11. public Integer getId() {
  12. return id;
  13. }
  14. public void setId(Integer id) {
  15. this.id = id;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public String getPasswd() {
  24. return passwd;
  25. }
  26. public void setPasswd(String passwd) {
  27. this.passwd = passwd;
  28. }
  29. }

Spring核心配置文件

这里用到了阿里巴巴的druid连接池


  
  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context= "http://www.springframework.org/schema/context"
  4. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. http://www.springframework.org/schema/context
  7. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  8. <!--开启注解-->
  9. <context:component-scan base-package="com.tulun"/>
  10. <!--配置数据源:借助连接池druid-->
  11. <bean id ="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
  12. <!--注入属性-->
  13. <property name="url" value="jdbc:mysql://localhost:3306/test"/>
  14. <property name="username" value="root"/>
  15. <property name="password" value="123456"/>
  16. </bean>
  17. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  18. <property name="dataSource" ref="dataSource"/>
  19. <!--注入mapper映射文件-->
  20. <property name="configLocation" value="classpath:spring-mybatis.xml"> </property>
  21. <property name="mapperLocations" value="classpath:mapper/*.xml"/>
  22. </bean>
  23. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  24. <property name="basePackage" value="com.tulun.dao"/>
  25. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
  26. </bean>
  27. </beans>

Spring-Mybatis配置文件


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!--根标签-->
  6. <configuration>
  7. </configuration>

SpringMVC配置文件


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xmlns:mvc= "http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
  8. http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
  9. <!--扫描controller写注解-->
  10. <context:component-scan base-package="com.tulun.controller"/>
  11. <!--配置映射器-->
  12. <mvc:annotation-driven/>
  13. <!--配置视图解析器-->
  14. <!--视图解析器-->
  15. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  16. <!--jsp页面前缀-->
  17. <property name="prefix" value="/WEB-INF/jsp/"/>
  18. <!--jsp后缀-->
  19. <property name="suffix" value=".jsp"/>
  20. <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
  21. </bean>
  22. </beans>

web配置文件


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation= "http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  6. <context-param>
  7. <param-name>contextConfigLocation </param-name>
  8. <param-value>classpath:spring-core.xml </param-value>
  9. </context-param>
  10. <listener>
  11. <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class>
  12. </listener>
  13. <!--前端控制器-->
  14. <servlet>
  15. <servlet-name>myBolg </servlet-name>
  16. <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
  17. <!--将springMVC的配置文件进行配置-->
  18. <init-param>
  19. <param-name>contextConfigLocation </param-name>
  20. <param-value>classpath:spring-mvc.xml </param-value>
  21. </init-param>
  22. </servlet>
  23. <servlet-mapping>
  24. <servlet-name>myBolg </servlet-name>
  25. <url-pattern>/ </url-pattern>
  26. </servlet-mapping>
  27. </web-app>

pom依赖


  
  1. <dependencies>
  2. <dependency>
  3. <groupId>junit </groupId>
  4. <artifactId>junit </artifactId>
  5. <version>4.11 </version>
  6. <scope>test </scope>
  7. </dependency>
  8. <!-- spring依赖-->
  9. <dependency>
  10. <groupId>org.springframework </groupId>
  11. <artifactId>spring-core </artifactId>
  12. <version>5.2.8.RELEASE </version>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework </groupId>
  16. <artifactId>spring-context </artifactId>
  17. <version>5.2.8.RELEASE </version>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework </groupId>
  21. <artifactId>spring-beans </artifactId>
  22. <version>5.2.8.RELEASE </version>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework </groupId>
  26. <artifactId>spring-expression </artifactId>
  27. <version>5.2.8.RELEASE </version>
  28. </dependency>
  29. <!--web依赖/spring mvc依赖-->
  30. <dependency>
  31. <groupId>org.springframework </groupId>
  32. <artifactId>spring-webmvc </artifactId>
  33. <version>5.2.8.RELEASE </version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework </groupId>
  37. <artifactId>spring-web </artifactId>
  38. <version>5.2.8.RELEASE </version>
  39. </dependency>
  40. <dependency>
  41. <groupId>javax.servlet </groupId>
  42. <artifactId>javax.servlet-api </artifactId>
  43. <version>3.1.0 </version>
  44. </dependency>
  45. <!--tomcat servlet api -->
  46. <dependency>
  47. <groupId>jstl </groupId>
  48. <artifactId>jstl </artifactId>
  49. <version>1.2 </version>
  50. </dependency>
  51. <dependency>
  52. <groupId>taglibs </groupId>
  53. <artifactId>standard </artifactId>
  54. <version>1.1.2 </version>
  55. </dependency>
  56. <!--mybatis依赖-->
  57. <dependency>
  58. <groupId>org.mybatis </groupId>
  59. <artifactId>mybatis </artifactId>
  60. <version>3.4.1 </version>
  61. </dependency>
  62. <dependency>
  63. <groupId>mysql </groupId>
  64. <artifactId>mysql-connector-java </artifactId>
  65. <version>5.1.39 </version>
  66. </dependency>
  67. <!-- 整合-->
  68. <dependency>
  69. <groupId>org.mybatis </groupId>
  70. <artifactId>mybatis-spring </artifactId>
  71. <version>1.3.0 </version>
  72. </dependency>
  73. <!-- 连接池-->
  74. <dependency>
  75. <groupId>com.mchange </groupId>
  76. <artifactId>c3p0 </artifactId>
  77. <version>0.9.5.2 </version>
  78. </dependency>
  79. <dependency>
  80. <groupId>org.springframework </groupId>
  81. <artifactId>spring-tx </artifactId>
  82. <version>5.2.8.RELEASE </version>
  83. </dependency>
  84. <dependency>
  85. <groupId>org.springframework </groupId>
  86. <artifactId>spring-jdbc </artifactId>
  87. <version>5.2.8.RELEASE </version>
  88. </dependency>
  89. <dependency>
  90. <groupId>javax.servlet.jsp.jstl </groupId>
  91. <artifactId>jstl </artifactId>
  92. <version>1.2 </version>
  93. </dependency>
  94. <dependency>
  95. <groupId>javax.servlet </groupId>
  96. <artifactId>servlet-api </artifactId>
  97. <version>2.5 </version>
  98. </dependency>
  99. <dependency>
  100. <groupId>com.google.code.gson </groupId>
  101. <artifactId>gson </artifactId>
  102. <version>2.3 </version>
  103. </dependency>
  104. <dependency>
  105. <groupId>com.alibaba </groupId>
  106. <artifactId>druid </artifactId>
  107. <version>0.2.6 </version>
  108. </dependency>
  109. <dependency>
  110. <groupId>commons-logging </groupId>
  111. <artifactId>commons-logging </artifactId>
  112. <version>1.1.1 </version>
  113. </dependency>
  114. <dependency>
  115. <groupId>commons-configuration </groupId>
  116. <artifactId>commons-configuration </artifactId>
  117. <version>1.9 </version>
  118. </dependency>
  119. </dependencies>

UserMapper


  
  1. import com.tulun.model.User;
  2. /**
  3. * Description :
  4. * Created by Resumebb
  5. * Date :2021/4/22
  6. */
  7. public interface UserMapper {
  8. public User getUserById(Integer id);
  9. }

UserService


  
  1. package com.tulun.service;
  2. import com.tulun.model.User;
  3. import com.tulun.dao.UserMapper;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. /**
  7. * Description :
  8. * Created by Resumebb
  9. * Date :2021/4/19
  10. */
  11. @Service
  12. public class UserService {
  13. @Autowired
  14. private UserMapper userMapper;
  15. public User getUserById(Integer id){
  16. if(id < 0)
  17. return new User();
  18. return userMapper.getUserById(id);
  19. }
  20. }

UserController

查询t_manager中的id为1的数据进行显示


  
  1. package com.tulun.controller;
  2. import com.tulun.model.User;
  3. import com.tulun.service.UserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.ResponseBody;
  8. /**
  9. * Description :
  10. * Created by Resumebb
  11. * Date :2021/4/22
  12. */
  13. @Controller
  14. public class UserController {
  15. @Autowired
  16. private UserService userService;
  17. @RequestMapping("/testUser")
  18. @ResponseBody
  19. public User testUser(){
  20. User user = userService.getUserById( 1);
  21. return user;
  22. }
  23. }

UserMapper.xml


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.tulun.dao.UserMapper">
  6. <resultMap id="UserMap" type="com.tulun.model.User">
  7. <result property="id" column="id"> </result>
  8. <result property="name" column="userName"> </result>
  9. <result property="passwd" column="password"> </result>
  10. </resultMap>
  11. <select id="getUserById" parameterType="int" resultMap="UserMap">
  12. select * from t_manager where id=#{id}
  13. </select>
  14. </mapper>

运行结果

 

错误记录

运行的界面显示unkown the request

 原因是因为端口被占用了,更改服务器的端口号就可以了。

报错org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException:
### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown error 1146

出现这个错误就要检查SQL查询语句,数据源的配置是否正确,经检查我报这个错是因为SQL查询语句manager写成了manger,用户名密码不对也会报这个错。

报错org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userServer'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.szh.easymvc.server.UserServer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

类似这种错,一是检查@Service有没有加上,二是检查映射文件有没有顶行写,第一行不能有空行。


转载:https://blog.csdn.net/qq_41573860/article/details/116048792
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场