课程管理-course_list我的课程接口

我的课程

需求分析

课程添加完成后可通过我的课程进入课程修改页面,此页面显示我的课程列表,如下图所示,可分页查询。

上边的查询要实现分页、会存在多表关联查询,所以建议使用mybatis实现我的课程查询。

API接口

输入参数:

页码、每页显示个数、查询条件

输出结果类型:

QueryResponseResult<自定义类型>

在api工程创建course包,创建CourseControllerApi接口。

//查询课程列表 
@ApiOperation("查询我的课程列表") 
public QueryResponseResult<CourseInfo> findCourseList( 
    int page, 
    int size, 
    CourseListRequest courseListRequest 
 );

课程管理服务

PageHelper

PageHelper是mybatis的通用分页插件,通过mybatis的拦截器实现分页功能,拦截sql查询请求,添加分页语句,

最终实现分页查询功能。

我的课程具有分页功能,本项目使用Pagehelper实现Mybatis分页功能开发,由于本项目使用springboot开发,在

springboot上集成pagehelper(https://github.com/pagehelper/pagehelper-spring-boot)

PageHelper的使用方法及原理如下:

在调用dao的service方法中设置分页参数:PageHelper.startPage(page, size),分页参数会设置在ThreadLocal中

PageHelper在mybatis执行sql前进行拦截,从ThreadLocal取出分页参数,修改当前执行的sql语句,添加分页

sql。

最后执行添加了分页sql的sql语句,实现分页查询。

1)添加依赖

<dependency> 
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId> 
    <version>1.2.4</version> 
</dependency>

2)配置pageHelper

在application.yml中配置pageHelper操作的数据库类型:

pagehelper: 
	helper-dialect: mysql

Dao

1)mapper 接口

CourseListRequest加上这个是为了后面如果有条件查询更方便

package com.xuecheng.manage_course.dao;

import com.github.pagehelper.Page;
import com.xuecheng.framework.domain.course.CourseBase;
import com.xuecheng.framework.domain.course.ext.CourseInfo;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;

/**
 * Created by Administrator.
 */
@Mapper
@Component
public interface CourseMapper {
   CourseBase findCourseBaseById(String id);
   Page<CourseInfo> findCourseListPage(CourseListRequest courseListRequest);
}

将courseBase加上图片属性二次封装,后期要根据课程信息关联查询课程图片

package com.xuecheng.framework.domain.course.ext;

import com.xuecheng.framework.domain.course.CourseBase;
import lombok.Data;
import lombok.ToString;

/**
 * Created by admin on 2018/2/10.
 */
@Data
@ToString
public class CourseInfo extends CourseBase {

    //课程图片
    private String pic;
}

2)mapper.xml映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xuecheng.manage_course.dao.CourseMapper">
    <select id="findCourseBaseById" parameterType="java.lang.String"
            resultType="com.xuecheng.framework.domain.course.CourseBase">
        select * from course_base where id = #{id}
    </select>
    <!--关联查询图片表,获取图片信息,后期实现FastDFS后可直接从图片服务器获取 -->
    <select id="findCourseListPage" parameterType="com.xuecheng.framework.domain.course.request.CourseListRequest"
    resultType="com.xuecheng.framework.domain.course.ext.CourseInfo">
        select course_base.*,
         (select pic from course_pic where courseid=course_base.id) pic
         from course_base
    </select>
</mapper>

3)测试Dao

//测试分页
@Test
public void testPageHelper(){ 
    PageHelper.startPage(2, 1); 
    CourseListRequest courseListRequest = new CourseListRequest(); 
    Page<CourseInfo> courseListPage = courseMapper.findCourseListPage(courseListRequest); 		         List<CourseInfo> result = courseListPage.getResult(); 
    System.out.println(courseListPage); 
}

测试前修改日志级别为debug,并跟踪运行日志,发现sql语句中已经包括分页语句

Service

定义CourseService.java类,用于课程管理的service定义:

/**
     * 分页查询课程列表
     * @param page
     * @param size
     * @param courseListRequest
     * @return
     */
    public QueryResponseResult<CourseInfo> findCourseList(int page, int size, CourseListRequest courseListRequest) {
        //保证传过来的对象不为空
        if (courseListRequest == null) {
            courseListRequest = new CourseListRequest();
        }
        //分页参数
        if (page<=0){
            page = 1;
        }
        if (size <= 0) {
            size = 10;
        }
        PageHelper.startPage(page, size);
        Page<CourseInfo> listPage = courseMapper.findCourseListPage(courseListRequest);
        if (listPage==null) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        List<CourseInfo> result = listPage.getResult();
        QueryResult queryResult = new QueryResult();
        queryResult.setList(result);
        queryResult.setTotal(listPage.getTotal());
        System.out.println(listPage.getTotal());
        return new QueryResponseResult<CourseInfo>(CommonCode.SUCCESS,queryResult);
    }

Controller

@RestController 
@RequestMapping("/course") 
public class CourseController implements CourseControllerApi {
    @Autowired 
    CourseService courseService; 
    @Override 
    @GetMapping("/coursebase/list/{page}/{size}") 
    public QueryResponseResult<CourseInfo> findCourseList( 
        @PathVariable("page") int page, 
        @PathVariable("size") int size, 
        CourseListRequest courseListRequest) { 
        return courseService.findCourseList(page,size,courseListRequest); 
    } 
}

前端

页面

创建course_list.vue

1)使用element 的card组件

页面布局代码如下:

<template>
  <section>
    <el-row >
      <el-col :span="8"  :offset=2 >
        <el-card :body-style="{ padding: '10px' }">
          <img src="/static/images/add.jpg" class="image" height="150px">
          <div style="padding: 10px;">
            <span>课程名称</span>
            <div class="bottom clearfix">
              <time class="time"></time>
              <router-link class="mui-tab-item" :to="{path:'/course/add/base'}">
                  <el-button type="text" class="button" >新增课程</el-button>
              </router-link>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="8" v-for="(course, index) in courses" :key="course.id" :offset="index > 0 ? 2 : 2">
        <el-card :body-style="{ padding: '10px' }">
          <img :src="course.pic!=null?imgUrl+course.pic:'/static/images/nonepic.jpg'" class="image" height="150px">
          <div style="padding: 10px;">
            <span>{{course.name}}</span>
            <div class="bottom clearfix">
              <time class="time"></time>
              <el-button type="text" class="button" @click="handleManage(course.id)">管理课程</el-button>
            </div>
          </div>
        </el-card>
      </el-col>

      <!--分页-->
      <el-col :span="24" class="toolbar">
        <el-pagination background layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="size"
                       :total="total" :current-page="page"
                       style="float:right;">
        </el-pagination>
      </el-col>
    </el-row>
  </section>
</template>
<script>
  import * as courseApi from '../api/course';
  import utilApi from '../../../common/utils';
  let sysConfig = require('@/../config/sysConfig')
  export default {
    data() {
      return {
        page:1,
        size:5,
        total: 0,
        courses: [
          {
            id:'test01',
            name:'test01',
            pic:''
          },
          {
            id:'test02',
            name:'test02',
            pic:''
          }
          ],
        sels: [],//列表选中列
        imgUrl:sysConfig.imgUrl
      }
    },
    methods: {
        //分页方法
      handleCurrentChange(val) {
        this.page = val;
        this.getCourse();
      },
      //获取课程列表
      getCourse() {
        courseApi.findCourseList(this.page,this.size,{}).then((res) => {
          console.log(res);
          if(res.success){
            this.total = res.queryResult.total;
            this.courses = res.queryResult.list;
          }

        });
      },
      handleManage: function (id) {
        console.log(id)
        this.$router.push({ path: '/course/manager/'+id})
      }

    },
    created(){

    },
    mounted() {
      //查询我的课程
      this.getCourse();
    }
  }
</script>
<style scoped>
  .el-col-8{
    width:20%
  }
  .el-col-offset-2{
    margin-left:2%
  }
  .time {
    font-size: 13px;
    color: #999;
  }

  .bottom {
    margin-top: 13px;
    line-height: 12px;
  }

  .button {
    padding: 0;
    float: right;
  }

  .image {
    width: 100%;
    display: block;
  }

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }

  .clearfix:after {
    clear: both
  }
</style>

6)路由

import course_list from '@/module/course/page/course_list.vue'; 
import Home from '@/module/home/page/home.vue'; 
export default [ 
    {
        path: '/course', 
        component: Home, 
        name: '课程管理', 
        hidden: false, 
        iconCls: 'el‐icon‐document', 
        children: [ 
            { path: '/course/list', name: '我的课程',component: course_list,hidden: false } 
        ] 
    } 
]

Api调用

1、定义Api方法

//我的课程列表 
export const findCourseList = (page,size,params) => { 
    //对于查询条件,向服务端传入key/value串。 
    //使用工具类将json对象转成key/value 
    let queries = querystring.stringify(params) 
    return http.requestQuickGet(apiUrl+"/course/coursebase/list/"+page+"/"+size+"?"+queries); 
}

2、在页面调用fifindCourseList方法:

//获取课程列表 
getCourse() { 
    courseApi.findCourseList(this.page,this.size,{}).then((res) => { 
        console.log(res); 
        if(res.success){ 
            this.total = res.queryResult.total; 
            this.courses = res.queryResult.list; 
        } 
    }); 
}

在mounted钩子中调用getCourse方法

mounted() { 
    //查询我的课程 
    this.getCourse(); 
}

在分页方法中调用getCourse方法

//分页方法 
handleCurrentChange(val) { 
    this.page = val; 
    this.getCourse(); 
},

测试

页面效果如下:

注意:由于课程图片服务器没有搭建,这里图片暂时无法显示。

HuangRui

Every man dies, not every man really lives.

HaungRui, China suixinblog.cn