百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

QA 由浅入深持久层框架- MyBatis Plus

ztj100 2025-01-06 16:30 52 浏览 0 评论

一、MyBatis-Plus Introduce

MyBatis-Plus是一款非常强大的MyBatis增强工具包,只做增强不做改变,在不用编写任何SQL语句的情况下即可以极其方便的实现单一、批量、分页等操作。

MyBatis-Plus支持通用CRUD操作,内置通用Mapper以及通用Service以及强大的条件构造器,并且支持逆向工程即支持代码生成器,其他特性可以参考MyBatis-Plus;关于通用Mapper可以参考Mappper3官网 或者 QA 由浅入深持久层框架(十)- MyBatis 通用 Mapper(Part A) 至 QA 由浅入深持久层框架(十三)- MyBatis 通用 Mapper(Part D) 这四篇文章

1.1 工程搭建

1.1.1 MyBatis-Spring集成

使用IDEA创建Maven工程创建mybatis-plus项目,加入Spring依赖、MyBatis依赖以及其他依赖。 同时resources目录下还需要Spring配置文件application.xml、MyBatis全局配置文件mybatis-config.xml、日志配置logback.xml以及数据库连接信息配置db.properties;具体配置可以参考 QA 由浅入深持久层框架(十)- MyBatis 通用 Mapper(Part A)。

新增entity包,增加实体类Tesla

@Data
public class Tesla {

    private Integer id;
    private String name;
    private Double price;
    private String vehicleType;
    private String factory;
}

新增mapper包,增加TeslaMapper接口

public interface TeslaMapper {

    Tesla selectTeslaById(Integer id);
}

resources目录下新增mappers文件夹,增加TeslaMapper.xml

<?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.lilith.mapper.TeslaMapper">
    <sql id="teslaAllColums">
        id,name,price,vehicle_type,factory
    </sql>

    <select id="selectTeslaById" resultType="com.lilith.entity.Tesla">
        SELECT
        <include refid="teslaAllColums"></include>
        FROM tesla where id = #{id}
    </select>
</mapper>

test包下增加测试类TeslaMapperTest,对selectTeslaById方法进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class TeslaMapperTest {

    @Autowired
    private TeslaMapper teslaMapper;

    @Test
    public void selectTeslaById(){
        Tesla tesla = teslaMapper.selectTeslaById(2);
        System.out.println("查询到的内容为:" + tesla);
    }
}

执行测试

1.1.2 集成MyBatis-Plus

集成MyBatis-Plus非常简单,只需要两步,并且MyBatis-Plus自动维护了MyBatis和MyBatis-Spring,所以只需要导入MyBatis-Plus的依赖就可以代替MyBatis和MyBatis-Spring。

第一步是增加MyBatis-Plus依赖,并注释MyBatis和MyBatis-Spring依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.5.0</version>
</dependency>

第二步是替换SqlSessionFactory

<!--替换为MyBatis-Plus的MyBatisSqlSessionFactoryBean,原来是MyBatis的SqlSessionFactoryBean-->
<bean id="mybatisSqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<!--标签内的内容保持不变-->
</property>
</bean>
复制代码

plus:集成MyBatis-Plus与集成通用Mapper的区别:

依赖不同

  • 增加的依赖不同,通用Mapper没有维护MyBatis和MyBatis-Spring,导入依赖的时候需要导入通用Mapper的依赖、MyBatis依赖以及MyBatis-Spring的依赖

配置文件修改方式不同

  • MyBatis继承通用Mapper需要修改Spring配置文件中的MapperScannerConfigurer为通用Mapper下的。MP使用的是MyBatis的MapperScannerConfigurer
  • MyBatis继承MP需要修改SqlSessionFactoryBean为MP下的MyBatisSqlSessionFactoryBean,通用Mapper使用的就是MyBatis本身的SqlSessionFactoryBean

再次执行测试

控制台出现MP的logo,输出查询的数据,MP集成成功

二、MyBatis-Plus 的 CRUD

在搭建工程的时候就是使用的原生MyBatis集成Spring对tesla表进行了一次查询操作,使用MyBatis与使用通用Mapper以及使用MP(MyBatis-Plus)操作表步骤有什么区别?

使用MyBatis操作表的步骤是:

  1. 创建TeslaMapper接口,增加CRUD方法
  2. 创建TeslaMapper.xml映射文件,在映射文件中添加CRUD对应的SQL语句

使用通用Mapper操作表的步骤是:

  1. 创建TeslaMapper接口,集成通用Mapper的Mapper接口,就自动获得了CRUD方法,不需要Mapper XML文件

使用MP操作表的步骤是:

  1. 创建TeslaMapper接口,继承BaseMapper接口,就获得了CRUD方法,甚至不需要常见Mapper XML文件

2.1 BaseMapper接口

查看BaseMapper接口源码

可以看出BaseMapper接口中提供了许多CRUD的方法,继承BaseMapper接口就自动获得了这些方法

2.2 重要注解使用

@TableId注解

在TeslaMapperTest类中新增insert方法测试,往tesla表中插入一条记录

@Test
public void insert(){
    Tesla tesla = new Tesla();
    tesla.setName("Model 3 Performance");
    tesla.setPrice(330000d);
    tesla.setVehicleType("Compact Car");
    tesla.setFactory("Shanghai Gigafactory");
    
    teslaMapper.insert(tesla);
}
复制代码

执行测试

控制台输出的INSERT语句主键是1166057474,并不是按照已存在的数据递增,这是应为没有设置主键策略。

@TableId注解可以设置主键策略

在id属性上增加@TableId注解@TableId(type = IdType.AUTO),再次测试

查看数据库中插入的数据

插入的主键实现了自动递增

如果想要获取注解可以直接在插入成功后从插入的对象获取。MP会自动将主键回写到实体类中。在insert方法最后增加一句代码

System.out.println(tesla.getId());
复制代码

执行insert方法

控制台输出插入数据库的主键值

@TableName注解

在通用Mapper中需要通过注解将实体类和表、实体类属性和字段实现一一对应,防止在实体类属性名无法通过驼峰转换法转为与表字段名一致或者实体类类名与表名不一致再或者实体类中有些属性在表中没有对应的字段,那么MP与通用Mapper一致都是通过继承接口来获取通用CRUD方法,MP应该有一些注解可以将表和实体类、字段和属性一一对应起来。

首先来看看如果表名和类名不一致,再次执行插入会出现什么错误。修改表tesla的表名为t_tesla

增加测试方法,对MP提供的selectById方法测试

@Test
public void selectById(){
    Tesla tesla = teslaMapper.selectById(2);
    System.out.println("查询到的内容为:" + tesla);
}
复制代码

执行selectById方法

默认查询的表名为实体类名的首字母小写

需要使用@TableName注解将Tesla实体类与t_tesla表关联起来 @TableName(value = "t_tesla")

再次执行selectById方法

成功查询出id为2的记录,查询的表名是注解中指定的表名

MP全局策略配置

在表非常多的情况下,如果每个表都需要指定主键生成策略以及使用注解指定表名,也会非常麻烦,所以可以通过全局配置来解决

主键的全局配置

在application.xml配置文件中可以设置MP全局策略,通过bean标签进行设置并且在mybatisSqlSessionFactoryBean中引入全局配置。

<!--将DB配置注入全局配置-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> <!--  非必须  -->
</bean>

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <!--全局配置主键策略,AUTO或者索引0-->
    <property name="idType" value="AUTO"></property>
</bean>
复制代码

在mybatisSqlSessionFactoryBean中注入全局配置

<!--替换为MyBatis-Plus的MyBatisSqlSessionFactoryBean,原来是MyBatis的SqlSessionFactoryBean-->
<bean id="mybatisSqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
</property>
    <!--将全局配置注入到SqlSessionFactoryBean-->
    <property name="globalConfig" ref="globalConfig" />
</bean>
复制代码

将Tesla实体类上的@TableId注解注释,执行insert方法

查看数据库插入的记录

同样可以实现主键自动递增,这样就免去了在每一个实体类的主键属性上增加@TableId注解

表名的全局配置

如果表名都有统一的前缀,也可以使用全局配置

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <!--全局配置主键策略,AUTO或者索引0-->
    <property name="idType" value="AUTO"></property>
    <!--配置统一表名前缀-->
    <property name="tablePrefix" value="t_" />
</bean>
复制代码

将实体类上的@TableName注解注释,执行selectById方法

查询的表名成功加上了指定的前缀。

其他MP配置请参考官方配置文档

@TableField注解

如果表字段和实体类属性完全不一致,这就不仅仅是通过配置驼峰命名法能够解决的了。

修改Tesla实体类属性,更改name为vehicleName、更改price为vehiclePrice

@Data
public class Tesla {

    private Integer id;
    private String vehicleName;
    private Double vehiclePrice;
    private String vehicleType;
    private String factory;
}
复制代码

执行selectById测试

在实体类属性和字段名不一致的时候可以使用@TableField注解来表示该属性和指定的字段一一对应。修改Tesla实体类

@Data
public class Tesla {

    private Integer id;
    @TableField(value = "name")
    private String vehicleName;
    @TableField(value = "price")
    private Double vehiclePrice;
    private String vehicleType;
    private String factory;
}
复制代码

再次selectById测试

控制台输出的SQL语句中增加了别名,别名就是原本的属性名,成功查询出数据。

@TableField的属性有value和exist,value就是要指定对应的字段的名称;exist指该属性在表中是否有对应的字段,默认是true

2.3 MP中关于表和实体类注解与通用Mapper中关于表和实体类注解的区别

MP中通过注解来解决实体类和表以及属性和字段的对应关系

  • @TableName:将实体类和指定的表对应起来,默认的表名是实体类名字的首字母小写
  • @TableId:指定主键生成策略,存在默认的生成策略
  • @TableField:设置属性与指定字段一一对应

在通用Mapper中也可以通过注解来解决实体类和表对应关系

  • @Table:该注解用来将实体类与指定的表一一对应
  • @Id:该注解用来指定属性与表中主键字段对应
  • @GeneratedValue:该注解用来指定主键的生成策略,与@Id同时使用
  • @Column:该注解用来将实体类属性和字段一一对应起来
  • @Transient:该注解表示属性在表中吴对应的字段

原生MyBatis注解策略需要在insert标签内使用两个属性useGeneratedKeys和keyProperty来获取生成的主键。

<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO t_employee(empname,gender,email) values (#{empName},#{gender},#{email})
</insert>
复制代码

2.4 MP 的 insert 相关方法

MP中BaseMapper的insert方法会将实体类插入带数据库表中,MP会对插入的属性进行值判断,可以实现将有值的字段插入,值为空的属性不会执行插入操作。

更改TeslaMapperTest中的insert方法,将部分属性赋值的代码注释,

@Test
public void insert(){
    Tesla tesla = new Tesla();
    tesla.setVehicleName("Model 3 Performance");
    // tesla.setVehiclePrice(330000d);
    // tesla.setVehicleType("Compact Car");
    tesla.setFactory("Shanghai Gigafactory");

    teslaMapper.insert(tesla);
    System.out.println(tesla.getId());
}
复制代码

执行测试

根据控制台输出的SQL语句,可以确定MP只将有值的字段执行了插入。如果想要空的字段也出现在INSERT语句中,需要给字段设置NULL。


作者:RiemannHypo
链接:https://juejin.cn/post/7069790264885248007

相关推荐

离谱!写了5年Vue,还不会自动化测试?

前言大家好,我是倔强青铜三。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。Playwright是一个功能强大的端到...

package.json 与 package-lock.json 的关系

模块化开发在前端越来越流行,使用node和npm可以很方便的下载管理项目所需的依赖模块。package.json用来描述项目及项目所依赖的模块信息。那package-lock.json和...

Github 标星35k 的 SpringBoot整合acvtiviti开源分享,看完献上膝盖

前言activiti是目前比较流行的工作流框架,但是activiti学起来还是费劲,还是有点难度的,如何整合在线编辑器,如何和业务表单绑定,如何和系统权限绑定,这些问题都是要考虑到的,不是说纯粹的把a...

Vue3 + TypeScript 前端研发模板仓库

我们把这个Vue3+TypeScript前端研发模板仓库的初始化脚本一次性补全到可直接运行的状态,包括:完整的目录结构所有配置文件研发规范文档示例功能模块(ExampleFeature)...

Vue 2迁移Vue 3:从响应式到性能优化

小伙伴们注意啦!Vue2已经在2023年底正式停止维护,再不升级就要面临安全漏洞没人管的风险啦!而且Vue3带来的性能提升可不是一点点——渲染速度快40%,内存占用少一半,更新速度直接翻倍!还在...

VUE学习笔记:声明式渲染详解,对比WEB与VUE

声明式渲染是指使用简洁的模板语法,声明式的方式将数据渲染进DOM系统。声明式是相对于编程式而言,声明式是面向对象的,告诉框架做什么,具体操作由框架完成。编程式是面向过程思想,需要手动编写代码完成具...

苏州web前端培训班, 苏州哪里有web前端工程师培训

前端+HTML5德学习内容:第一阶段:前端页面重构:PC端网站布局、HTML5+CSS3基础项目、WebAPP页面布局;第二阶段:高级程序设计:原生交互功能开发、面向对象开发与ES5/ES6、工具库...

跟我一起开发微信小程序——扩展组件的代码提示补全

用户自定义代码块步骤:1.HBuilderX中工具栏:工具-代码块设置-vue代码块2.通过“1”步骤打开设置文件...

JimuReport 积木报表 v1.9.3发布,免费可视化报表

项目介绍积木报表JimuReport,是一款免费的数据可视化报表,含报表、大屏和仪表盘,像搭建积木一样完全在线设计!功能涵盖:数据报表、打印设计、图表报表、门户设计、大屏设计等!...

软开企服开源的无忧企业文档(V2.1.3)产品说明书

目录1....

一款面向 AI 的下一代富文本编辑器,已开源

简介AiEditor是一个面向AI的下一代富文本编辑器。开箱即用、支持所有前端框架、支持Markdown书写模式什么是AiEditor?AiEditor是一个面向AI的下一代富文本编辑...

玩转Markdown(2)——抽象语法树的提取与操纵

上一篇玩转Markdown——数据的分离存储与组件的原生渲染发布,转眼已经鸽了大半年了。最近在操纵mdast生成md文件的时候,心血来潮,把玩转Markdown(2)给补上了。...

DeepseekR1+ollama+dify1.0.0搭建企业/个人知识库(入门避坑版)

找了网上的视频和相关文档看了之后,可能由于版本不对或文档格式不对,很容易走弯路,看完这一章,可以让你少踩三天的坑。步骤和注意事项我一一列出来:1,前提条件是在你的电脑上已配置好ollama,dify1...

升级JDK17的理由,核心是降低GC时间

升级前后对比升级方法...

一个vsCode格式化插件_vscode格式化插件缩进量

ESlint...

取消回复欢迎 发表评论: