ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Student Demo(实习的第一个小小小Demo)

2021-09-22 14:31:08  阅读:210  来源: 互联网

标签:Student GRADE Demo 视图 USER STUDENT 实习 成绩 ID


一、需求

使用WebService+Hibernate+Oracle完成一下这几个需求

(刚到公司实习,老大让我先自学给了几个简单项目练手)
1、能录入同学成绩;
2、获取全班成绩列表;
3、计算全班成绩平均分;
4、查询单个同学单科成绩;
5、合理设计表结构,这个也会检查。

二、建库建表

(一)数据库表的设计:使用的Oracle数据库

       学生表(STUDENT_USER)下面统称USER表:USER_ID为主键

 

 课程表(STUDENT_COURSE)下面统称COURSE表:COURSE_ID为主键

(这里为什么有英文又要中文后面设计视图的时候分析)。

 成绩表(STUDENT_GRADE)下面统称GRADE表(关联课程和学生表):

这里我用的是联合主键——(USER_ID,COURSE_ID),同时他们也是外键,分别关联USER表,COURSE表。USER_ID和USER表的约束为SET NULL 这样当我删除某条学生信息的时候,同时会删除该学生的所有信息。

(二)创建物化视图

为什么使用物化视图?(个人想法欢迎指点)

        物化视图的更新十分影响性能,但是用它来查询数据,那么可以节省很多的时间。、

        因为我觉得学生数据主要还是以查询为主,学生是没有权限去修改数据的,同时每次插入学生信息,一般就是在开学的时候,插入成绩就是在每次考试的时候,每次修改完半夜手动刷新就行了(我觉我在学校的成绩搞好几天才能查到这个原因),修改的次数比较少,所以我觉得建立一张物化视图,可以优化数据库,方便操作。

物化视图和普通视图的区别:

        普通视图其实还是使用Sql查询,每次查询还是重复查询Sql,我觉得除了方便没有其他意义(不让程序员查看其他字段信息?)具体不是很清楚。

        物化视图是直接建立一张物理表,存储在本地,等于生成了一张新的表,刷新的化一般就是手动刷新或者更改自动刷新,我这里使用的是自动刷新(主要是为了测试省事)

建立物化视图的SQl

SELECT 
			STUDENT_GRADE.USER_ID ID ,
			STUDENT_USER.USER_NAME NAME,
			STUDENT_USER.USER_SEX SEX,
			SUM(CASE STUDENT_GRADE.COURSE_ID 
					WHEN 1 THEN STUDENT_GRADE.USER_GRADE
					ELSE 0 END) LANGUAGE,	
			SUM(CASE STUDENT_GRADE.COURSE_ID 
					WHEN 2 THEN STUDENT_GRADE.USER_GRADE
					ELSE 0 END) ENGLISH,
			SUM(CASE STUDENT_GRADE.COURSE_ID 
					WHEN 3 THEN STUDENT_GRADE.USER_GRADE
					ELSE 0 END) MATHEMATICS,
			SUM(STUDENT_GRADE.USER_GRADE) TOTAL
		FROM
			STUDENT_USER JOIN STUDENT_GRADE
		ON
			STUDENT_USER.USER_ID = STUDENT_GRADE.USER_ID
GROUP BY STUDENT_USER.USER_NAME,
			   STUDENT_GRADE.USER_ID,
				 STUDENT_USER.USER_SEX

        至于之前为什么课程表中需要有中文,英文就是这个物化视图中的字段,中文的化到时候代码返回,会用到,同时可以用中文关联去查询英文,在去查找需要的字段。

 三、代码实现

(一)导入依赖

 <dependencies>

    <!--  启动业务用的包                                                                     -->
    <!--    Oracle 驱动-->
    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.2.0</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.4.1.Final</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.10</version>
    </dependency>

<!--    ws依赖 -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>3.0.1</version>
    </dependency>

    <!-- 日志引入  -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>

    <!-- spring 核心 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- spring web集成 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- spring 整合junit  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- junit 开发包 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
          <showWarnings>true</showWarnings>
        </configuration>
      </plugin>
      <!-- 运行tomcat7方法:tomcat7:run -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <!-- 指定端口 -->
          <port>8080</port>
          <!-- 请求路径 -->
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>

  (二)   文件配置

配置连接HIbernate

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>
    <session-factory>
        <!--        数据源配置-->
        <property name="connection.username">LUNA_MCS_SXS</property>
        <property name="connection.password">ewell</property>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@//192.168.(**).25:1521/EWELL</property>
        <!--    c3po-->
        <property name="hibernate.c3p0.acquire_increment">10</property>
        <property name="hibernate.c3p0.idle_test_period">10000</property>
        <property name="hibernate.c3p0.timeout">5000</property>
        <property name="hibernate.c3p0.max_size">30</property>
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_statements">10</property>

<!--        设置方言-->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <!--        答应SQL语句-->
        <property name="show_sql">true</property>
        <!--        格式化SQL-->
        <property name="format_sql">true</property>
        <!-- 配置在输出的SQL语句前面添加提示信息 -->
        <property name="use_sql_comments">true</property>
        <!--    注册实体关系文件-->
<!--        <mapping resource="dao/xml/StudentCourse.hbm.xml"></mapping>-->
        <mapping class="org.example.entity.StudentCourse"></mapping>
        <mapping class="org.example.entity.StudentUser"></mapping>
        <mapping class="org.example.entity.StudentGrade"></mapping>
        <mapping class="org.example.entity.MVStudent"></mapping>

    </session-factory>
</hibernate-configuration>

 配置web.xml文件

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>cxfservlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxfservlet</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>
    <!--2.spring容器配置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

配置 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:cxf="http://cxf.apache.org/core"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/core
        http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd
        http://cxf.apache.org/jaxrs
        http://cxf.apache.org/schemas/jaxrs.xsd">

        <!--
            Spring整合cxf发布基于restful风格服务,关键点:
            1. 服务地址
            2. 服务类
            服务完整访问地址:http://localhost:8080/ws/serviceWs

        -->
    <jaxws:server address="/serviceWs">
        <jaxws:serviceBean>
            <bean class="org.example.service.impl.StudentServiceImpl"></bean>
        </jaxws:serviceBean>
    </jaxws:server>

</beans>

(三)创建关联表(没啥好说的,和视图还有表关联)

关联GRADE表(其他表基本都一样的)

@Data
@Accessors(chain = true)
@Entity
@Table(name = "STUDENT_GRADE")
public class StudentGrade implements Serializable {
    @Id
    @Column(name = "USER_ID")
    private Integer userID;
    @Id
    @Column(name = "COURSE_ID")
    private Integer courseID;
    @Column(name = "USER_GRADE")
    private Integer grade;
}

(四)需求实现

1.修改或者插入学生成绩:

        思路的话用个对象接受学生信息,封装到映射学生表的类里面去,然后再把AllCourses对象里面的成绩拆离出来,插入到成绩表中。(挺简单的)

   @WebMethod(operationName = "ModifyTheStudent")
    public void setGrade(
            @WebParam(name = "StudentInformation") StudentInformation studentInformation) {
        //先拿到这个学生
        StudentUser studentUser = new StudentUser();
        studentUser.setId(studentInformation.getId());
        studentUser.setName(studentInformation.getName());
        studentUser.setSex(studentInformation.getSex());
        //语文成绩
        StudentGrade languageGrade = new StudentGrade();
        languageGrade.setUserID(studentInformation.getId())//学生学号
                .setCourseID(1)//课程id
                .setGrade(studentInformation.getGrades().getLanguage());//课程成绩
        //英语成绩
        StudentGrade englishGrade = new StudentGrade();
        englishGrade.setUserID(studentInformation.getId())
                .setCourseID(2)
                .setGrade(studentInformation.getGrades().getEnglish());
        //数学成绩
        StudentGrade mathematicsGrade = new StudentGrade();
        mathematicsGrade.setUserID(studentInformation.getId())
                .setCourseID(3)
                .setGrade(studentInformation.getGrades().getMathematics());
        session.merge(studentUser);
        System.out.println(studentUser);
        session.saveOrUpdate(languageGrade);
        System.out.println(languageGrade);
        session.saveOrUpdate(englishGrade);
        System.out.println(englishGrade);
        session.saveOrUpdate(mathematicsGrade);
        System.out.println(mathematicsGrade);
        session.beginTransaction().commit();
        //一开始不清除缓存是无法修改的,会报:(A different object with the same identifier value was already associated with the session :
        // [org.example.entity.StudentUser#65)的错误,是因为session中有原先这个id对象的缓存,相同id其他不同的对象无法加入,所以需要清楚一下缓存
        session.clear();
    }

首先我用一个StudentInformation 对象来接受传入的参数 :

StudentInformation : {

private Integer id; //学生的学号
private String name; //学生的名字
private String sex; //学生的性别
private AllCourses grades : {
        private Integer language;  //学生的语文成绩
        private Integer english;   //学生的英语成绩
        private Integer mathematics; //学生的数学成绩
    };
}

        一开始我是用一个Map集合接受学生的成绩的(其实后面很多返回值一开始都用了map),但是发现WebService好像不太建议使用map(有可能是我学艺不精,等以后慢慢学习),于是我该用对象接受。

        然后session(因为没清除缓存)这边我也遇见了问题:见这篇博客

2.获取所有学生的成绩

思路:这个就更简单了,直接获取物化视图遍历出来,也没啥好说的

    @WebMethod(operationName = "GetStudentGrades")
    public @WebResult(name = "StudentGrades") List<MVStudent> getGrade() {
        String hql = "from MVStudent ";
        return session.createQuery(hql).list();
    }

3.获取平均成绩

                因为老大只告诉我说要获取平均成绩,我也不知道获取什么的平均成绩,于是我干脆通过输入课程表中的课程编号获取这门课的平均成绩。 

        然后的话如果要获取总平均成绩的话,就输入课程表中没有的ID(其实也可以增加一个特殊ID是这个特殊ID就平均成绩)这样的话每次新增课程,课程表中ID也会相应的增加,依旧可以获取对应的课程成绩。

        判断的话我就直接拿他给我的id去查,查出来的list集合为空的话,那么就返回平均值。

  @WebMethod(operationName = "GetCourseAverage")
    public @WebResult(name = "CourseAverage")
    CourseScore getAverage(
            @WebParam(name = "CourseID") Integer courseId) {
        CourseScore average = new CourseScore();
        Integer vag = 0;
            //查询对方想要什么科目,取出这门课的名字和课程字段
            String hql = "from StudentCourse where id = ?1";
            //集合为空说明没查到对应课程,返回平均值
            List list1 = session.createQuery(hql)
                    .setParameter(1, courseId).list();
            if (list1.size() == 0){
                List<MVStudent> grade = getGrade();
                for (MVStudent mvStudent : grade) {
                    vag = vag + mvStudent.getTotal() / grade.size();
                }
                average.setCourse("总平均分").setVag(vag);
                return average;
            }
            StudentCourse course = (StudentCourse) list1.get(0);
            System.out.println(course);
            String sql = "select * from MV_STUDENT";
            List<Object> list = session.createNativeQuery(sql).addScalar(course.getCourseName()).list();
            System.out.println(list);
            for (Object o : list) {
                int i = Integer.parseInt(o.toString());
                vag = vag + i / list.size();
            }
            average.setCourse(course.getName()).setVag(vag);
        return average;
    }

遇见问题:

        这边遇见一个很尴尬的问题,主要感觉还是基础不牢(地动山摇啊)Hibernate 返回类型转Integer

4.获取某门课的成绩

这个也很简单,就是直接拿ID去物化视图里面查,然后取出自己想要的东西

    @WebMethod(operationName = "GetStudentGrade")
    public @WebResult(name = "StudentGrade")
    AllCourses getCourseGrade(
            @WebParam(name = "StudentID") Integer id) {
        AllCourses courseGrade = new AllCourses();
        String hql = "from MVStudent where id= ?1 ";
        Query query = UtilSession.getQuery().createQuery(hql);
        query.setParameter(1, id);
        List<MVStudent> list = query.list();
        MVStudent mvStudent = list.get(0);
        courseGrade.setLanguage(mvStudent.getLanguage())
                .setEnglish(mvStudent.getEnglish())
                .setMathematics(mvStudent.getMathematics());
        return courseGrade;
    }

总结:

1.表设计其他想法

        我一开始有另外一个想法,因为如果所有成绩放在一张表里面的话,一旦课程过多或者学生过多的话会导致成绩表特别的大和冗余,查询和遍历就很浪费时间。

        于是我打算一门课程一张表。课程表里面拿一个字段出来存储这门课程所在的表(其实也不用),这样子每次增加新的课程的话新增一张表就好了。我总结下自认为的优缺点

             优点:1、当数据量很大的时候查询速度快(比如大学里面大量数据)。2、插入方便,如果某个学生的某门课程需要更改(或者需要增加这门课程的分数),去对应的表里面修改就行了(而且还可以用多线程的方式并发插入,操作不同表的话,相对比多线程操作一张表要安全的多)。3、主要是我感觉这样子整个数据库的结构就清晰明了,不至于成绩表像锅大杂烩。

              缺点:1、数据库表过多?(空间换时间?)2、操作繁琐(每个学生可能因为选的课不一样,导致查询繁琐——我觉得可以学生表里面可以使用一个字段,去存储自己选修了那些课解决这个问题,所以我觉得这不是问题)?3.其他问题欢迎大家指点一下,菜鸟阶段很多不懂。

 

2.杂谈随笔      

        写这个东西大概花了我两天半左右,需要使用hibernate,Oracle,WebService(学习)

        因为这些东西都是刚学的,而且就学了一下子,了解的比较浅,所以最大的问题反而是依赖的选择(因为我有时候根本不知道有这个依赖),环境的搭建(有时候明明照着网上操作,总会出莫名其妙的问题),因为技术比较老,网上资料都是 1*年甚至0*年的,很多东西都淘汰了。

                1. 比如HIbernate和Oracle搭建,数据库驱动一开始需要去下载,后面想了想,公司Maven仓库里面肯定有配套的。下下来发现驱动好像HIbernate版本出问题,又去改了一下,搞了半天。然后很多配置也是0几年的,去网上找,很多配置都淘汰了,后面又找到官网去了

                2.反正配置方面乱七八糟的问题(我想这可能就是架构师为啥工资这么高的问题,哈哈)每次一个项目从0到有最难的就是项目配置搭建

        写代码业务其实就花了半天左右,这半天里面有一小半时间还是在解决上面说到的两个问题。感觉业务挺简单的。

标签:Student,GRADE,Demo,视图,USER,STUDENT,实习,成绩,ID
来源: https://blog.csdn.net/LMR1314/article/details/120409584

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有