Mybatis-Plus升级完成! 我的系统到底更新了什么?Mybatis-Plus比Mybatis好在了哪里?
拖拖沓沓写了将近一个月的系统,总的来说是把自己的Mybatis升级成了Mybatis-Plus,可是仔细一想又不完全是这样,还有许多细小的改动,这次特意写一篇博客来记录一下系统的更新日志,顺便给这个Vue–SpringBoot–Mybatis-Plus 系统画上一个句号!
一、清除警告以及不规范不必要的代码
由于之前是7天速成的这个系统,所以有很多为了省事写的代码,包括一些代码重复,过时引用,警告。
这次更新,彻底解决了以上内容,做到了在JDK8、IDEA2021.2.1上后端代码完美编译,无警告!无错误!
这是更改之前的IDEA检测数据,仔细的算了一下,竟然有341个警告,可以称得上是在警告上运行的程序了!
更改之后是这样的,还是有一点成就感(可能有警告消除强迫症吧。。。。)
二、重新绘制了一下界面,更换主题颜色
之前的系统是在网上学到的,所以颜色也和人家的差不多,借着这次更新系统的机会,我也重新设计了前端网页的主题。
这是之前的主题颜色:
这是更新之后的主题颜色(可能更加难看了,但是不管怎么说也是自己花一上午调色的(^▽^))
三、界面无ID化
由于数据库的设计,许多表之间的关联必须要用ID作为桥梁,当时设计过于粗糙,界面上直接显示了ID而不是名称,可是在实际生活中,用户看到的是名称,而不是摸不着头脑的一串数字,这应该算是当时一个严重的设计漏洞了(改起来太费劲了),这里给一个小窍门,以后在设计数据库的时候,可以在ID后面加上一个与之关联的Name列,在前端显示ID的地方改为Name(虽然会造成数据冗余,但是改起来真的好改,就偷个懒吧)
更新之前(现在看看真是不合理)
更新之后
四、Mybatis升级为Mybatis-Plus
这一点可以说是最主要的一点了,升级Mybatis-Plus之后,一条SQL语句都不用写,写过SQL语句的人都知道,设计到多表查询简直是折磨。虽然我当时是用Navicat自动生成的SQL语句,但是也没有快捷到哪里去。而且许多的操作都涉及到同一类操作(比如按照ID查找一条数据、查找表中所有数据),使用Mybatis就没有办法做到统一方法提供接口(大一统),而且当时写的比较匆忙,也没有设计一个统一方法。采用Mybatis-Plus,一行selectList就可以解决了。
更新之前(十分麻烦):
controller层:
@RequestMapping("/equipmentHire")
public String updateFactoryHire(@RequestParam("id") Integer id,
@RequestParam("hire") int hire) {
int i = udao.updateHire(id, hire);
String str = i > 0 ? "success" : "error";
return str;
}
dao层:
public int updateHire(Integer id, int hire);
mapper文件:
<update id="updateHire">
UPDATE equipment
SET e_hire = #{hire}
WHERE e_id = #{id}
</update>
更新之后(十分简便而且易于维护):
@RequestMapping("/equipmentHire")
public String updateFactoryHire(@RequestParam("id") Long id,
@RequestParam("hire") int hire) {
Equipment equipment = new Equipment();
equipment.setE_hire(hire);
QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
wrapper.eq("e_id", id);
int i = equipmentMapper.update(equipment, wrapper);
return i > 0 ? "success" : "error";
}
五、更新主键ID形式
以前的主键ID为数据库中的逐渐递增形式,可是使用过数据库中默认递增的同学就会知道,一旦调试中对数据进行手动删除,就会出现ID不连续的情况(而且一个对象的ID是1多少有点看不过去。。。),这次采用Mybatis-Plus之后,主键ID采用了SnowFlake(雪花算法),不经过数据库,完全由代码产生ID,而且唯一性极高,基本不会产生重复。由于雪花算法产生的ID为Long长整型,所以传到前端会有许多问题产生,这里给出了解决办法(^▽^)
雪花算法
Springboot-Vue-MybatisPlus 返回给前端的 Long类型数据失去精度怎么办 之 Long类型作为实体类的一个属性
Long类型传到前端失去精度(2):Long类型不是实体类的某一个字段,Long类型是一个函数的返回值
六、新增加了乐观锁
这里可以看到乐观锁插件起到了作用
七、增加了逻辑删除、新增时间、更新时间(全部由Mybatis-Plus自动执行)
通过Mybatis-Plus的逻辑删除组件,以及元数据(Meta)的自动填充组件,就可以实现逻辑删除或者在新增(更新)数据库的时候自动填充当前时间。
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill.....");
this.setFieldValByName("gmt_create", new Date(), metaObject);
this.setFieldValByName("gmt_modified", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill.....");
this.setFieldValByName("gmt_modified", new Date(), metaObject);
}
}
// 逻辑删除组件!
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
这里可以看到Mybatis-Plus在运行的时候也是和JDBC差不多:先使用prepareStatement构建SQL语句,再使用占位符(?)进行变量赋值,最后就可以对数据库进行操作。
下面的红色箭头也表明了雪花算法的ID、创建时间、更新时间是自动生成的,并不是代码中人为写出来的
八、新增SQL效率分析
通过Mybatis-Plus可以实现对SQL语句执行效率的控制!
//SQL执行效率插件
// 设置 dev test 环境开启,保证我们的效率
@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
// ms 设置sql执行的最大时间,如果超过了则不执行
performanceInterceptor.setMaxTime(100);
// 是否格式化代码
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
这里可以看出,一个select语句的执行时间为3毫秒,小于预定的100毫秒,可以执行!
如果把SQL的执行时间设置为1毫秒(其实我们知道1毫秒啥也干不了),可以看到,Mybatis-Plus终止了SQL语句的执行(这个SQL语句的执行太大了,请优化!)。这样的话我们可以根据这个SQL效率分析插件,被动地实现代码的优化!
九、代码自动生成器
设计完数据库后,再进行一遍操作差不多的实体类设计,实在是太麻烦了。Mybatis-Plus为此设计出了代码自动生成器,根据数据库的设计,一键生成bean层、dao层、controller层!十分的方便,而且可以选择一系列的选择,比如说包的策略、下划线转驼峰等
数据库设计:
自动生成的代码结构:
自动生成的实体类:
package com.neu.edu.cloudfactoryplus.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author duzhenyang
* @since 2021-09-14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Agency implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "a_id", type = IdType.ID_WORKER)
private Long a_id;
/**
* 用户名
*/
private String a_name;
/**
* 密码
*/
private String a_password;
/**
* 真实姓名
*/
private String a_realName;
/**
* 联系方式
*/
private String a_contact;
/**
* 乐观锁
*/
@Version
private Integer version;
/**
* 逻辑删除
*/
@TableLogic
private Integer deleted;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date gmt_create;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmt_modified;
}