谷粒学院_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配置文件的位置,用于读取

 

posted @ 2020-12-25 17:45  爱编程DE文兄  阅读(264)  评论(0编辑  收藏  举报