zoukankan      html  css  js  c++  java
  • 谷粒学院_day08_课程管理_添加课程之课程发布(后端开发)

    终于来到添加课程的第3个步骤:课程信息的最终确认,其实这个步骤对于后端来说就是查之前第一个步骤的数据,抽象的话就是课程信息,但是说得具体点包含课程,课程简介,对应讲师,对应分类(注意,这里不查课程章节和小节),所以数据库的话我们得查4张表,查的方式有两种:单表查询和多表关联查询

      》单表查询适用于需要查询的表不多的情况下,我们可以一张一张查,查完再依次设置到实体类中

      》多表查询适用于需要查询的表多的情况下,因为表一多,单表查询的代码就会变多了,还要一一设置到实体类中就很麻烦,而多表关联查询可以一次性查出来我们需要的表字段,然后再设置到提前设计好的实体类就可以了。如果要说缺点就是sql语句难写,查询效率没有单表高

      这次我们使用多表关联查询,首先得确认哪些表是要查的?分别是:课程表,课程简介表,讲师表,分类表(包含一级和二级分类)

      表确认完之后,再考虑一个事,多表连接的话是内连接还是外连接呢?平时开发中使用最多的就是这两个了,我说下这两个的特点:

        》内连接是要求全部【连接条件】必须满足,也就是全部匹配才查出来

        》而外连接分为左外和右外,就不详说这两个了,只是换个方向而已。外连接是除了匹配的数据外,还保留左或右表中未匹配的数据,不过要记住一点的是,这里说未匹配的数据,只是指【连接条件】未全部满足的,而不是where和having的条件,这两者不满足的话肯定不会查出来的

      在本次的课程信息查询中,我们采用左外连接,为什么呢?因为可能存在课程不存在讲师或分类,但是该课程是不是也得查出来啊;好了,就来先写sql语句先把,毕竟DAO使用mybatis,还是需要写sql语句的,如下:

        SELECT ec.id,ec.title,ec.price,ec.lesson_num AS lessonNum,ec.cover,
                   et.name AS teacherName,
                   es1.title AS subjectLevelOne,
                   es2.title AS subjectLevelTwo
            FROM edu_course ec LEFT OUTER JOIN edu_course_description ecd ON ec.id=ecd.id
                               LEFT OUTER JOIN edu_teacher et ON ec.teacher_id=et.id
                               LEFT OUTER JOIN edu_subject es1 ON ec.subject_parent_id=es1.id
                       LEFT OUTER JOIN edu_subject es2 ON ec.subject_id=es2.id
            WHERE ec.id=#{courseId}

      sql语句写完,测试也通了,剩下就是写mapper了,是不是有点激动啊?一直在使用别人提供单表查询的API,好久没写sql和mapper了吧,还是以前的老套路:写mapper接口=》mapper配置文件的编写,如下:

      mapper:

    public interface EduCourseMapper extends BaseMapper<EduCourse> {
        public CoursePublishVo getPublishCourse(String courseId);
    }

      mapper配置文件:

        <!-- 根据课程ID查询课程信息   -->
        <select id="getPublishCourse" parameterType="String" resultType="cn.aib.eduservice.entity.vo.CoursePublishVo">
            SELECT ec.id,ec.title,ec.price,ec.lesson_num AS lessonNum,ec.cover,
                   et.name AS teacherName,
                   es1.title AS subjectLevelOne,
                   es2.title AS subjectLevelTwo
            FROM edu_course ec LEFT OUTER JOIN edu_course_description ecd ON ec.id=ecd.id
                               LEFT OUTER JOIN edu_teacher et ON ec.teacher_id=et.id
                               LEFT OUTER JOIN edu_subject es1 ON ec.subject_parent_id=es1.id
                       LEFT OUTER JOIN edu_subject es2 ON ec.subject_id=es2.id
            WHERE ec.id=#{courseId}
        </select>

      然后service=》controller,接着就可以测试了;对了,由于查询出来的字段和之前表单提交上来字段不符合,就不用封装表单的实体类的,创建新的一个实体类符合给客户端,实体类我也贴一下,如下:

    @Data
    public class CoursePublishVo {
        private String id;
        private String title;
        private String cover;
        private Integer lessonNum;
        private String subjectLevelOne;
        private String subjectLevelTwo;
        private String teacherName;
        private String price;//只用于显示
    }

      controller:

       //根据课程ID回显最终发布的课程信息
        @GetMapping("getPublishCourseInfo/{courseId}")
        public R updateCourseInfo(@PathVariable String courseId){
            //调用service完成课程修改
            //修改课程数据
            CoursePublishVo publishCourse = eduCourseService.getPublishCourse(courseId);
    
            return R.ok().data("publishCourse",publishCourse);
        }

      service:

        @Override
        public CoursePublishVo getPublishCourse(String courseId) {
    
            //查询课程信息
            CoursePublishVo publishCourse = baseMapper.getPublishCourse(courseId);
    
            return publishCourse;
        }

      测试的话,其实还是会报错的,这个错误早在很久以前就遇见过了,异常如下:

    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.aib.eduservice.mapper.EduCourseMapper.getPublishCourse

      这个异常的直接原因是maven的加载机制导致的,maven项目会把src/main/java的java文件进行编译并放到类路径下,但是mapper.xml文件并不会被加载;所以改变原因就是mapper.xml没有被加载到类路径下或没有和mapper在同一文件夹下。

      解决的办法有很多,有3个:

        1.将maper.xml直接手动复制到类路径下(不推荐)

        2.将mapper.xml放到resource下,这样的maven就能把resouce下的配置加载到类路径下,但是得保证包结构是一致的。(不推荐)

        3.通过pom.xml和application.properties配置的方式完成。(推荐)

      我采用第3种,配置如下:

      由于考虑到其他模块也要使用到pom.xml的配置,就放到service的pom.xml下:配置的目的是让Maven能加载xml文件

        <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>  //两个**是代表多层目录,一个*代表一级目录
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
        </build>

      application.properties:

    #配置mapper xml文件的路径
    mybatis-plus.mapper-locations=classpath:cn/aib/eduservice/mapper/xml/*.xml   //指明mapper配置文件的位置,用于读取
  • 相关阅读:
    Vue无缝滚动
    vue+Axios 实现路由拦截和登录拦截
    添加删除数组元素的方法
    日期时间相关
    Vue源码编译过程
    new关键字执行过程
    预解析
    echarts图表数据为空的时候不显示气泡
    arguments使用
    log4net介绍很全面
  • 原文地址:https://www.cnblogs.com/ibcdwx/p/14188095.html
Copyright © 2011-2022 走看看