springboot班级学生demo后端代码

本教程详细介绍了使用Spring Boot集成Mybatis-Plus实现学生和班级管理功能,包括实体类、配置、Service、Controller的编写,并利用Swagger生成API文档。此外,还展示了如何处理数据填充、分页查询和逻辑删除。
摘要由CSDN通过智能技术生成

在之前的层次分析开始编写代码
层次分析
然后由于每个人编写代码风格不同,可以根据自己情况而定,一般分2种,代码编写顺序:从实体类到controller或者从controller到实体类。
本次Demo是采用实体类到controller编写。

实体类

先写与数控库字段一一对应的实体类
base包下的基类

@Data
@ApiModel("公有字段")
public class BaseEntity {

    @ApiModelProperty(value = "")
    @TableId(value = "id" ,type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "创建时间")
    @TableField(value = "createTime" ,fill = FieldFill.INSERT)
    private Date createTime;

    @ApiModelProperty(value = "修改时间")
    @TableField(value = "changeTime" ,fill = FieldFill.INSERT_UPDATE)
    private Date changeTime;

    @TableField(value = "logicDelete",fill = FieldFill.INSERT)
    @TableLogic(value = "0",delval ="1")
    private Integer logicDelete;
}

entity包下自己与数据库相连的实体

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "student_db")
@ApiModel("学生实体")
public class Student extends BaseEntity {

    @ApiModelProperty(value = "班级名称")
    @TableField(value = "className")
    private String className;

    @ApiModelProperty(value = "学生姓名")
    @TableField(value = "studentName")
    private String studentName;

    @ApiModelProperty(value = "学生性别")
    @TableField(value = "studentSex")
    private String studentSex;

    @ApiModelProperty(value = "学生年龄")
    @TableField(value = "studentAge")
    private Integer studentAge;

    @ApiModelProperty(value = "加入班级时间")
    @TableField(value = "addClassTime")
    private Date addClassTime;
}
@ApiModel("班级实体")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "class_db")
public class StudentClass extends BaseEntity {

    @ApiModelProperty("班级名称")
    @TableField(value = "className")
    private String className;

}

然后再写前后端相互需要的数据内容实体,这个可以根据后面接口需要的参数或者返回值进行修改就行。
DTO:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("班级DTO")
public class StudentClassDTO {

    @ApiModelProperty("班级名称")
    private String className;

}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("学生DTO")
public class StudentDTO {

    @ApiModelProperty(value = "学生姓名")
    private String studentName;

    @ApiModelProperty(value = "学生性别")
    private String studentSex;

    @ApiModelProperty(value = "学生年龄")
    private Integer studentAge;

    @ApiModelProperty(value = "班级名称")
    private String className;
}

VO:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("班级VO")
public class StudentClassVO {

    @ApiModelProperty("班级名称")
    private String className;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("学生VO")
public class StudentVO {

    @ApiModelProperty(value = "学生姓名")
    private String studentName;

    @ApiModelProperty(value = "学生性别")
    private String studentSex;

    @ApiModelProperty(value = "学生年龄")
    private Integer studentAge;

    @ApiModelProperty(value = "班级名称")
    private String className;

    @ApiModelProperty(value = "加入班级时间")
    private Date addClassTime;
}

这样需要的实体类都建立完毕。

编写其他的基础配置代码

config包下面的Mybatis-plus分页基础配置和Swagger基础配置

@Configuration
@MapperScan("com.example.demo.mapper")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
/**
 * Swagger使用例子
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    /**
     * 配置Swagger功能配置
     * @return Docket
     */
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(true)
                .groupName("学生班级接口文档")
                .select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller"))
                // 配置如何通过path过滤,即这里只扫描请求以/student开头的接口
//                .paths(PathSelectors.ant("/student/**"))
                .build();
    }

    /**
     * 配置文档信息
     * Contact参数:name,url,email
     * ApiInfo参数:标题,描述,版本,组织链接,联系人信息,许可,许可连接,扩展
     * @return ApiInfo
     */
    private ApiInfo apiInfo() {
        Contact contact = new Contact("联系人名字", "http://xxx.xxx.com/联系人访问链接", "联系人邮箱");
        return new ApiInfo(
                "考核Demo",
                "班级学生基础功能实习",
                "v1.0",
                "http://terms.service.url/组织链接",
                contact,
                "Apach 2.0 许可",
                "许可链接",
                new ArrayList<>()
        );
    }
}

handler包下的自动给数据库字段内容填充的配置

@Component
public class StudentHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {

        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "changeTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "logicDelete", Integer.class, 0);

    }

    @Override
    public void updateFill(MetaObject metaObject) {

        this.strictInsertFill(metaObject, "changeTime", Date.class, new Date());

    }
}

application.properties配置文件:

#应用名称
spring.application.name=test

#数 据 源 配 置
spring.datasource.url=jdbc:mysql://localhost:3306/school_db?characterEncoding=UTF-8&serverTimezone=CTT
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#应用服务 WEB 访问端口
server.port=8080

#相关映射
mybatis-plus.mapper-locations=classpath:mappers/*xml
mybatis-plus.type-aliases-package=com.example.test.mybatis.entity

#驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true

#统一字节编码
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8

mybatis-plus.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl

mapper(dao)、mappers的相互映射代码

由StudentClassMappers.xml映射到StudentClassMapper接口

<?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.example.demo.mapper.StudentClassMapper">
    <select id="studentClassPage" resultType="com.example.demo.entity.StudentClass">
        SELECT * FROM class_db
    </select>
</mapper>
@Mapper
@Component
public interface StudentClassMapper extends BaseMapper<StudentClass> {

    IPage<StudentClass> studentClassPage(Page<StudentClass> page);
    
}

由StudentMappers.xml映射到StudentMapper接口

<?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.example.demo.mapper.StudentMapper">
    <select id="studentPage" resultType="com.example.demo.entity.vo.StudentVO">
        SELECT * FROM student_db
    </select>

    <update id="emptyTime" parameterType="com.example.demo.entity.Student" >
        update student_db set addClassTime = null , className = null where id = #{id}
    </update>

</mapper>
@Mapper
@Component
public interface StudentMapper extends BaseMapper<Student> {

    IPage<StudentVO> studentPage(Page<Student> page);
    void emptyTime (long id );

}

由于我是拿成品代码所以里面有自己直接编写的sql语句的方法。就是简单的Mybatis-plus无法满足业务需求而自己编写的方法。
而接下来可以编写Service或者Controller。

demo-service业务层编写

一般而言,我都是直接先创建与实体相对应的service和impl,注意这里是实体都是与数据有直接链接的实体,就是上面的Student实体和StudentClass实体。
然后再根据接口的需求写方法在这里面。
大致的整体流程图:
在这里插入图片描述
3层衔接完整,这样就可以避免controller直接与数据层直接交互,而产生不安全。
StudentService和StudentImpl的代码:

@Service
public interface StudentService extends IService<Student> {

    /**
     * 插入新学生数据
     * @param studentDTO
     * @return
     */
    Student transferStudent(StudentDTO studentDTO);

    /**
     * 更新学生信息
     * @param studentDTO 更新信息
     * @param student    要更新的目标
     * @return
     */
    Student studentUpdata(StudentDTO studentDTO, Student student);

    /**
     * 根据id将字段className,addClassTime置为NULL
     * @param id
     */
    void emptyAddClassTime(long id);
}
@Service
public class StudentImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Autowired
    StudentClassService studentClassService;

    @Autowired
    StudentService studentService;

    @Override
    public Student transferStudent(StudentDTO studentDTO){
        Student student = Student.builder()
                .studentName(studentDTO.getStudentName())
                .studentSex(studentDTO.getStudentSex())
                .studentAge(studentDTO.getStudentAge())
                .build();
        if ( studentClassService.classChooseService(studentDTO.getClassName())){
            student.setClassName(studentDTO.getClassName());
            student.setAddClassTime(new Date());
        }else {
            student.setAddClassTime(null);
            student.setClassName(null);
        }
       return student;
    }

    @Override
    public Student studentUpdata(StudentDTO studentDTO ,Student student) {

        if (student.getClassName() != studentDTO.getClassName() &&
                studentClassService.classChooseService(studentDTO.getClassName())){
            student.setClassName(studentDTO.getClassName());
            student.setAddClassTime(new Date());
        } else if (studentDTO.getClassName() != student.getClassName() && studentDTO.getClassName() == ""){
            studentService.emptyAddClassTime(student.getId());
        }
        student.setStudentName(studentDTO.getStudentName());
        student.setStudentSex(studentDTO.getStudentSex());
        student.setStudentAge(studentDTO.getStudentAge());
        student.setChangeTime(null);
        return student;
    }

    @Override
    public void emptyAddClassTime(long id) {
        baseMapper.emptyTime(id);
    }
}

StudentClassService和StudentClassImpl代码:

@Service
public interface StudentClassService extends IService<StudentClass> {

    /**
     * 判断班级是否存在
     * @param className
     * @return
     */
    boolean classChooseService(String className);

    /**
     * 班级加入学生
     * @param classId
     * @param studentId
     * @return
     */
    StudentVO classAddStudent(long classId , long studentId);

    /**
     * 班级删除学生
     * @param id
     * @return
     */
    StudentVO classDeleteStudent(long id);
}
@Service
public class StudentClassImpl extends ServiceImpl<StudentClassMapper, StudentClass> implements StudentClassService {

    @Autowired
    StudentService studentService;

    @Autowired
    StudentClassService studentClassService;

    @Override
    public boolean classChooseService(String className) {

        boolean result = false;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("className",className);
        if ( baseMapper.selectOne(queryWrapper) != null ){
            result = true;
        }
        return result;
    }

    @Override
    public StudentVO classAddStudent(long classId,long studentId) {

        StudentClass studentClass =studentClassService.getBaseMapper().selectById(classId);
        Student student = studentService.getBaseMapper().selectById(studentId);
        String className = student.getClassName();
        student.setChangeTime(null);
        student.setAddClassTime(null);
        if (className == studentClass.getClassName()){
            System.out.println("已经加入过该班级");
        }else {
            student.setChangeTime(new Date());
            student.setAddClassTime(new Date());
            student.setClassName(studentClass.getClassName());
            studentService.getBaseMapper().updateById(student);
        }
        StudentVO studentVO = new StudentVO();
        BeanUtils.copyProperties(student,studentVO);
        return  studentVO;
    }

    @Override
    public StudentVO classDeleteStudent(long id) {

        studentService.emptyAddClassTime(id);
        Student student = studentService.getBaseMapper().selectById(id);
        StudentVO studentVO = new StudentVO();
        BeanUtils.copyProperties(student,studentVO);
        return studentVO;
    }
}

其中涉及到DTO与VO与T之间的相互转换,还有Pag< T >和Pag< VO >之间的转换,方法有很多写原生的转换或者直接借用一些工具包都可以。
本次实例采用的是hutool工具包的方法完成相应转换。
这个具体使用链接:关于转换数据实体的方法

Controller代码

StudentController和StudentClassController代码

@RestController
@Api(value = "学生相关接口")
@RequestMapping("/student")
public class StudentController {

    @Autowired
    StudentService studentService;

    @ApiOperation("新建学生信息")
    @PostMapping("/add")
    public Integer add(StudentDTO studentDTO){
        return studentService.getBaseMapper()
                .insert(studentService.transferStudent(studentDTO));
    }

    @ApiOperation("学生逻辑删除")
    @DeleteMapping("/delete/{id}")
    public Integer delete(@PathVariable("id") Long id){
        return studentService.getBaseMapper().deleteById(id);
    }

    @ApiOperation("更新学生数据")
    @PostMapping("/update")
    public StudentVO update(StudentDTO studentDTO,
                         @ApiParam(value = "学生id") @RequestParam("id") long id){
        Student student = studentService.getBaseMapper().selectById(id);
        student = studentService.studentUpdata(studentDTO, student);
        studentService.getBaseMapper().updateById(student);
        StudentVO studentVO = new StudentVO();
        BeanUtils.copyProperties(student,studentVO);
        return  studentVO;
    }

    @ApiOperation("支持按班级名字查询学生")
    @PostMapping("/list/className")
    public IPage<StudentVO> selectPage(@ApiParam(value = "班级名字") @RequestParam("className") String className){
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("className",className);
        Page<Student> page = new Page();
        page = studentService.getBaseMapper().selectPage(page,queryWrapper);
        Page<StudentVO> voPage = new Page<>();
        BeanUtils.copyProperties(page,voPage);
        List<Student> records = page.getRecords();
        List<StudentVO> studentVOList = CglibUtil.copyList(records,StudentVO::new);
        voPage.setRecords(studentVOList);
        return voPage;
    }



    @ApiOperation("学生列表获取")
    @PostMapping("/list")
    public IPage<StudentVO> listPage(){
        Page<Student> page = new Page<>();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("logicDelete",0);
        page = studentService.getBaseMapper().selectPage(page,queryWrapper);
        Page<StudentVO> voPage = new Page<>();
        BeanUtils.copyProperties(page,voPage);
        List<Student> records = page.getRecords();
        List<StudentVO> studentVOList = CglibUtil.copyList(records,StudentVO::new);
        voPage.setRecords(studentVOList);
        return voPage;
    }

}
@Api(value = "班级相关接口")
@RestController
@RequestMapping("/Class")
public class StudentClassController {

    @Autowired
    StudentClassService studentClassService;

    @ApiOperation("班级添加学生")
    @PostMapping("/addStudent")
    public StudentVO addStudent(@ApiParam(value = "班级id") @RequestParam("classId") long classId,
                                @ApiParam(value = "学生id") @RequestParam("studentId") long studentId){
        return studentClassService.classAddStudent(classId,studentId);
    }

    @ApiOperation("班级删除学生")
    @PostMapping("/deleteStudent")
    public StudentVO deleteStudent(@ApiParam(value = "学生id") @RequestParam("id") long id){
        return studentClassService.classDeleteStudent(id);
    }

    @ApiOperation("添加新班级")
    @PostMapping("/add")
    public Integer add(@ApiParam(value = "班级名字") @RequestParam("className") String className){
        Integer result = 0;
        if(studentClassService.classChooseService(className)){

        }else {
            StudentClass studentClass = StudentClass.builder()
                    .className(className).build();
            result = studentClassService.getBaseMapper().insert(studentClass);
        }
        return result;
    }
}

然后就可以运行测试了,因为采用了Swagger文档,极大的方便前端阅读接口功能,有良好的阅读性。

测试运行

默认地址:http://localhost:8080/doc.html
在这里插入图片描述
在这里插入图片描述

功能就不一一测试了,基本功能就这样完成了。
新手实践项目的不二选择。。。。。。。。。
具体代码下载
压缩包

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值