Java阶段四03

devtools/2025/1/12 0:57:56/

第4章-第3节

一、知识点

Mybatis-Plus、mapstruct

二、目标

  • 理解为什么要过滤敏感字段

  • 如何使用查询过滤

  • Mybatis-Plus如何使用联表分页查询

  • 如何实现字段的自动填充

三、内容分析

  • 重点

    • 掌握几种过滤敏感字段的方式

    • 掌握Mybatis-Plus的联表分页查询方式

    • 掌握字段自动填充的实现

  • 难点

    • 掌握几种过滤敏感字段的方式

    • 掌握Mybatis-Plus的联表分页查询方式

    • 掌握字段自动填充的实现

四、内容

1、过滤敏感字段

有的时候有一些敏感数据不方便发给前端,比如用户的密码信息、一些不需要的字段、不能给前端看的数据字段,这个时候这种字段就需要过滤一下

1.1 创建一个要返回给前端的数据实体
java">@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentVo {private Long id;private String name;private Integer sex;private Integer age;private Long classId;// 在这边 我们认为下面的几个字段是不需要给前端的,将其取消掉// 代码中不用写,这边只是为了突出不要的是这几个字段// private Date createTime;// private String createBy;// private Date updateTime;// private String updateBy;// private Integer delFlag;
}
​
1.2 传统方法
java">@GetMapping("/list")
public List<StudentVo> queryList() {Page<Student> studentPage = new Page<>(1, 5);Page<Student> page = service.page(studentPage);List<Student> students = page.getRecords();List<StudentVo> studentVos = new ArrayList<>();// 循环对象集合,对需要保存的字段进行赋值加入集合for (Student s : students) {StudentVo s2 = new StudentVo();s2.setName(s.getName());s2.setClassId(s.getClassId());s2.setSex(s.getSex());// 可以发现,如果字段很多那么这个操作很繁琐studentVos.add(s2);}return studentVos;
}
1.2 使用BeanUtils
java">@GetMapping("/list")
public List<StudentVo> queryList() {Page<Student> studentPage = new Page<>(1, 5);Page<Student> page = service.page(studentPage);List<Student> students = page.getRecords();List<StudentVo> studentVos = new ArrayList<>();// 循环对象集合,对需要保存的字段进行赋值加入集合for (Student s : students) {StudentVo s2 = new StudentVo();// 简化操作,但是效率比较低BeanUtils.copyProperties(s,s2);studentVos.add(s2);}return studentVos;
}
1.3 使用插件 mapstruct
1.3.1 导入依赖
java"><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>
1.3.2 建一个专门用于映射的文件夹mapping
java">@Mapper
public interface StudentMapping {StudentMapping INSTANCE = Mappers.getMapper(StudentMapping.class);StudentVo toStudentVo(Student student);
}
1.3.3 使用
java">@GetMapping("/list")
public List<StudentVo> queryList() {Page<Student> studentPage = new Page<>(1, 5);Page<Student> page = service.page(studentPage);List<Student> students = page.getRecords();List<StudentVo> studentVos = new ArrayList<>();// 循环对象集合,对需要保存的字段进行赋值加入集合for (Student s : students) {StudentVo s2 = StudentMapping.INSTANCE.toStudentVo(s);studentVos.add(s2);}return studentVos;
}
1.3.4 也可以直接处理list
java">@Mapper
public interface StudentMapping {StudentMapping INSTANCE = Mappers.getMapper(StudentMapping.class);StudentVo toStudentVo(Student student);List<StudentVo> toStudentVoList(List<Student> studentList);
}
java">@GetMapping("/list")
public List<StudentVo> queryList() {Page<Student> studentPage = new Page<>(1, 5);Page<Student> page = service.page(studentPage);List<Student> students = page.getRecords();List<StudentVo> studentVos = StudentMapping.INSTANCE.toStudentVoList(students);return studentVos;
}
1.3.5 通过配置自动生成的方法来映射字段
java">@Mappings({@Mapping(source = "money", target = "studentMoney")
})
MsStudentVo msStudentToMsStudentVo(MsStudent msStudent);

2、联表分页查询

查询每个班级的学生 -> 查询每个班级,以及这个班级的学生数量

2.1 创建要返回的数据的实体类
java">@Data
public class ClassStudentVo {private Long id;private String name;private List<Student> studentList;
}
2.2 创建ClassMapper
java">@Repository
public interface ClassMapper extends BaseMapper<ClassStudentVo> {// 由于Mybatis本身没有联表查询的操作,所以我们要自己手写一个方法来实现Page<ClassStudentVo> queryClassAndStudent(@Param("page") Page<ClassStudentVo> page,@Param(Constants.WRAPPER) Wrapper<ClassStudentVo> wrapper);
}
2.3 接口中创建方法
java">public interface IClassService extends IService<ClassStudentVo> {Page<ClassStudentVo> queryClassAndStudent(Page<ClassStudentVo> page, Wrapper<ClassStudentVo> wrapper);
}
2.4 实现类重写方法
java">@Service
public class ClassService extends ServiceImpl<ClassMapper, ClassStudentVo> implements IClassService {@Autowiredprivate ClassMapper mapper;
​@Overridepublic Page<ClassStudentVo> queryClassAndStudent(Page<ClassStudentVo> page, Wrapper<ClassStudentVo> wrapper) {return mapper.queryClassAndStudent(page, wrapper);}
}
2.5 两种实现方式
  • 集中式

    ClassController.java

    java">@GetMapping("/queryClassAndStudent")
    public List<ClassStudentVo> queryAll(ClassStudentVo classStudentVo) {Page<ClassStudentVo> classPage = new Page<>(1, 5);QueryWrapper<ClassStudentVo> wrapper = new QueryWrapper<>();wrapper.eq(StringUtils.isNotEmpty(classStudentVo.getId()), "c.id", classStudentVo.getId());Page<ClassStudentVo> page = service.queryClassAndStudent(classPage, wrapper);System.out.println(page.getTotal());return page.getRecords();
    }

    classMapper.xml

    java"><!--  配置关联  -->
    <resultMap id="classStudentVoRes" type="com.example.demo.entity.vo.ClassStudentVo"><id property="id" column="id"/><result property="name" column="name"/><collection property="studentList" ofType="com.example.demo.entity.Student" autoMapping="true"><id property="id" column="studentId"/><result property="name" column="studentName"/><result property="age" column="age"/></collection>
    </resultMap>
    <!--  查询语句  -->
    <select id="queryClassAndStudent" resultMap="classStudentVoRes">SELECT c.id,c.name,s.id studentId,s.name studentName,s.sex,s.age,s.class_idFROM class cLEFT JOIN student s on c.id = s.class_id<!-- ${ew.customSqlSegment}这个是固定写法一定要加,不然条件就无效了 -->${ew.customSqlSegment}
    </select>

  • 分布式

    ClassController.java

    java">@GetMapping("/queryClassAndStudent2")
    public List<ClassStudentVo> queryAll2(ClassStudentVo classStudentVo) {Page<ClassStudentVo> classPage = new Page<>(1, 5);QueryWrapper<ClassStudentVo> wrapper = new QueryWrapper<>();wrapper.eq(StringUtils.isNotEmpty(classStudentVo.getId()), "id", classStudentVo.getId());Page<ClassStudentVo> page = service.queryClassAndStudent(classPage, wrapper);System.out.println(page.getTotal());return page.getRecords();
    }

    classMapper.xml

    java"><!--  配置关联  -->
    <resultMap id="classStudentVoRes" type="com.example.demo.entity.vo.ClassStudentVo"><id property="id" column="id"/><!--            <result property="name" column="name"/>--><collection property="studentList"ofType="com.example.demo.entity.Student"select="getStudentsByClassId"column="{classId=id}"/>
    </resultMap>
    <!--  班级的查询  -->
    <select id="queryClassAndStudent" resultMap="classStudentVoRes">SELECT id,name FROM class<!-- ${ew.customSqlSegment}这个是固定写法一定要加,不然条件就无效了 -->${ew.customSqlSegment}
    </select>
    <!--  内部的子查询  -->
    <select id="getStudentsByClassId" resultType="com.example.demo.entity.Student">SELECT id, name, sex, age, class_idFROM studentWHERE class_id = #{classId}
    </select>

3、字段自动填充

3.1 字段注解
java">@TableField(fill = FieldFill.INSERT)
private Date createTime;
​
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
3.2 封装一个填充类
java">@Component
public class FieldHandler implements MetaObjectHandler {/*** 插入时的填充策略** @param metaObject*/@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime", new Date(), metaObject);this.setFieldValByName("updateTime", new Date(), metaObject);}
​/*** 更新时的填充策略** @param metaObject*/@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime", new Date(), metaObject);}
​
}
3.3 执行对应的语句即可

4、小结

本章节中我们学习了Mybatis-Plus的联表分页查询、字段的自动填充和敏感字段的过滤,对Mybatis-Plus的操作更加得心应手,课后再通过练习进行巩固彻底掌握Mybatis-Plus的使用。

下一节中我们将会学到项目中会用到的插件-jwt,了解什么是CSRF攻击手段,学习如何防范、掌握真实项目中的登录流程。


http://www.ppmy.cn/devtools/149739.html

相关文章

IPV6离线地址库Java版(极致性能,无内存分配,申请了专利)

IPV6版本的技术含量就比V4版本的高了很多&#xff0c;当时还申请了技术专利的&#xff0c;也一样贴给大家看看。 IPV6离线数据包构建 package com.bob.common.utils.ip.v6;import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.util.ArrayList; i…

Wi-Fi Direct (P2P)原理及功能介绍

目录 Wi-Fi Direct &#xff08;P2P&#xff09;介绍Wi-Fi Direct P2P 概述P2P-GO&#xff08;P2P Group Owner&#xff09;工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct &#xff…

Linux第一课:c语言 学习记录day06

四、数组 冒泡排序 两两比较&#xff0c;第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮&#xff1a;i 0 n&#xff1a;n个数&#xff0c;比较 n-1-i 次 4 5 3 2 1 // 第一次比较 j 0 4 3 5 2 1 // 第二次比较 j 1 4 3 2 5 1 // 第三次比较 j 2 4 3 2 1 5 // …

【LeetCode】力扣刷题热题100道(11-15题)附源码 环形链表 二叉树中序遍历 插入法(C++)

目录 1.字母异位词分组 2.环形链表 3.环形链表2 4.二叉树的中序遍历 5.搜索插入位置 1.字母异位词分组 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 排序字符…

Ubuntu 24.04 LTS系统安装Docker踩的坑

一开始我跟着Docker给出的官网文档 Ubuntu | Docker Docs 流程走&#xff0c;倒腾了两个多小时&#xff0c;遇到了各种坑&#xff0c;最后放弃了。在我们使用脚本安装Docker命令前&#xff0c;我们先把已经安装的Docker全部卸载掉。 卸载Docker 1.删除docker及安装时自动安装…

Springboot3.x工程创建及必要引用(基础篇)

下面从环境的安装和配置开始&#xff0c;到Springboot3.x工程创建&#xff0c;记录一下让完全没有基础的小白用户也能够开始自己的第一个项目。 准备 安装JDK环境&#xff08;这里最好安装JDK17及以上版本&#xff09;安装IntelliJ IDEA Ultimate工具&#xff08;可以从官网下…

第37周:咖啡豆识别 (Tensorflow实战第七周)

目录 前言 一、前期工作 1.1 设置GPU 1.2 导入数据 输出 二、数据预处理 2.1 加载数据 2.2 可视化数据 2.3 配置数据集 三、构建VGG-16网络 3.1 VGG-16网络介绍 3.2 搭建VGG-16模型 3.2.1 直接调用官方 3.2.2 自建模型 四、编译 4.1 设置动态学习率 五、模型训…

基于Qt的OFD阅读器开发原理与实践

摘要 本文详细探讨了基于Qt开发OFD阅读器的原理与实践。通过解析OFD文件格式、构建文档结构、实现页面渲染、处理用户交互以及进行性能优化&#xff0c;本文展示了如何使用Qt框架开发一个功能强大、性能优异的OFD阅读器。文章还提供了示例代码和未来发展方向&#xff0c;为开发…