Mooc项目的课程分类采用二级分类,也就是分为两级,例如:
在数据库中的存储结构主要包含三个字段
另外,课程分类的信息不再采用表单的形式,而是通过导入excle添加。
1、数据导入:减轻录入工作量
2、数据导出:统计信息归档
3、数据传输:异构系统之间数据传输
在service_edu的pom下引入下面的依赖
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>2.1.1version>
dependency>
dependencies>
注意还需要引入poi的依赖,而且版本要和easyexcel对应(service模块已经引入过了,所以不需要放入service_edu中)
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
dependency>
设置表头和添加的数据字段
在service_edu的test目录下创建cn/hanzhuang42/excel/DemoData.java
实体类
package cn.hanzhuang42.excel;
import lombok.Data;
@Data
public class DemoData {
//设置表头名称,和它对应的列
@ExcelProperty(value = "学生编号", index = 0)
private Integer sno;
@ExcelProperty(value = "学生姓名", index = 1)
private String sname;
}
在test中进行测试:
public class TestEasyExcel {
//实现写入excle
@Test
public void writeTest(){
//设置写入文件夹地址和文件名称
String filename = "C:\\Users\\ada\\Desktop\\writeTest.xlsx";
//调用方法实现写操作
//第一个参数是文件路径名,第二个参数是实体类的class
EasyExcel.write(filename, DemoData.class).sheet("学生列表").doWrite(getData());
}
private static List<DemoData> getData() {
List<DemoData> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
DemoData d = new DemoData();
d.setSno(i);
d.setSname("Eva" + i);
list.add(d);
}
return list;
}
}
结果:
1)创建对excel表中数据对应的实体类。这里仍然使用上面的DemoData
2)创建读取操作的监听器
public class ExcelListener extends AnalysisEventListener<DemoData> {
/**
* 一行一行的读出excel中的数据
* @param demoData 每行的数据
* @param analysisContext
*/
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("------"+demoData);
}
/**
* 读取表头的内容
* @param headMap
* @param context
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("表头:" + headMap);
}
/**
* 读取完成后会调用
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
3、调用实现最终的读取
//实现excel的读操作
@Test
public void readTest(){
//设置读取文件夹地址和文件名称
String filename = "C:\\Users\\ada\\Desktop\\writeTest.xlsx";
//调用方法实现读操作
EasyExcel.read(filename, DemoData.class, new ExcelListener()).sheet().doRead();
}
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>2.1.1version>
dependency>
dependencies>
上边过程中已经引入
使用Mybatis-plus的代码生成器生成代码mapper,service,controller
参见开发笔记二
创建完成之后有几个地方需要修改:
1)创建和修改时间上加上@TableField注解,用于自动填充时间
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduSubject对象", description="课程科目")
public class EduSubject implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程类别ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "类别名称")
private String title;
@ApiModelProperty(value = "父ID")
private String parentId;
@ApiModelProperty(value = "排序字段")
private Integer sort;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
2)、Controller上加上@CrossOrigin用于允许跨域访问
@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
public class EduSubjectController {
..
}
创建包cn.hanzhuang42.eduservice.entity.excel
,并在下面创建与excel数据对应的实体类:
package cn.hanzhuang42.eduservice.entity.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class SubjectData {
//设置表头名称,和它对应的列
@ExcelProperty( index = 0)
private String topSubjectName;
@ExcelProperty(index = 1)
private String subSubjectName;
}
package cn.hanzhuang42.eduservice.listener;
import cn.hanzhuang42.eduservice.entity.EduSubject;
import cn.hanzhuang42.eduservice.entity.excel.SubjectData;
import cn.hanzhuang42.eduservice.service.EduSubjectService;
import cn.hanzhuang42.servicebase.exception.CustomException;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
//监听器没有交给spring管理,所以不能自动注入
private EduSubjectService subjectService;
public SubjectExcelListener() {
}
public SubjectExcelListener(EduSubjectService subjectService) {
this.subjectService = subjectService;
}
/**
* 读取每行数据并存入数据库
*
* @param subjectData
* @param analysisContext
*/
@Override
public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
if (subjectData == null) {
throw new CustomException(20001, "文件内容为空");
}
//这一行中的一级分类和二级分类的名称
String topSubjectName = subjectData.getTopSubjectName();
String subSubjectName = subjectData.getSubSubjectName();
//判读该行的一级分类是否存在,不存在则插入
EduSubject topSubject = existTopSubject(topSubjectName);
if (topSubject == null) { //表中没有相同的一级分类,需要插入
topSubject = new EduSubject();
topSubject.setTitle(topSubjectName);
topSubject.setParentId("0");
subjectService.save(topSubject);
}
//插入数据之后mp会自动将id放入topSubject中
String parent_id = topSubject.getId();
//判读该行的一级分类是否存在,不存在则插入
EduSubject subSubject = existSubSubject(subSubjectName, parent_id);
if (subSubject == null) { //表中没有相同的一级分类,需要插入
subSubject = new EduSubject();
subSubject.setTitle(subSubjectName);
subSubject.setParentId(parent_id);
subjectService.save(subSubject);
}
}
//判断一级分类是否存在
private EduSubject existTopSubject(String name) {
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title", name)
.eq("parent_id", 0);
EduSubject subject = subjectService.getOne(wrapper);
return subject;
}
//判断二级分类是否存在
private EduSubject existSubSubject(String name, String parent_id) {
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title", name)
.eq("parent_id", parent_id);
EduSubject subject = subjectService.getOne(wrapper);
return subject;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
修改service接口
package cn.hanzhuang42.eduservice.service;
import cn.hanzhuang42.eduservice.entity.EduSubject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;
/**
*
* 课程科目 服务类
*
*
* @author Miracle42
* @since 2020-06-25
*/
public interface EduSubjectService extends IService<EduSubject> {
void saveSubject(MultipartFile file, EduSubjectService subjectService);
}
修改sevice实现类
package cn.hanzhuang42.eduservice.service.impl;
import cn.hanzhuang42.eduservice.entity.EduSubject;
import cn.hanzhuang42.eduservice.entity.excel.SubjectData;
import cn.hanzhuang42.eduservice.listener.SubjectExcelListener;
import cn.hanzhuang42.eduservice.mapper.EduSubjectMapper;
import cn.hanzhuang42.eduservice.service.EduSubjectService;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
/**
*
* 课程科目 服务实现类
*
*
* @author Miracle42
* @since 2020-06-25
*/
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
/**
* 添加课程分类
* @param file
* @param subjectService
*/
@Override
public void saveSubject(MultipartFile file, EduSubjectService subjectService) {
try {
InputStream inputStream = file.getInputStream();
EasyExcel.read(inputStream, SubjectData.class, new SubjectExcelListener(subjectService)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package cn.hanzhuang42.eduservice.controller;
import cn.hanzhuang42.commonutils.R;
import cn.hanzhuang42.eduservice.service.EduSubjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
*
* 课程科目 前端控制器
*
*
* @author Miracle42
* @since 2020-06-25
*/
@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
public class EduSubjectController {
@Autowired
private EduSubjectService subjectService;
/**
* 添加课程分类
* 通过前端上传文件到服务器,
* 然后通过easyexcel读取并存入数据库
*/
@PostMapping("addSubject")
public R addSubject(MultipartFile file){
subjectService.saveSubject(file, subjectService);
return R.ok();
}
}
打开swagger进行测试:
上传文件,点击执行