曲线救国的表操作

        昨天继续在写用jsoup爬取教务系统中学生成绩,在数据爬取后,需要在用户登录的时候,及时爬取该用户在教务系统中的学习成绩,防止学生成绩更新,然后将最新的成绩存储到score表中,这就有如下的几个问题:

        1.当用户第一次使用test.jsp进行登录的时候,score表中没有该用户的成绩,需要通过score检索来判断是否存在用户成绩信息 ,然后根据返回值来确定是插入还是更新(其实第一次应该默认为插入数据),

        2.当用户曾使用过test.jsp模拟登录(也就是score表中曾在用户的成绩信息),这时候就需要判断score表中的成绩信息和教务系统中爬取出来的成绩信息是否一样,当两者一样的时候,应该不进行任何操作,当两者不一样的时候,我们又需要判断score表中的成绩信息和教务系统成绩信息的差别,我们的目的是做到score中的数据,同步教务系统而不重复.

        3.我们知道,当某同学挂科时候,其实是有两个该课程的分数,只是标志不一样,就像这样(这是我昨天做好存入到score表中的数据).

也就是说,我们如果想根据学号+课程名称来联合查找,是否存在该课程成绩(1.成绩更新2.老师上传成绩错误,出现修改(我的成绩曾经就这样过)3.补考),这样最直接的错误就是,当出现补考的 时候,我们的判断思路就出现了明显的问题,存取的数据也会出现遗漏(判断过程中的特殊情况遗漏).

           4.我昨天下午一直在 修改这个问题,可能是我的思路太直接,过分的判断操作的if.....else情况,没有想过从反面来操作,这样更好,我昨天最原始的做法,代码如下,记录一哈

	private void diffWayByJudge(int i) {
//		由于存在多科目的成绩,所以没有课做做完循环读取后,就应该将score对象写入到score表中,以免数据覆盖
		if (i % 14 == 0) {
			System.out.println(i);
			// 循环一科目,i递加13,等到i++到14时,就往score表中存储对象
			ScoreDAO scoreDAO = new ScoreDAO();
			score.setSid(student.getSid());
			 //通过sid查询,课程名称来判断score表中是否有sid学号的成绩记录,是否需要插入 数据,避免重复往数据库中添加数据
			try {
				if (scoreDAO.findScoreBySid(student.getSid()) != null) {
					// 存在socre对象集合,有成绩记录,可尝试更新
					System.out.println("!!!!!!!!!-->" + score.getKcmc());// 当i=14的整数倍的时候,其实,是获取上一个score的getkcmc()值,出现错误;
					Score jScore = new Score();
					jScore = scoreDAO.findScoreBySidAndKcmc(student.getSid(), score.getKcmc());
					if (jScore == null) {
						// 不存在,需要将该科目写入到数据库中入
						scoreDAO.insert(score);
					} else {
						/**
						 * 存在,尝试更新(考虑到老师在上传成绩的时候,出现问题,学生申诉,以免二次存储无法刷新)
						 * 也有可能该科目存在补考
						 */
						// 判断补考的情况,两次分数不一样,而且两个的考试性质不一样
						if (jScore.getZcj() != score.getZcj() && jScore.getKsxz() != score.getKsxz()) {
							// 补考
							scoreDAO.insert(score);
						} else if (jScore.getZcj() == score.getZcj() && jScore.getKsxz() == score.getKsxz()) {
							// 数据重合,覆盖;不能进行数据库操作
						} else {
							// 教师上传成绩错误,及时更正结果
							scoreDAO.update(score);
						}
					}
				} else {
					// 之前没有该学生的数据集,直接插入数据
					scoreDAO.insert(score);
				}

			} catch (ClassNotFoundException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

像这样的分多种情况考虑,到最后,其实混淆了自己的思路 ,相反不能够很好的得到操作的结果.不过昨天在买晚饭回来的路上,我想到的另外一种做法,刚好是我之前用diffWayByJudge(int i)来判断的反面,我的思路是:

        当用户用test.jsp登录成功后,我只需要用用户的学号向数据库中查询,是否存在该学生的成绩记录,这样如果存在,我们就直接将所有的记录删除,我们要做的其实就是同步教务系统的成绩信息 ,那么直接将之前有的或没有的信息都做一个判断之后,删除,然后将该学号学生的是所有最新成绩,插入到score表中,将数据及时的更新,这样便不会存在数据遗漏的问题.

代码如下:

		/**
		 * 方法一:直接判断后台的score表中是否有该学号同学的成绩记录,直接将其全部删除,然后重新将从教务系统网页源码上爬取下来的成绩记录存入到是score表中,实现更新;
		 * 优点:1.可实现更新,且思路清晰
		 * 2.和判断多种成绩情况(补考,成绩登记错误等情况)相比,这种思路更加直接,且能够在用户进行登录的同时,实时的将成绩存储到score
		 * 3.代码量小,容易判断 操作 方法二:diffWayByJudge() 功能不完善
		 */
		ScoreDAO scoreDAO = new ScoreDAO();
		try {
			if (scoreDAO.findScoreBySid(student.getSid()) != null) {
				// 存在记录,直接删除
				scoreDAO.deleteBySid(student.getSid());
				if (scoreDAO.findScoreBySid(student.getSid()) == null) {
					// 删除记录成功
					System.out.println("记录删除成功!");
				}
			}

			int i = 1;//循环标记
			for (Element element : tr) {
				switch (i % 13) {
				// 开课学期
				case 4:
					score.setKkxq(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 课程名称
				case 5:
					score.setKcmc(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 考试分数
				case 6:
					score.setZcj(element.text().trim());
					System.out.print(element.text() + "\t");
					String onclickStr = element.select("a").attr("onclick");

					// 截取成绩详情的url链接,写入
					score.setCjurl(onclickStr.substring(onclickStr.indexOf("'") + 1, onclickStr.lastIndexOf("'")));
					System.out.println(
							onclickStr.substring(onclickStr.indexOf("'") + 1, onclickStr.lastIndexOf("'")) + "\t");
					break;
				// 课程性质
				case 8:
					score.setKcxz(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 课程类别
				case 9:
					score.setType(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 学时
				case 10:
					score.setTime(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 课程学分
				case 11:
					score.setXf(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 考试性质
				case 12:
					score.setKsxz(element.text().trim());
					System.out.print(element.text() + "\t");
					break;
				// 补考时间
				case 0:
					score.setBkxq(element.text().trim());
					System.out.print(element.text() + "\t");
					System.out.println("-------------------");
					break;
				default:
					break;
				}
				if (i%13==0) {
					// 对score表,直接插入数据
					scoreDAO.insert(score);
				}
				i++;
			}
			
			// 尝试更新学习成绩,可记录到record表中;

		} catch (ClassNotFoundException | SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

总结一哈:

            错误的路上需要我们不断的尝试错误,这样才能在茫然无措的时候,否定之前的做法,向死而生,生活也是一样,不能总是盯着一面看,我们要 学会看事物的背面,这样才能有收获!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值