JavaWeb 项目 --- 在线 OJ 平台 (二)

x33g5p2x  于2022-05-25 转载在 Java  
字(7.3k)|赞(0)|评价(0)|浏览(606)

1. 使用数据库实现题目管理

1.1 设计数据库

题目表一般有的属性:

  • 题号
  • 标题
  • 难度
  • 描述
  • 测试用例
  • 自带的代码
  1. create database if not exists Oj_Online;
  2. use Oj_Online;
  3. drop table if exists oj_problem;
  4. -- 题目表
  5. create table oj_problem(
  6. -- 题目的序号
  7. id int primary key auto_increment,
  8. -- 题目的标题
  9. title varchar(50),
  10. -- 题目的难度
  11. level varchar(50),
  12. -- 题目的描述
  13. description varchar(4096),
  14. -- 题目给定的代码
  15. templateCode varchar(4096),
  16. -- 题目的测试用例
  17. testCode varchar(4096)
  18. );

1.2 封装 DBUtil

在 common 中创建 DBUtil

  1. package common;
  2. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  3. import javax.sql.DataSource;
  4. import java.sql.Connection;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. /**
  9. * 数据库操作
  10. */
  11. public class DBUtil {
  12. public static final String URL = "jdbc:mysql://127.0.0.1:3306/Oj_Online?characterEncoding=utf8&useSSL=false";
  13. public static final String USERNAME = "root";
  14. public static final String PASSWORD = "";
  15. private static volatile DataSource dataSource = null;
  16. private static DataSource getDataSource() {
  17. if(dataSource == null){
  18. synchronized (DBUtil.class){
  19. if(dataSource == null){
  20. dataSource = new MysqlDataSource();
  21. ((MysqlDataSource) dataSource).setURL(URL);
  22. ((MysqlDataSource) dataSource).setUser(USERNAME);
  23. ((MysqlDataSource) dataSource).setPassword(PASSWORD);
  24. }
  25. }
  26. }
  27. return dataSource;
  28. }
  29. public static Connection getConnection() throws SQLException {
  30. return getDataSource().getConnection();
  31. }
  32. public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
  33. if(resultSet != null){
  34. try {
  35. resultSet.close();
  36. } catch (SQLException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. if(statement != null){
  41. try {
  42. statement.close();
  43. } catch (SQLException e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. if(connection != null) {
  48. try {
  49. connection.close();
  50. } catch (SQLException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. }

1.3 创建 Problem类

这个类表示一个题目

  1. package dao;
  2. public class Problem {
  3. private int id;
  4. private String title;
  5. private String level;
  6. private String description;
  7. private String templateCode;
  8. private String testCode;
  9. // ...一堆getter和setter
  10. }

1.4 创建 ProblemDao类

这个类封装了对 Problem类的增删改查操作.

1.4.1 实现新增题目的功能

  1. /**
  2. * 新增题目
  3. * @param problem 题目
  4. */
  5. public void insert(Problem problem){
  6. Connection connection = null;
  7. PreparedStatement statement =null;
  8. try {
  9. // 1. 建立连接
  10. connection = DBUtil.getConnection();
  11. // 2. 拼装 SQL 语句
  12. String sql = "insert into oj_problem values(null,?,?,?,?,?)";
  13. statement = connection.prepareStatement(sql);
  14. statement.setString(1,problem.getTitle());
  15. statement.setString(2,problem.getLevel());
  16. statement.setString(3,problem.getDescription());
  17. statement.setString(4,problem.getTemplateCode());
  18. statement.setString(5,problem.getTestCode());
  19. // 3. 执行 SQL 语句
  20. int ret = statement.executeUpdate();
  21. if(ret == 1){
  22. System.out.println("插入成功!");
  23. }else {
  24. System.out.println("插入失败!");
  25. }
  26. } catch (SQLException e) {
  27. e.printStackTrace();
  28. } finally {
  29. // 4. 关闭释放资源
  30. DBUtil.close(connection,statement,null);
  31. }
  32. }

1.4.2 实现删除题目的功能

  1. /**
  2. * 删除对应id的题目
  3. * @param id 题目的序号
  4. */
  5. public void delete(int id){
  6. Connection connection = null;
  7. PreparedStatement statement = null;
  8. try {
  9. // 1. 建立连接
  10. connection = DBUtil.getConnection();
  11. // 2. 拼装 SQL 语句
  12. String sql = "delete from oj_problem where id = ?";
  13. statement = connection.prepareStatement(sql);
  14. statement.setInt(1,id);
  15. // 3. 执行 SQL 语句
  16. int ret = statement.executeUpdate();
  17. if(ret == 1){
  18. System.out.println("删除成功!");
  19. }else {
  20. System.out.println("删除失败!");
  21. }
  22. } catch (SQLException e) {
  23. e.printStackTrace();
  24. } finally {
  25. // 4. 关闭释放资源
  26. DBUtil.close(connection,statement,null);
  27. }
  28. }

1.4.3 实现查询题目列表的功能

  1. /**
  2. * 查询题目列表
  3. * @return 题目列表
  4. */
  5. public List<Problem> selectAll(){
  6. Connection connection = null;
  7. PreparedStatement statement = null;
  8. ResultSet resultSet = null;
  9. List<Problem> list = new ArrayList<>();
  10. try {
  11. // 1. 建立连接
  12. connection = DBUtil.getConnection();
  13. // 2. 拼装 SQL 语句
  14. String sql = "select id,title,level from oj_problem";
  15. statement = connection.prepareStatement(sql);
  16. // 3. 执行 SQL 语句
  17. resultSet = statement.executeQuery();
  18. // 4. 遍历结果集
  19. while (resultSet.next()){
  20. Problem problem = new Problem();
  21. problem.setId(resultSet.getInt("id"));
  22. problem.setTitle(resultSet.getString("title"));
  23. problem.setLevel(resultSet.getString("level"));
  24. list.add(problem);
  25. }
  26. return list;
  27. } catch (SQLException e) {
  28. e.printStackTrace();
  29. }finally {
  30. // 5. 关闭释放资源
  31. DBUtil.close(connection,statement,resultSet);
  32. }
  33. return null;
  34. }

1.4.4 实现查找对应id题目的功能

  1. /**
  2. * 查找对应id的题目
  3. * @param id 题目序号
  4. * @return 返回一个题目
  5. */
  6. public Problem selectOne(int id){
  7. Connection connection = null;
  8. PreparedStatement statement = null;
  9. ResultSet resultSet = null;
  10. try {
  11. // 1. 建立连接
  12. connection = DBUtil.getConnection();
  13. // 2. 拼装 SQL 语句
  14. String sql = "select * from oj_problem where id = ?";
  15. statement = connection.prepareStatement(sql);
  16. statement.setInt(1,id);
  17. // 3. 执行 SQL 语句
  18. resultSet = statement.executeQuery();
  19. // 4. 遍历结果集
  20. if (resultSet.next()){
  21. Problem problem = new Problem();
  22. problem.setId(resultSet.getInt("id"));
  23. problem.setTitle(resultSet.getString("title"));
  24. problem.setLevel(resultSet.getString("level"));
  25. problem.setDescription(resultSet.getString("description"));
  26. problem.setTemplateCode(resultSet.getString("templateCode"));
  27. problem.setTestCode(resultSet.getString("testCode"));
  28. return problem;
  29. }
  30. } catch (SQLException e) {
  31. e.printStackTrace();
  32. } finally {
  33. // 5. 关闭释放资源
  34. DBUtil.close(connection,statement,resultSet);
  35. }
  36. return null;
  37. }

1.5 测试这几个功能

1.5.1 设计测试用例测试新增功能

  1. public static void main(String[] args) {
  2. ProblemDao problemDao = new ProblemDao();
  3. Problem problem = new Problem();
  4. problem.setTitle("两数之和");
  5. problem.setLevel("简单");
  6. problem.setDescription("给定一个整数数组 nums和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。\n" +
  7. "你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。\n" +
  8. "你可以按任意顺序返回答案。\n" +
  9. "示例 1:\n" +
  10. "输入:nums = [2,7,11,15], target = 9\n" +
  11. "输出:[0,1]\n" +
  12. "解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。\n" +
  13. "示例 2:\n" +
  14. "输入:nums = [3,2,4], target = 6\n" +
  15. "输出:[1,2]\n" +
  16. "示例 3:\n" +
  17. "输入:nums = [3,3], target = 6\n" +
  18. "输出:[0,1]\n" +
  19. "\n" +
  20. "提示:\n" +
  21. "2 <= nums.length <= 104\n" +
  22. "-109 <= nums[i] <= 109\n" +
  23. "-109 <= target <= 109\n" +
  24. "只会存在一个有效答案\n" +
  25. "进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?\n" +
  26. "来源:力扣(LeetCode)\n" +
  27. "链接:https://leetcode.cn/problems/two-sum\n" +
  28. "著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。");
  29. problem.setTemplateCode("class Solution {\n" +
  30. " public int[] twoSum(int[] nums, int target) {\n" +
  31. "\n" +
  32. " }\n" +
  33. "}");
  34. problem.setTestCode(" public static void main(String[] args) {\n" +
  35. " Solution solution = new Solution();\n" +
  36. " int[] test1 = {2,7,11,15};\n" +
  37. " int target1 = 9;\n" +
  38. " int[] res1 = solution.twoSum(test1, target1);\n" +
  39. " if (res1.length == 2 && res1[0] == 0 && res1[1] == 1){\n" +
  40. " System.out.println(\"testcase1 OK!\");\n" +
  41. " }else {\n" +
  42. " System.out.println(\"testcase1 FAILED!\");\n" +
  43. " }\n" +
  44. " int[] test2 = {3,2,4};\n" +
  45. " int target2 = 6;\n" +
  46. " int[] res2 = solution.twoSum(test2, target2);\n" +
  47. " if (res2.length == 2 && res2[0] == 1 && res2[1] == 2){\n" +
  48. " System.out.println(\"testcase2 OK!\");\n" +
  49. " }else {\n" +
  50. " System.out.println(\"testcase2 FAILED!\");\n" +
  51. " }\n" +
  52. " }");
  53. problemDao.insert(problem);
  54. }

查看数据库中的内容

1.5.2 测试删除功能

再次新增一个内容

执行以下代码

  1. ProblemDao problemDao = new ProblemDao();
  2. problemDao.delete(2);

再次查看数据库

1.5.3 测试查询列表功能

  1. ProblemDao problemDao = new ProblemDao();
  2. List<Problem> list = problemDao.selectAll();
  3. System.out.println(list);

1.5.4 测试查询对应id的功能

  1. ProblemDao problemDao = new ProblemDao();
  2. Problem problem = problemDao.selectOne(1);
  3. System.out.println(problem);

相关文章