Java阶段四03

news2025/1/12 1:39:54

第4章-第3节

一、知识点

Mybatis-Plus、mapstruct

二、目标

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

  • 如何使用查询过滤

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

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

三、内容分析

  • 重点

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

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

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

  • 难点

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

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

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

四、内容

1、过滤敏感字段

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

1.1 创建一个要返回给前端的数据实体
@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 传统方法
@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
@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 导入依赖
<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
@Mapper
public interface StudentMapping {
    StudentMapping INSTANCE = Mappers.getMapper(StudentMapping.class);
    StudentVo toStudentVo(Student student);
}
1.3.3 使用
@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
@Mapper
public interface StudentMapping {
    StudentMapping INSTANCE = Mappers.getMapper(StudentMapping.class);
    StudentVo toStudentVo(Student student);
    List<StudentVo> toStudentVoList(List<Student> studentList);
}
@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 通过配置自动生成的方法来映射字段
@Mappings({
    @Mapping(source = "money", target = "studentMoney")
})
MsStudentVo msStudentToMsStudentVo(MsStudent msStudent);

2、联表分页查询

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

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

    ClassController.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

    <!--  配置关联  -->
    <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_id
        FROM class c
        LEFT JOIN student s on c.id = s.class_id
        <!-- ${ew.customSqlSegment}这个是固定写法一定要加,不然条件就无效了 -->
        ${ew.customSqlSegment}
    </select>

  • 分布式

    ClassController.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

    <!--  配置关联  -->
    <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_id
        FROM student
        WHERE class_id = #{classId}
    </select>

3、字段自动填充

3.1 字段注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;
​
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
3.2 封装一个填充类
@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);
    }
​
    /**
     * 更新时的填充策略
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
​
}
3.3 执行对应的语句即可

4、小结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

继承(7)

大家好&#xff0c;今天我们继续来学习一下继承的知识&#xff0c;这方面需要大家勤动脑才能理解&#xff0c;那么我们来看。 1.9 protected关键字 在类和对象章节中&#xff0c;为了实现封装特性,java中引入访向限定符,主要限定:类或者类中成员能否在类外和其他包中被访问. …

基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS

产品设计初衷 HS-P2-2D是一款针对大车盲区开发的360度全景影像 安全行车辅助系统&#xff0c;通过车身四周安装的超广角像机&#xff0c;经算法合成全景鸟瞰图&#xff0c;通过鸟瞰图&#xff0c;司机非常清楚的看清楚车辆四周情况&#xff0c;大大降低盲区引发的交通事故。 产…

NVIDIA发布GeForce RTX 50 系列,售价549美元起

2025 CES消费电子展&#xff08;1月7日至10日&#xff0c;美国拉斯维加斯&#xff09;正式开幕。北京时间1月7日 (星期二)上午10:30&#xff0c;NVIDIA举办主题演讲&#xff0c;CEO黄仁勋担任主讲。正式发布了全新的RTX 50系列显卡&#xff01;一月下旬上市。同时公布了各版本的…

后端:Spring(IOC、AOP)

文章目录 1. Spring2. IOC 控制反转2-1. 通过配置文件定义Bean2-1-1. 通过set方法来注入Bean2-1-2. 通过构造方法来注入Bean2-1-3. 自动装配2-1-4. 集合注入2-1-5. 数据源对象管理(第三方Bean)2-1-6. 在xml配置文件中加载properties文件的数据(context命名空间)2-1-7. 加载容器…

基于EasyExcel实现通用版一对一、一对多、多层嵌套结构数据导出并支持自动合并单元格

接口功能 通用 支持一对一数据结构导出 支持一对多数据结构导出 支持多层嵌套数据结构导出 支持单元格自动合并 原文来自&#xff1a;https://blog.csdn.net/qq_40980205/article/details/136564176 新增及修复 基于我自己的使用场景&#xff0c;新增并能修复一下功能&#x…

【数据库】一、数据库系统概述

文章目录 一、数据库系统概述1 基本概念2 现实世界的信息化过程3 数据库系统内部体系结构4 数据库系统外部体系结构5 数据管理方式 一、数据库系统概述 1 基本概念 数据&#xff1a;描述事物的符号记录 数据库&#xff08;DB&#xff09;&#xff1a;长期存储在计算机内的、…

网络安全建设方案,信息安全风险评估报告,信息安全检测文档(Word原件完整版)

一、概述 1.1工作方法 1.2评估依据 1.3评估范围 1.4评估方法 1.5基本信息 二、资产分析 2.1 信息资产识别概述 2.2 信息资产识别 三、评估说明 3.1无线网络安全检查项目评估 3.2无线网络与系统安全评估 3.3 ip管理与补丁管理 3.4防火墙 四、威胁细…

数据分析工作流

数据分析工作流 1.流程 数据产生阶段 业务系统生成数据&#xff1a;在各种业务场景下&#xff0c;如用户在电商平台上进行购物&#xff08;产生订单信息、浏览记录等&#xff09;、在金融系统中进行交易&#xff08;产生交易流水、账户余额变动等&#xff09;或者在企业内部的…

【Go】:图片上添加水印的全面指南——从基础到高级特性

前言 在数字内容日益重要的今天&#xff0c;保护版权和标识来源变得关键。为图片添加水印有助于声明所有权、提升品牌认知度&#xff0c;并防止未经授权的使用。本文将介绍如何用Go语言实现图片水印&#xff0c;包括静态图片和带旋转、倾斜效果的文字水印&#xff0c;帮助您有…

PyQt5 UI混合开发,控件的提升

PromoteLabelTest.py 提升的类 import sys from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout,QTextEdit,QPushButton,QHBoxLayout,QFileDialog,QLabelclass PromoteLabel(QLabel):def __init__(self,parent None):super().__init__(parent)self.setText("…

CI/CD 流水线

CI/CD 流水线 CI 与 CD 的边界CI 持续集成CD&#xff08;持续交付/持续部署&#xff09;自动化流程示例&#xff1a; Jenkins 引入到 CI/CD 流程在本地或服务器上安装 Jenkins。配置 Jenkins 环境流程设计CI 阶段&#xff1a;Jenkins 流水线实现CD 阶段&#xff1a;Jenkins 流水…

ROS核心概念解析:从Node到Master,再到roslaunch的全面指南

Node 在ROS中&#xff0c;最小的进程单元就是节点&#xff08;node&#xff09;。一个软件包里可以有多个可执行文件&#xff0c;可执行文件在运行之后就成了一个进程(process)&#xff0c;这个进程在ROS中就叫做节点。 从程序角度来说&#xff0c;node就是一个可执行文件&…

深入Android架构(从线程到AIDL)_22 IPC的Proxy-Stub设计模式04

目录 5、 谁来写Proxy及Stub类呢? 如何考虑人的分工 IA接口知识取得的难题 在编程上&#xff0c;有什么技术可以实现这个方法&#xff1f; 范例 5、 谁来写Proxy及Stub类呢? -- 强龙提供AIDL工具&#xff0c;给地头蛇产出Proxy和Stub类 如何考虑人的分工 由框架开发者…

风水算命系统架构与功能分析

系统架构 服务端&#xff1a;Java&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;数据库&#xff1a;MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;ORM框架&#xff1a;Mybatis&#xff08;集成通用tk-mapper&#xff0c;支持myb…

551 灌溉

常规解法&#xff1a; #include<bits/stdc.h> using namespace std; int n,m,k,t; const int N105; bool a[N][N],b[N][N]; int cnt; //设置滚动数组来存贮当前和下一状态的条件 //处理传播扩散问题非常有效int main() {cin>>n>>m>>t;for(int i1;i&l…

HDFS编程 - 使用HDFS Java API进行文件操作

文章目录 前言一、创建hdfs-demo项目1. 在idea上创建maven项目2. 导入hadoop相关依赖 二、常用 HDFS Java API1. 简介2. 获取文件系统实例3. 创建目录4. 创建文件4.1 创建文件并写入数据4.2 创建新空白文件 5. 查看文件内容6. 查看目录下的文件或目录信息6.1 查看指定目录下的文…

Java面试题~~

深拷贝和浅拷贝区别了解吗?什么是引用拷贝? 关于深拷贝和浅拷贝区别&#xff0c;我这里先给结论&#xff1a; 浅拷贝&#xff1a;浅拷贝会在堆上创建一个新的对象&#xff08;区别于引用拷贝的一点&#xff09;&#xff0c;不过&#xff0c;如果原对象内部的属性是引用类型的…

el-table 自定义表头颜色

第一种方法&#xff1a;计算属性 <template><div><el-table:data"formData.detail"border stripehighlight-current-row:cell-style"{ text-align: center }":header-cell-style"headerCellStyle"><el-table-column fixed…

MySQL笔记大总结20250108

Day2 1.where (1)关系运算符 select * from info where id>1; select * from info where id1; select * from info where id>1; select * from info where id!1;(2)逻辑运算符 select * from info where name"吴佩奇" and age19; select * from info wh…

精选2款.NET开源的博客系统

前言 博客系统是一个便于用户创建、管理和分享博客内容的在线平台&#xff0c;今天大姚给大家分享2款.NET开源的博客系统。 StarBlog StarBlog是一个支持Markdown导入的开源博客系统&#xff0c;后端基于最新的.Net6和Asp.Net Core框架&#xff0c;遵循RESTFul接口规范&…