在线学习平台-班级模块
在线学习平台------手把手教程👈
通过分析可知,班级模块的结构会比较简单,可以先从班级模块入手
1.先在domain里写上班级里的属性
? ? ? ? 快捷方式:
时区可以这里找,时区和数据库名之间要加一个 '?'
右键需要的数据库模型,便可直接生成
生成的实体类不需要get、set方法,可以全部删掉,然后在类上面加上注解@data
数据类型要改成包装类
再配置好MyBatisPlus的一套流程:
? ? ? ?第一步:
????????先在mapper新建一个接口:____Mapper,继承BaseMapper<里面放上对应的实体类模型>
? ? ? ?第二步:
????????在service层建一个接口:I___Service,继承IService<里面放上对应的实体类模型>
? ? ? ?第三步
????????在service层下面建一个实现类的包:Impl
? ? ? ? ? ? ? ? 在impl包下建一个实现I___Service的类 ___ServiceImpl,继承ServiceImpl<mapper,class>
? ? ? ? ? ? ? ? 控制层需要调用这个地方,要用@service注入.
到此为止,就可以在控制层实现对类 基本的增删改查功能
将登入接口写入swagger
将验证码接口写入swagger
关于数据的返回类型:
????????
????????com.ruoyi.common.core.domain.R;
????????com.ruoyi.common.core.page.TableDateinfo; (分页)
可以借用上面两个封装好的实体类返回
????????????????
班级分析
班级除了一些常规字段,还需要备注、名称、班级id、同时还需要支持分页查询
代码编写
在控制层注入Service的内容
@Autowired
private IMsClassService msClassService;
想要实现分类操作,可以用msClassService里的page方法,
page方法需要传入page对象,
page对象需要传入分页信息(pageNum,pageSize)
最后会返回一个分页对象Page<实体类名称>
将分页参数封装成实体类
返回值类的选择
BaseController里面封装了一个TableDateinfo类型的方法getDateTable,需要传入一个list集合
但如果使用swagger,这个方法会用不了(swagger无法识别带有问好的参数)
此时启动会出现mapper层找不到的情况
因为这是我们自己写的增强模块,命名没有符号若依设定好的规则,需要自己配置扫描路径
配置扫描
通过全局搜索,寻找com.ruo.*
加上自己的模块,才能扫描出来
启动后,因为rows里面的参数是?,swagger识别不出来,需要外面自己写一个类来返回
返回值类
在自己的模块建一个core包(放一些通用的包),里面再建一个TableDate(用于返回分类数据的实体类)
里面的rows<T>要用泛型来传,swagger才能接收到,里面再生成它的构造器,和一些通用的方法
package com.mashang.elearing.core;
/*
统一返回实体类
*/
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel("分页数据")
@Data
public class TableData<T> {
@ApiModelProperty("状态码")
private Integer code;
@ApiModelProperty("提示消息")
private String msg;
@ApiModelProperty("数据")
private List<T> rows;
@ApiModelProperty("总数量")
private Long total;
public TableData(Integer code, String msg, List<T> rows, Long total) {
this.code = code;
this.msg = msg;
this.rows = rows;
this.total = total;
}
public static TableData success(List list, Long total){
return new TableData(200,"操作成功",list,total);
}
}
版本问题
这个时候可能会出现sql语法问题,这种情况是plus的版本有问题
可以在common模块更改成3.5.1
实现班级模糊查询
在page方法里,除了可以传pageNum,和pageSize还可以传条件构造器 lamdaQueryWrapper
qw.like()方法,要支持不传入班级名称时不执行该方法,调用
LambdaQueryWrapper<MsClass> qw = new LambdaQueryWrapper();
//模糊查询,没传参数的时候不执行
qw.like(StringUtils.isNotEmpty(className),MsClass::getClassName,className);
来判断
配置日志:
在用swagger调试时,没有日志信息,不方便排查错误
可以在ruoyi-admin/logback.xml,加上我们自己的模块
mapstruct转化
此时查询出来的数据,并不是所有的数据(如updatetime之类的)都需要返回给前端,需要借助mapstruct依赖进行转化
mapstruct有个缺点,经常需要清缓存才能正常使用
在自己的模块移入依赖mapstruct
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
提取需要的字段
需求里只需要classId、className和remake,此时可以在domain下面搞一个Vo包来映射
package com.mashang.elearing.domain.vo; 在这个位置建MsClassPageVo
package com.mashang.elearing.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("班级分页模型")
public class MsClassPageVo {
@ApiModelProperty("班级主键")
private Long classId;
@ApiModelProperty("班级名称")
private String className;
@ApiModelProperty("备注")
private String remark;
}
具体操作
分页对象和条件构造器查询出来的都是msclass,需要在最后转成MsclassPageVo来返回
建一个mapping包,包下面放接口,命名为MsClassMapper
查询接口的最终代码
@ApiOperation("分页查询")
@GetMapping("/list")
public TableData<MsClassPageVo> test(String className, Pager pager){
//条件构造器,这里的实体类是MsClass,不是MsClassPageVo
LambdaQueryWrapper<MsClass> qw = new LambdaQueryWrapper();
//模糊查询,没传参数的时候不执行
qw.like(StringUtils.isNotEmpty(className),MsClass::getClassName,className);
qw.ne(MsClass::getDelFlag,"2");//假删后的内容不需要查出来
//按降序来显示,最近添加的放在最上面
qw.orderByDesc(MsClass::getCreateTime);
//page对象,这里的实体类是MsClass,不是MsClassPageVo
Page<MsClass> page = msClassService.page(
new Page<>(pager.getPageNum(),pager.getPageSize()),qw);
//这个时候再把MsClass转成MsClassPageVo
List<MsClassPageVo> vos = MsClassMapping.INSTANCE.to(page.getRecords());
return TableData.success(vos,page.getTotal());
}
查询接口样例
添加接口
? ? ? ? 所需参数
? ? ? ? 添加时,只需要传classId、className和remake就行,其他不用。
????????如果直接用实体类MsClass传,前端会得到很多数据,可能会误导前端。
????????跟前面的查询一样,在domain单独搞一个包params,里面放前端需要的 实体类传入,然后再转成MsClass。剩下那些创建者、创建时间之类的字段可以后端统一自动填充
package com.mashang.elearing.domain.params.clazz;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@ApiModel("添加模型")
@Data
public class MsClassCreate {
@ApiModelProperty(value = "班级名称",required = true)
@NotBlank(message = "班级名称不能为空")
private String className;
@ApiModelProperty("备注")
private String remark;
}
? ? ? ? 在mapping里面转
MsClass to(MsClassCreate create);
? ? ? ?统一返回实体类
????????添加的返回值是boolean,为了适配,也能够返回一些信息,可以自己在core那里搞一个返回的实体类
package com.mashang.elearing.core;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ApiModel("操作响应对象")
@Data
public class Result<T> {
private Integer code;
private String msg;
private T data;
public Result(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static Result success(Object data){
return new Result(200,"操作成功",data);
}
public static Result success(){
return new Result(200,"操作成功",null);
}
public static Result error(){
return new Result(500,"操作失败",null);
}
public static Result error(String msg){
return new Result(500,msg,null);
}
public static Result to(boolean rs){
return rs ? success() : error();
}
public static Result to(int rs){
return rs > 0? success() : error();
}
}
操作完后只需要知道成功与失败,不需要返回具体信息
? ? ? ? 自动填充类
????????创建一个handle包,里面创建FiledHanlder(用来自动填充不需要传的字段)
????????createBy和updateBy是用户的账号
package com.mashang.elearing.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class FieldHandler implements MetaObjectHandler {
/**
* 插入时的填充策略
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("createBy", SecurityUtils.getUsername(),metaObject);
this.setFieldValByName("updateBy", SecurityUtils.getUsername(),metaObject);
}
/**
* 更新时的填充策略
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateBy", SecurityUtils.getUsername(),metaObject);
}
}
然后在实体类上加上注解,以后这些字段有需要的话就自动填充
? ? ? ? 在MsClass添加自动填充
注意这里:添加Id会自动生成一个随机的整数,会爆int,所以要把id设置成自动递增type = IDType.AUTO
package com.mashang.elearing.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.Date;
@Data
public class MsClass {
@TableId(type = IdType.AUTO)
private Long classId;
private String className;
private String delFlag;
@TableField(fill = FieldFill.INSERT)
private String createBy;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
private String remark;
}
一些小规范
? ? ? ? 导入swagger参数验证的依赖@Validated,防止一些空值传入
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.3.Final</version>
<scope>compile</scope>
</dependency>
@Notblank:不能为空也不能为空字符串
??添加接口的最终代码
@ApiOperation("添加")
@PostMapping
// @RequestBody以json的格式传
public Result create(@RequestBody @Validated MsClassCreate create){
MsClass msClass = MsClassMapping.INSTANCE.to(create);
// msClass.setCreateTime(new Date());
// msClass.setCreateBy(getUsername()); //有自动填充就不需要自习设置
return Result.to(msClassService.save(msClass));
}
修改接口
参照添加接口,更改参数,在mapping里转化。updateById传入的MsClass对象,但是msclass里的内容不是都需要给前端的,所以需要转化将MsClassDtlVo转成MsClass
????????第一步:
? ? ? ? 在domain的params包下创建需要的实体类MsClassDtlVo
package com.mashang.elearing.domain.params.clazz;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ApiModel("班级修改模型")
@Data
public class MsClassUpdate {
@NotNull(message = "班级id不能为空")
private Long classId;
@ApiModelProperty(value = "班级名称",required = true)
@NotBlank(message = "班级名称不能为空")
private String className;
@ApiModelProperty("备注")
private String remark;
}
? ? ? ? 修改,classId和班级名称都是必传,要用@Validated验证
????????第二步:
? ? ? ? 跟之前一样,需要在mapping里面转
? ? ? ? 修改接口需要的是MsClass,将传入的MsClassUpdate转成MsClass
MsClass to(MsClassUpdate update);
? ? ? ? 最后代码
@ApiOperation("修改")
@PutMapping
//@RequestBody以json的格式传
public Result update(@RequestBody @Validated MsClassUpdate update){
MsClass msClass = MsClassMapping.INSTANCE.to(update);
return Result.to(msClassService.updateById(msClass));
}
? ?要再写查询接口,每次点击修改,要把之前的信息查出来
查询详情接口
package com.mashang.elearing.domain.vo;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("班级详情模型")
@Data
public class MsClassDtlVo {
@ApiModelProperty("班级主键")
private Long classId;
@ApiModelProperty("班级名称")
private String className;
@ApiModelProperty("备注")
private String remark;
}
? ?第一步
? 查询出来的是MsClass对象,然后把再把它转成MsClassDtlVo
? ?第二步
? ?在domain的Vo创建MsClassDtlVo
package com.mashang.elearing.domain.vo;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("班级详情模型")
@Data
public class MsClassDtlVo {
@ApiModelProperty("班级主键")
private Long classId;
@ApiModelProperty("班级名称")
private String className;
@ApiModelProperty("备注")
private String remark;
}
? ? ? ? 第三步
? ? ? ?在mapping里的MsClassMapping加上下面这段代码
MsClassDtlVo to(MsClass msClass);
? ? ? ?TableId
????????ById结尾的方法默认用Id属性,如果命名不是id的话,需要去实体类配置
查询详情接口代码
@ApiOperation("查询详情")
@GetMapping("/{id}")
//@RequestBody以json的格式传
//@PathVariable 把参数放在路径上
public Result<MsClassDtlVo> getById(@PathVariable Long id){
//getById 查出来的是Msclass对象,其中不是所有数据都需要返回,可以转成前端需要展现的内容
//getById返回值是MsClass类型,需要转成MsClassDtlVo
MsClassDtlVo dtlVo = MsClassMapping.INSTANCE.to(msClassService.getById(id));
return Result.success(dtlVo);
}
删除接口
? ? ? ? 删除接口用的是假删,不是调用removeById,而是用updateById,传入MsClass对象
? ? ? ? 把MsClass对象的DelFlag 设置成2
? ? ? ? 只需要返回成功与失败,不需要返回删除了什么内容
@ApiOperation("删除")
@DeleteMapping("/{id}")
public Result delete(@PathVariable Long id){
MsClass msClass = new MsClass();
msClass.setClassId(id);
msClass.setDelFlag("2");
return Result.to(msClassService.updateById(msClass));
}
查询所有班级接口
? ? ? ? 最终代码
@ApiOperation("查询所有班级")
@GetMapping("/all")
//班级id是用来支持搜索的
public Result<MsClassAllVo> test(String className){
LambdaQueryWrapper<MsClass> qw = new LambdaQueryWrapper();
qw.like(StringUtils.isNotEmpty(className),MsClass::getClassName,className);
qw.ne(MsClass::getDelFlag,"2");//只查询delflag!=2
List<MsClassAllVo> vos = MsClassMapping.INSTANCE.toAllVo(msClassService.list(qw));
return Result.success(vos);
}
实体类Vo转化
只需要返回班级id和名称就行
package com.mashang.elearing.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("查询所有班级模型")
@Data
public class MsClassAllVo {
@ApiModelProperty("班级主键")
private Long classId;
@ApiModelProperty("班级名称")
private String className;
}
List<MsClassAllVo> toAllVo(List<MsClass> msClasses);
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!