在本文中,我们将展示如何使用 Java 和 Spring Boot 创建一个简单的试题管理系统。
1. 数据库设计
创建 Question 表
首先,您需要在数据库中创建一个存储试题信息的表。假设我们使用的是 MySQL 数据库,创建表的 SQL 语句如下:
CREATE TABLE `questions` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`question_text` VARCHAR(255) NOT NULL,
`option_a` VARCHAR(255) NOT NULL,
`option_b` VARCHAR(255) NOT NULL,
`option_c` VARCHAR(255) NOT NULL,
`option_d` VARCHAR(255) NOT NULL,
`answer` VARCHAR(255) NOT NULL
);
表中包含了题目(question_text)、四个选项(option_a, option_b, option_c, option_d)和正确答案(answer)。
2. 后端开发:Spring Boot 配置
2.1 创建 Spring Boot 项目
首先,我们需要使用 Spring Boot 来搭建后端服务。可以通过 Spring Initializr(https://start.spring.io/)来快速创建一个 Spring Boot 项目,选择以下依赖:
Spring Web
Spring Data JPA
MySQL Driver
Lombok(用于简化 Java 类的开发)
2.2 配置数据库连接
在 application.properties 文件中配置数据库连接:
spring.datasource.url=jdbc:mysql://localhost:3306/exam_db?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
在这里,我们配置了 MySQL 数据库的连接和 Hibernate 自动更新数据库模式。
3. 实体类和数据访问层
3.1 创建 Question 实体类
我们将创建一个 Question 实体类,用于映射数据库中的 questions 表:
@Entity
@Data // 使用 Lombok 自动生成 getter, setter 等方法
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String questionText;
private String optionA;
private String optionB;
private String optionC;
private String optionD;
private String answer;
}
3.2 创建 QuestionMapper 数据访问层
接下来,我们创建 QuestionMapper 接口,用于与数据库进行交互:
@Repository
public interface QuestionMapper extends JpaRepository<Question, Long> {
// 可以添加自定义查询方法
}
4. 解析上传的文档
4.1 使用 Apache POI 解析 DOC 文件
我们需要解析上传的 DOC 文件,并将文件内容转化为题目数据。在本例中,我们将使用 Apache POI 来解析 .docx 文件。
首先,添加 Apache POI 依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
4.2 创建解析服务
创建一个 QuestionService 类来处理文件上传和解析过程:
@Service
public class QuestionService {
@Autowired
private QuestionMapper questionMapper;
public void parseAndSaveQuestions(MultipartFile file) throws IOException {
XWPFDocument document = new XWPFDocument(file.getInputStream());
List<QuestionModel> modelQuestions = new ArrayList<>();
List<XWPFParagraph> paragraphs = document.getParagraphs();
QuestionModel currentModelQuestion = null;
for (XWPFParagraph paragraph : paragraphs) {
String text = paragraph.getText().trim();
if (text.isEmpty()) {
continue;
}
if (text.matches("^[0-9]+\\..*")) { // 匹配题目
if (currentModelQuestion != null) {
modelQuestions.add(currentModelQuestion);
}
currentModelQuestion = new QuestionModel();
currentModelQuestion.setOptions(new ArrayList<>()); // 确保选项列表初始化
currentModelQuestion.setQuestionText(text);
} else if (text.matches("^[A-D]\\..*")) { // 匹配选项
if (currentModelQuestion != null) {
currentModelQuestion.getOptions().add(text);
}
} else if (text.startsWith("答案:")) { // 匹配答案
if (currentModelQuestion != null) {
currentModelQuestion.setAnswer(text.replace("答案:", "").trim());
modelQuestions.add(currentModelQuestion);
currentModelQuestion = null;
}
}
}
// 将 Model 转换为 Entity,并保存到数据库
for (QuestionModel modelQuestion : modelQuestions) {
Question entityQuestion = QuestionConverter.convertToEntity(modelQuestion);
questionMapper.save(entityQuestion);
}
}
}
这段代码的作用是:
使用 XWPFDocument 解析 .docx 文件。
遍历文件中的每个段落,根据正则表达式匹配题目、选项和答案。
将解析到的数据保存到数据库。
4.3 创建 QuestionConverter 工具类
为了将解析后的数据保存到数据库,我们创建一个 QuestionConverter 工具类,用于将 QuestionModel 转换为 Question 实体:
public class QuestionConverter {
public static Question convertToEntity(QuestionModel model) {
Question entity = new Question();
entity.setQuestionText(model.getQuestionText());
entity.setOptionA(model.getOptions().get(0));
entity.setOptionB(model.getOptions().get(1));
entity.setOptionC(model.getOptions().get(2));
entity.setOptionD(model.getOptions().get(3));
entity.setAnswer(model.getAnswer());
return entity;
}
}
5. 文件上传控制器
5.1 创建文件上传控制器
我们创建一个控制器来处理文件上传请求:
@RestController
@RequestMapping("/questions")
public class QuestionController {
@Autowired
private QuestionService questionService;
@PostMapping("/upload")
public String uploadQuestions(@RequestParam("file") MultipartFile file) {
try {
questionService.parseAndSaveQuestions(file);
return "File uploaded and questions saved successfully!";
} catch (IOException e) {
return "Failed to upload file: " + e.getMessage();
}
}
}
这个控制器处理 /questions/upload 路径的 POST 请求,接收上传的文件并调用 QuestionService 来解析并保存试题。
6. 总结
通过以上步骤,我们完成了从数据库设计、后端开发到文件上传解析的流程。以下是关键步骤的总结:
数据库设计:创建 questions 表,包含题目、选项和答案。
后端开发:使用 Spring Boot 配置数据库连接,并实现数据访问层和服务层。
文件解析:使用 Apache POI 解析 DOC 文件,提取题目、选项和答案。
文件上传:创建控制器处理文件上传请求,并保存解析后的数据到数据库。