前言
本系列文章主要通过从零开始搭建自己的个人博客,来加深对SSM框架的学习与使用,了解一个系统从提出到设计-到开发-到测试-部署运行的过程,并记录在搭建过程中的学习心得、遇见的错误及解决方式。
个人博客的主要功能有:
- 博客列表展示:文章按照时间顺序(时间倒序:最新最先展示)列表展示
- 博客文章详情展示:展示文章全部内容,包含:作者、创建时间、所属目录、标签、文章标题、内容
- 用户权限管理:游客只能浏览文章、管理员可以发布文章、文章下线处理
- 添加文章功能:支持富文本编辑。可以调整字体大小、样式、键入代码等功能
界面展示:
前台博客列表界面
博客详情页面
后台管理页面
登录页面
项目技术简介
系统实现的功能点
- 用户权限管理:普通的用户(游客)只能浏览文章、管理员用户可以发布文章、文章管理
- 博客列表展示:文章按照发布时间顺序(按照时间倒叙)展示 :博客类别、标签、博客名称、作者名、发布时间、阅读数量、博客的内容概括
- 博客详情页面:博客名称、作者、时间、博客内容、标签
- 博客后台列表:博客检索(类别、标签、博客名称)、博客列表(博客id、博客类别、标签、时间)、博客操作
- 新增博客功能:支持富文本编辑:可以调整大小、样式等
服务端技术
核心框架: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语句:
-
DROP
TABLE
IF
EXISTS
`t_article`;
-
CREATE
TABLE
`t_article` (
-
`id`
int(
11)
NOT
NULL AUTO_INCREMENT,
-
`categoryId`
int(
11)
NOT
NULL
COMMENT
'分类Id',
-
`title`
varchar(
40)
NOT
NULL
COMMENT
'标题',
-
`content`
blob
NOT
NULL
COMMENT
'内容',
-
`description`
varchar(
500)
NOT
NULL
COMMENT
'文章简介 用于列表显示',
-
`statue`
int(
11)
NOT
NULL
DEFAULT
'0'
COMMENT
'状态 0:正常 1:不可用',
-
`author`
varchar(
15)
DEFAULT
'tulun'
COMMENT
'作者',
-
`createTime` datetime
NOT
NULL
COMMENT
'发表时间',
-
`showCount`
int(
11)
NOT
NULL
DEFAULT
'0'
COMMENT
'浏览量',
-
PRIMARY
KEY (
`id`),
-
)
ENGINE=
InnoDB
DEFAULT
CHARSET=utf8
COMMENT=
'文章表';
-
-
-
-- ----------------------------
-
-- Table structure for t_article_image
-
-- ----------------------------
-
DROP
TABLE
IF
EXISTS
`t_article_image`;
-
CREATE
TABLE
`t_article_image` (
-
`id`
int(
11)
NOT
NULL AUTO_INCREMENT,
-
`imageUrl`
varchar(
100)
NOT
NULL
COMMENT
'图片地址',
-
`articleId`
int(
11)
NOT
NULL
COMMENT
'文章Id',
-
PRIMARY
KEY (
`id`,
`articleId`),
-
)
ENGINE=
InnoDB
DEFAULT
CHARSET=utf8
COMMENT=
'文章图 主要用于列表浏览';
-
-
-- ----------------------------
-
-- Table structure for t_tag
-
-- ----------------------------
-
DROP
TABLE
IF
EXISTS
`t_tag`;
-
CREATE
TABLE
`t_tag` (
-
`id`
int(
11)
NOT
NULL AUTO_INCREMENT,
-
`tagName`
varchar(
25)
NOT
NULL
COMMENT
'标签名称 唯一',
-
PRIMARY
KEY (
`id`),
-
UNIQUE
KEY
`tagName_UNIQUE` (
`tagName`)
-
)
ENGINE=
InnoDB AUTO_INCREMENT=
23
DEFAULT
CHARSET=utf8
COMMENT=
'标签表';
-
-
-
-- ----------------------------
-
-- Table structure for t_article_tag
-
-- ----------------------------
-
DROP
TABLE
IF
EXISTS
`t_article_tag`;
-
CREATE
TABLE
`t_article_tag` (
-
`articleId`
int(
11)
NOT
NULL
COMMENT
'文章Id',
-
`tagId`
int(
11)
NOT
NULL
COMMENT
'标签Id',
-
PRIMARY
KEY (
`articleId`,
`tagId`),
-
)
ENGINE=
InnoDB
DEFAULT
CHARSET=utf8
COMMENT=
'文章标签中间表';
-
-
-- ----------------------------
-
-- Table structure for t_category
-
-- ----------------------------
-
DROP
TABLE
IF
EXISTS
`t_category`;
-
CREATE
TABLE
`t_category` (
-
`id`
int(
11)
NOT
NULL AUTO_INCREMENT,
-
`categoryName`
varchar(
20)
NOT
NULL
COMMENT
'分类名称 唯一',
-
`iconClass`
varchar(
45)
NOT
NULL
COMMENT
'图标样式',
-
`aliasName`
varchar(
20)
NOT
NULL
COMMENT
'别名 唯一 比如新闻 就用News 代替 栏目Id不显示在url中',
-
`sort`
int(
11)
NOT
NULL
DEFAULT
'0'
COMMENT
'排序 (0-10)',
-
PRIMARY
KEY (
`id`),
-
UNIQUE
KEY
`aliasName_UNIQUE` (
`aliasName`),
-
UNIQUE
KEY
`categoryName_UNIQUE` (
`categoryName`)
-
)
ENGINE=
InnoDB
DEFAULT
CHARSET=utf8
COMMENT=
'分类表 只支持一级分类 如果需要分多个层次 用标签来协助实现';
-
-
-
-- ----------------------------
-
-- Table structure for t_manager
-
-- ----------------------------
-
DROP
TABLE
IF
EXISTS
`t_manager`;
-
CREATE
TABLE
`t_manager` (
-
`id`
int(
11)
NOT
NULL AUTO_INCREMENT,
-
`userName`
varchar(
25)
NOT
NULL
COMMENT
'用户名',
-
`password`
varchar(
45)
NOT
NULL,
-
PRIMARY
KEY (
`id`)
-
)
ENGINE=
InnoDB
DEFAULT
CHARSET=utf8;
框架结构搭建
SSM项目脚手架搭建
搭建如下框架结构:
目录说明:
-
目录说明:
-
|-src
-
|
--mian
-
|
---java JAVA源代码根目录
-
|
----com
-
|
-----tulun
-
|
------model 存放pogo类:基本基本的getter和setter方法
-
|
------controller 展示层类包路径:前端用户请求映射到该包路径下类的实现
-
|
------service 业务逻辑层包路径:业务逻辑实现,调用dao层服务
-
|
------dao 数据库操作层包路径:提供对数据库的操作类与方法
-
|
------util 工具类包路径
-
|
---resource 配置文件根目录
-
|
----myatis mybatis接口对应配置文件目录
-
|
----spring-XXX.xml SSM中mybatis、spring核心、springMVC的全局配置文件
-
|
--webapp 前端页面内容根目录
-
|
---WEB-INF
-
|
----web.xml 前端页面必要配置文件
-
|-pom.xml maven的配置文件
测试Demo
主要完成各个层之间的连接映射,完成从t_manager表中读取数据并进行回显
POJO类
根据数据库表t_manager,创建User类
-
package com.tulun.model;
-
-
/**
-
* Description :
-
* Created by Resumebb
-
* Date :2021/4/17
-
*/
-
public
class User {
-
private Integer id;
-
private String name;
-
private String passwd;
-
-
public Integer getId() {
-
return id;
-
}
-
-
public void setId(Integer id) {
-
this.id = id;
-
}
-
-
public String getName() {
-
return name;
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
-
public String getPasswd() {
-
return passwd;
-
}
-
-
public void setPasswd(String passwd) {
-
this.passwd = passwd;
-
}
-
}
Spring核心配置文件
这里用到了阿里巴巴的druid连接池
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:context=
"http://www.springframework.org/schema/context"
-
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
-
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-
http://www.springframework.org/schema/context
-
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-
-
<!--开启注解-->
-
<context:component-scan base-package="com.tulun"/>
-
-
<!--配置数据源:借助连接池druid-->
-
<bean id ="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
-
<!--注入属性-->
-
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
-
<property name="username" value="root"/>
-
<property name="password" value="123456"/>
-
</bean>
-
-
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
-
<property name="dataSource" ref="dataSource"/>
-
<!--注入mapper映射文件-->
-
<property name="configLocation" value="classpath:spring-mybatis.xml">
</property>
-
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
-
-
</bean>
-
-
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
-
<property name="basePackage" value="com.tulun.dao"/>
-
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
-
</bean>
-
-
</beans>
Spring-Mybatis配置文件
-
<?xml version="1.0" encoding="UTF-8" ?>
-
<!DOCTYPE configuration
-
PUBLIC
"-//mybatis.org//DTD Config 3.0//EN"
-
"http://mybatis.org/dtd/mybatis-3-config.dtd">
-
<!--根标签-->
-
<configuration>
-
</configuration>
SpringMVC配置文件
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:context=
"http://www.springframework.org/schema/context"
-
xmlns:mvc=
"http://www.springframework.org/schema/mvc"
-
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
-
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
-
<!--扫描controller写注解-->
-
<context:component-scan base-package="com.tulun.controller"/>
-
-
<!--配置映射器-->
-
<mvc:annotation-driven/>
-
-
<!--配置视图解析器-->
-
<!--视图解析器-->
-
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
-
<!--jsp页面前缀-->
-
<property name="prefix" value="/WEB-INF/jsp/"/>
-
<!--jsp后缀-->
-
<property name="suffix" value=".jsp"/>
-
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
-
</bean>
-
-
</beans>
web配置文件
-
<?xml version="1.0" encoding="UTF-8"?>
-
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
-
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee
-
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
-
-
<context-param>
-
<param-name>contextConfigLocation
</param-name>
-
<param-value>classpath:spring-core.xml
</param-value>
-
</context-param>
-
<listener>
-
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
-
</listener>
-
-
<!--前端控制器-->
-
<servlet>
-
<servlet-name>myBolg
</servlet-name>
-
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
-
<!--将springMVC的配置文件进行配置-->
-
<init-param>
-
<param-name>contextConfigLocation
</param-name>
-
<param-value>classpath:spring-mvc.xml
</param-value>
-
</init-param>
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>myBolg
</servlet-name>
-
<url-pattern>/
</url-pattern>
-
</servlet-mapping>
-
-
</web-app>
pom依赖
-
<dependencies>
-
<dependency>
-
<groupId>junit
</groupId>
-
<artifactId>junit
</artifactId>
-
<version>4.11
</version>
-
<scope>test
</scope>
-
</dependency>
-
-
<!-- spring依赖-->
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-core
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-context
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-beans
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-expression
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
-
<!--web依赖/spring mvc依赖-->
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-webmvc
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-web
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
<dependency>
-
<groupId>javax.servlet
</groupId>
-
<artifactId>javax.servlet-api
</artifactId>
-
<version>3.1.0
</version>
-
</dependency>
-
-
<!--tomcat servlet api -->
-
<dependency>
-
<groupId>jstl
</groupId>
-
<artifactId>jstl
</artifactId>
-
<version>1.2
</version>
-
</dependency>
-
<dependency>
-
<groupId>taglibs
</groupId>
-
<artifactId>standard
</artifactId>
-
<version>1.1.2
</version>
-
</dependency>
-
-
<!--mybatis依赖-->
-
<dependency>
-
<groupId>org.mybatis
</groupId>
-
<artifactId>mybatis
</artifactId>
-
<version>3.4.1
</version>
-
</dependency>
-
<dependency>
-
<groupId>mysql
</groupId>
-
<artifactId>mysql-connector-java
</artifactId>
-
<version>5.1.39
</version>
-
</dependency>
-
-
<!-- 整合-->
-
<dependency>
-
<groupId>org.mybatis
</groupId>
-
<artifactId>mybatis-spring
</artifactId>
-
<version>1.3.0
</version>
-
</dependency>
-
-
<!-- 连接池-->
-
<dependency>
-
<groupId>com.mchange
</groupId>
-
<artifactId>c3p0
</artifactId>
-
<version>0.9.5.2
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-tx
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework
</groupId>
-
<artifactId>spring-jdbc
</artifactId>
-
<version>5.2.8.RELEASE
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>javax.servlet.jsp.jstl
</groupId>
-
<artifactId>jstl
</artifactId>
-
<version>1.2
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>javax.servlet
</groupId>
-
<artifactId>servlet-api
</artifactId>
-
<version>2.5
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>com.google.code.gson
</groupId>
-
<artifactId>gson
</artifactId>
-
<version>2.3
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>com.alibaba
</groupId>
-
<artifactId>druid
</artifactId>
-
<version>0.2.6
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>commons-logging
</groupId>
-
<artifactId>commons-logging
</artifactId>
-
<version>1.1.1
</version>
-
</dependency>
-
-
<dependency>
-
<groupId>commons-configuration
</groupId>
-
<artifactId>commons-configuration
</artifactId>
-
<version>1.9
</version>
-
</dependency>
-
-
</dependencies>
UserMapper
-
import com.tulun.model.User;
-
-
/**
-
* Description :
-
* Created by Resumebb
-
* Date :2021/4/22
-
*/
-
public
interface UserMapper {
-
public User getUserById(Integer id);
-
}
UserService
-
package com.tulun.service;
-
-
import com.tulun.model.User;
-
import com.tulun.dao.UserMapper;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Service;
-
-
/**
-
* Description :
-
* Created by Resumebb
-
* Date :2021/4/19
-
*/
-
@Service
-
public
class UserService {
-
@Autowired
-
private UserMapper userMapper;
-
-
public User getUserById(Integer id){
-
if(id <
0)
-
return
new User();
-
return userMapper.getUserById(id);
-
}
-
}
UserController
查询t_manager中的id为1的数据进行显示
-
package com.tulun.controller;
-
-
import com.tulun.model.User;
-
import com.tulun.service.UserService;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.ResponseBody;
-
-
/**
-
* Description :
-
* Created by Resumebb
-
* Date :2021/4/22
-
*/
-
@Controller
-
public
class UserController {
-
@Autowired
-
private UserService userService;
-
-
@RequestMapping("/testUser")
-
@ResponseBody
-
public User testUser(){
-
User user = userService.getUserById(
1);
-
return user;
-
}
-
}
UserMapper.xml
-
<?xml version="1.0" encoding="UTF-8" ?>
-
<!DOCTYPE mapper
-
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
-
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
<mapper namespace="com.tulun.dao.UserMapper">
-
<resultMap id="UserMap" type="com.tulun.model.User">
-
<result property="id" column="id">
</result>
-
<result property="name" column="userName">
</result>
-
<result property="passwd" column="password">
</result>
-
</resultMap>
-
-
<select id="getUserById" parameterType="int" resultMap="UserMap">
-
select * from t_manager where id=#{id}
-
</select>
-
</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
查看评论