创建一个基于SSM(Spring, Spring MVC, MyBatis)的教学视频点播系统
开发指南:包括项目结构、数据库设计、配置文件、DAO层、Service层、Controller层和前端页面的示例。
1. 需求分析
明确系统的主要功能需求,例如:
- 用户注册与登录
- 视频上传与管理
- 视频播放与评论
- 分类管理
- 搜索功能
- 用户权限管理
2. 技术选型
确定使用的技术栈:
- 后端:Spring, Spring MVC, MyBatis
- 前端:HTML, CSS, JavaScript (可选框架如Vue.js或React.js)
- 数据库:MySQL
- 服务器:Tomcat
3. 数据库设计
设计数据库模型,比如用户表、视频表、分类表等。这里以用户表、视频表和分类表为例:
user
表
CREATE TABLE `user` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) NOT NULL UNIQUE,
`password` VARCHAR(100) NOT NULL,
`email` VARCHAR(100),
`phone` VARCHAR(20),
`role` VARCHAR(50) DEFAULT 'user',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP
);
video
表
CREATE TABLE `video` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(255) NOT NULL,
`description` TEXT,
`file_path` VARCHAR(255) NOT NULL,
`category_id` INT NOT NULL,
`upload_user_id` INT NOT NULL,
`upload_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`category_id`) REFERENCES `category`(`id`),
FOREIGN KEY (`upload_user_id`) REFERENCES `user`(`id`)
);
category
表
CREATE TABLE `category` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(100) NOT NULL UNIQUE,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP
);
4. 创建项目结构
使用IDE(如IntelliJ IDEA或Eclipse)创建一个新的Maven项目,并添加必要的依赖项到pom.xml
文件中。
5. 配置Spring和MyBatis
在src/main/resources
目录下创建配置文件,如applicationContext.xml
和mybatis-config.xml
,用于配置Spring和MyBatis。
applicationContext.xml
示例
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/video?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.video.mapper"/>
</bean>
6. 编写Mapper接口
定义MyBatis的Mapper接口来操作数据库。例如,为用户表、视频表和分类表创建UserMapper.java
、VideoMapper.java
和CategoryMapper.java
:
UserMapper.java
package com.video.mapper;
import com.video.entity.User;
import org.apache.ibatis.annotations.*;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE username = #{username}")
User findByUsername(@Param("username") String username);
@Insert("INSERT INTO user(username, password, email, phone, role) VALUES(#{username}, #{password}, #{email}, #{phone}, #{role})")
int insert(User user);
}
VideoMapper.java
package com.video.mapper;
import com.video.entity.Video;
import org.apache.ibatis.annotations.*;
@Mapper
public interface VideoMapper {
@Select("SELECT * FROM video")
List<Video> findAll();
@Select("SELECT * FROM video WHERE id = #{id}")
Video findById(@Param("id") int id);
@Insert("INSERT INTO video(title, description, file_path, category_id, upload_user_id) VALUES(#{title}, #{description}, #{file_path}, #{category_id}, #{upload_user_id})")
int insert(Video video);
@Update("UPDATE video SET title=#{title}, description=#{description}, file_path=#{file_path}, category_id=#{category_id}, upload_user_id=#{upload_user_id} WHERE id=#{id}")
int update(Video video);
@Delete("DELETE FROM video WHERE id=#{id}")
int delete(@Param("id") int id);
}
CategoryMapper.java
package com.video.mapper;
import com.video.entity.Category;
import org.apache.ibatis.annotations.*;
@Mapper
public interface CategoryMapper {
@Select("SELECT * FROM category")
List<Category> findAll();
@Select("SELECT * FROM category WHERE id = #{id}")
Category findById(@Param("id") int id);
@Insert("INSERT INTO category(name) VALUES(#{name})")
int insert(Category category);
@Update("UPDATE category SET name=#{name} WHERE id=#{id}")
int update(Category category);
@Delete("DELETE FROM category WHERE id=#{id}")
int delete(@Param("id") int id);
}
7. 实现Service层
编写服务层来处理业务逻辑。例如,创建一个UserService.java
、VideoService.java
和CategoryService.java
:
UserService.java
package com.video.service;
import com.video.entity.User;
import com.video.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User login(String username, String password) {
User user = userMapper.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
public void register(User user) {
userMapper.insert(user);
}
}
VideoService.java
package com.video.service;
import com.video.entity.Video;
import com.video.mapper.VideoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class VideoService {
@Autowired
private VideoMapper videoMapper;
public List<Video> getAllVideos() {
return videoMapper.findAll();
}
public Video getVideoById(int id) {
return videoMapper.findById(id);
}
public void addVideo(Video video) {
videoMapper.insert(video);
}
public void updateVideo(Video video) {
videoMapper.update(video);
}
public void deleteVideo(int id) {
videoMapper.delete(id);
}
}
CategoryService.java
package com.video.service;
import com.video.entity.Category;
import com.video.mapper.CategoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryService {
@Autowired
private CategoryMapper categoryMapper;
public List<Category> getAllCategories() {
return categoryMapper.findAll();
}
public Category getCategoryById(int id) {
return categoryMapper.findById(id);
}
public void addCategory(Category category) {
categoryMapper.insert(category);
}
public void updateCategory(Category category) {
categoryMapper.update(category);
}
public void deleteCategory(int id) {
categoryMapper.delete(id);
}
}
8. 控制器层
使用Spring MVC编写控制器来处理HTTP请求。例如,创建一个UserController.java
、VideoController.java
和CategoryController.java
:
UserController.java
package com.video.controller;
import com.video.entity.User;
import com.video.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
User user = userService.login(username, password);
if (user != null) {
return "redirect:/home";
} else {
return "login";
}
}
@PostMapping("/register")
public String register(@ModelAttribute User user) {
userService.register(user);
return "redirect:/login";
}
}
VideoController.java
package com.video.controller;
import com.video.entity.Video;
import com.video.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/video")
public class VideoController {
@Autowired
private VideoService videoService;
@GetMapping("/list")
public String listVideos(Model model) {
List<Video> videos = videoService.getAllVideos();
model.addAttribute("videos", videos);
return "videoList";
}
@GetMapping("/view/{id}")
public String viewVideo(@PathVariable("id") int id, Model model) {
Video video = videoService.getVideoById(id);
model.addAttribute("video", video);
return "videoView";
}
@GetMapping("/add")
public String showAddForm(Model model) {
model.addAttribute("video", new Video());
return "videoAdd";
}
@PostMapping("/add")
public String addVideo(@ModelAttribute Video video) {
videoService.addVideo(video);
return "redirect:/video/list";
}
@GetMapping("/edit/{id}")
public String showEditForm(@PathVariable("id") int id, Model model) {
Video video = videoService.getVideoById(id);
model.addAttribute("video", video);
return "videoEdit";
}
@PostMapping("/edit/{id}")
public String editVideo(@PathVariable("id") int id, @ModelAttribute Video video) {
video.setId(id);
videoService.updateVideo(video);
return "redirect:/video/list";
}
@GetMapping("/delete/{id}")
public String deleteVideo(@PathVariable("id") int id) {
videoService.deleteVideo(id);
return "redirect:/video/list";
}
}
CategoryController.java
package com.video.controller;
import com.video.entity.Category;
import com.video.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@GetMapping("/list")
public String listCategories(Model model) {
List<Category> categories = categoryService.getAllCategories();
model.addAttribute("categories", categories);
return "categoryList";
}
@GetMapping("/view/{id}")
public String viewCategory(@PathVariable("id") int id, Model model) {
Category category = categoryService.getCategoryById(id);
model.addAttribute("category", category);
return "categoryView";
}
@GetMapping("/add")
public String showAddForm(Model model) {
model.addAttribute("category", new Category());
return "categoryAdd";
}
@PostMapping("/add")
public String addCategory(@ModelAttribute Category category) {
categoryService.addCategory(category);
return "redirect:/category/list";
}
@GetMapping("/edit/{id}")
public String showEditForm(@PathVariable("id") int id, Model model) {
Category category = categoryService.getCategoryById(id);
model.addAttribute("category", category);
return "categoryEdit";
}
@PostMapping("/edit/{id}")
public String editCategory(@PathVariable("id") int id, @ModelAttribute Category category) {
category.setId(id);
categoryService.updateCategory(category);
return "redirect:/category/list";
}
@GetMapping("/delete/{id}")
public String deleteCategory(@PathVariable("id") int id) {
categoryService.deleteCategory(id);
return "redirect:/category/list";
}
}
9. 前端页面
根据需要设计前端页面,可以使用Thymeleaf作为模板引擎。例如,创建一个简单的登录页面login.html
和视频列表页面videoList.html
:
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login Page</title>
</head>
<body>
<form th:action="@{/user/login}" method="post">
<label>Username:</label><input type="text" name="username"/><br/>
<label>Password:</label><input type="password" name="password"/><br/>
<button type="submit">Login</button>
</form>
</body>
</html>
videoList.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Video List</title>
</head>
<body>
<h1>Video List</h1>
<table border="1">
<tr>
<th>ID</th>
<th>Title</th>
<th>Description</th>
<th>File Path</th>
<th>Category</th>
<th>Upload User</th>
<th>Upload Time</th>
<th>Actions</th>
</tr>
<tr th:each="video : ${videos}">
<td th:text="${video.id}"></td>
<td th:text="${video.title}"></td>
<td th:text="${video.description}"></td>
<td th:text="${video.file_path}"></td>
<td th:text="${video.category_id}"></td>
<td th:text="${video.upload_user_id}"></td>
<td th:text="${video.upload_time}"></td>
<td>
<a th:href="@{/video/view/{id}(id=${video.id})}">View</a>
<a th:href="@{/video/edit/{id}(id=${video.id})}">Edit</a>
<a th:href="@{/video/delete/{id}(id=${video.id})}">Delete</a>
</td>
</tr>
</table>
<a href="/video/add">Add New Video</a>
</body>
</html>
10. 测试与部署
完成所有编码后,进行单元测试确保各部分工作正常。之后,可以将应用部署到Tomcat服务器上。