马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
第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攻击手段,学习如何防范、掌握真实项目中的登录流程。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|