基于SSM(Spring + Spring MVC + MyBatis)框架的旅游资源网站
基于SSM(Spring + Spring MVC + MyBatis)框架的旅游资源网站是一个经典的Java Web项目案例。
项目结构
tourism-website/
├── src/main/java/com/example/tourism/
│ ├── controller/
│ │ └── TouristAttractionController.java
│ ├── model/
│ │ ├── Comment.java
│ │ └── TouristAttraction.java
│ ├── service/
│ │ ├── CommentService.java
│ │ ├── CommentServiceImpl.java
│ │ ├── TouristAttractionService.java
│ │ └── TouristAttractionServiceImpl.java
│ └── dao/
│ ├── CommentMapper.java
│ └── TouristAttractionMapper.java
├── src/main/resources/
│ ├── mybatis-config.xml
│ ├── spring-mvc.xml
│ ├── applicationContext.xml
│ └── db.properties
└── src/main/webapp/
├── WEB-INF/
│ └── views/
│ ├── attractionDetail.jsp
│ └── index.jsp
└── static/
└── css/style.css
数据库表结构
假设我们有两个主要的数据库表:tourist_attraction
和 comment
。
CREATE TABLE tourist_attraction (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
location VARCHAR(255),
image_url VARCHAR(255)
);
CREATE TABLE comment (
id INT AUTO_INCREMENT PRIMARY KEY,
attraction_id INT,
user_name VARCHAR(255),
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (attraction_id) REFERENCES tourist_attraction(id)
);
Java代码
TouristAttraction.java
package com.example.tourism.model;
public class TouristAttraction {
private int id;
private String name;
private String description;
private String location;
private String imageUrl;
// getters and setters
}
Comment.java
package com.example.tourism.model;
import java.util.Date;
public class Comment {
private int id;
private int attractionId;
private String userName;
private String content;
private Date createdAt;
// getters and setters
}
TouristAttractionMapper.java
package com.example.tourism.dao;
import com.example.tourism.model.TouristAttraction;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface TouristAttractionMapper {
@Select("SELECT * FROM tourist_attraction")
List<TouristAttraction> getAll();
@Select("SELECT * FROM tourist_attraction WHERE id = #{id}")
TouristAttraction getById(int id);
}
CommentMapper.java
package com.example.tourism.dao;
import com.example.tourism.model.Comment;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface CommentMapper {
@Select("SELECT * FROM comment WHERE attraction_id = #{attractionId} ORDER BY created_at DESC")
List<Comment> getCommentsByAttractionId(int attractionId);
@Insert("INSERT INTO comment(attraction_id, user_name, content) VALUES(#{attractionId}, #{userName}, #{content})")
void addComment(Comment comment);
}
TouristAttractionService.java
package com.example.tourism.service;
import com.example.tourism.model.TouristAttraction;
import java.util.List;
public interface TouristAttractionService {
List<TouristAttraction> getAll();
TouristAttraction getById(int id);
}
TouristAttractionServiceImpl.java
package com.example.tourism.service.impl;
import com.example.tourism.dao.TouristAttractionMapper;
import com.example.tourism.model.TouristAttraction;
import com.example.tourism.service.TouristAttractionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TouristAttractionServiceImpl implements TouristAttractionService {
@Autowired
private TouristAttractionMapper mapper;
@Override
public List<TouristAttraction> getAll() {
return mapper.getAll();
}
@Override
public TouristAttraction getById(int id) {
return mapper.getById(id);
}
}
CommentService.java
package com.example.tourism.service;
import com.example.tourism.model.Comment;
import java.util.List;
public interface CommentService {
List<Comment> getCommentsByAttractionId(int attractionId);
void addComment(Comment comment);
}
CommentServiceImpl.java
package com.example.tourism.service.impl;
import com.example.tourism.dao.CommentMapper;
import com.example.tourism.model.Comment;
import com.example.tourism.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommentServiceImpl implements CommentService {
@Autowired
private CommentMapper mapper;
@Override
public List<Comment> getCommentsByAttractionId(int attractionId) {
return mapper.getCommentsByAttractionId(attractionId);
}
@Override
public void addComment(Comment comment) {
mapper.addComment(comment);
}
}
TouristAttractionController.java
package com.example.tourism.controller;
import com.example.tourism.model.Comment;
import com.example.tourism.model.TouristAttraction;
import com.example.tourism.service.CommentService;
import com.example.tourism.service.TouristAttractionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class TouristAttractionController {
@Autowired
private TouristAttractionService attractionService;
@Autowired
private CommentService commentService;
@GetMapping("/")
public String home(Model model) {
List<TouristAttraction> attractions = attractionService.getAll();
model.addAttribute("attractions", attractions);
return "index";
}
@GetMapping("/attraction/{id}")
public String attractionDetail(@PathVariable int id, Model model) {
TouristAttraction attraction = attractionService.getById(id);
List<Comment> comments = commentService.getCommentsByAttractionId(id);
model.addAttribute("attraction", attraction);
model.addAttribute("comments", comments);
return "attractionDetail";
}
@PostMapping("/attraction/{id}/comment")
public String addComment(@PathVariable int id, @RequestParam String userName, @RequestParam String content) {
Comment comment = new Comment();
comment.setAttractionId(id);
comment.setUserName(userName);
comment.setContent(content);
commentService.addComment(comment);
return "redirect:/attraction/" + id;
}
}
配置文件
db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tourism_db?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=password
applicationContext.xml
<?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.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.tourism"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.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.example.tourism.dao"/>
</bean>
</beans>
spring-mvc.xml
<?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.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.tourism.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:resources mapping="/static/**" location="/static/"/>
</beans>
mybatis-config.xml
<?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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
前端页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Tourism Website</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/static/css/style.css">
</head>
<body>
<h1>Welcome to Our Tourism Website</h1>
<div class="attractions">
<c:forEach var="attraction" items="${attractions}">
<div class="attraction">
<a href="<%=request.getContextPath()%>/attraction/${attraction.id}">
<img src="${attraction.imageUrl}" alt="${attraction.name}">
<h2>${attraction.name}</h2>
<p>${attraction.description}</p>
</a>
</div>
</c:forEach>
</div>
</body>
</html>
attractionDetail.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>${attraction.name}</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/static/css/style.css">
</head>
<body>
<h1>${attraction.name}</h1>
<img src="${attraction.imageUrl}" alt="${attraction.name}">
<p>${attraction.description}</p>
<h2>Comments</h2>
<ul>
<c:forEach var="comment" items="${comments}">
<li><strong>${comment.userName}</strong>: ${comment.content}</li>
</c:forEach>
</ul>
<form action="<%=request.getContextPath()%>/attraction/${attraction.id}/comment" method="post">
<label for="userName">Name:</label>
<input type="text" id="userName" name="userName" required>
<br>
<label for="content">Comment:</label>
<textarea id="content" name="content" rows="4" cols="50" required></textarea>
<br>
<button type="submit">Add Comment</button>
</form>
<a href="<%=request.getContextPath()%>/">Back to Home</a>
</body>
</html>
style.css
body {
font-family: Arial, sans-serif;
}
.attractions {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.attraction {
border: 1px solid #ccc;
padding: 10px;
width: calc(33% - 20px);
}
.attraction img {
max-width: 100%;
height: auto;
}
.attraction h2 {
margin-top: 10px;
}
form {
margin-top: 20px;
}
form label {
display: block;
margin-bottom: 5px;
}
form input[type="text"],
form textarea {
width: 100%;
padding: 8px;
margin-bottom: 10px;
}
form button {
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
form button:hover {
background-color: #0056b3;
}
以上是一个基于SSM框架的简单旅游资源网站的实现示例。你可以根据实际需求进一步扩展和完善这个项目,例如添加更多的功能模块、优化前端界面、增强后端服务等。