当前位置: 首页 > news >正文

【JavaEE】(19) MyBatis-plus

一、MyBatis Generator

        为 MyBastis 框架设计的代码生成工具,简化持久层编码工作。根据数据库表自动生成 Java 实体类、Mapper 接口、SQL 的 xml 文件。让开发者专注于业务逻辑。

1、引入插件

        MyBatis 官网搜索 MyBatis Generator 插件:Running MyBatis Generator With Maven – MyBatis Generator Corehttps://mybatis.org/generator/running/runningWithMaven.html

            <plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.6</version><executions><execution><id>Generate MyBatis Artifacts</id><phase>deploy</phase><goals><goal>generate</goal></goals></execution></executions><configuration><!--generator配置文件所在位置--><configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile><!-- 允许覆盖生成的文件;xml不会覆盖, 采用追加的方式--><overwrite>true</overwrite><verbose>true</verbose><!--将当前pom的依赖项添加到生成器的类路径中--><includeCompileDependencies>true</includeCompileDependencies></configuration><!--该插件的依赖,在 <dependencies> 中引入的它识别不到--><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies></plugin>

2、修改 generatorConfig.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration><!-- 一个数据库一个context --><context id="MysqlTables" targetRuntime="MyBatis3Simple"><!--禁用自动生成的注释--><commentGenerator><property name="suppressDate" value="true"/><property name="suppressAllComments" value="true" /></commentGenerator><!--数据库连接信息--><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://127.0.0.1:3306/book_test?serverTimezone=Asia/Shanghai&amp;nullCatalogMeansCurrent=true"userId="root"password="root"></jdbcConnection><!-- 生成实体类, 配置路径 --><javaModelGenerator targetPackage="com.edu.generator.model" targetProject="src/main/java" ><property name="enableSubPackages" value="false"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- 生成mapxml文件 --><sqlMapGenerator targetPackage="generatorMapper" targetProject="src/main/resources" ><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- 生成mapxml对应client,也就是接口dao --><javaClientGenerator targetPackage="com.edu.generator.mapper" targetProject="src/main/java" type="XMLMAPPER" ><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- table可以有多个,tableName表示要匹配的数据库表 --><table tableName="user_info" domainObjectName="UserInfo" enableSelectByExample="true"enableDeleteByExample="true" enableDeleteByPrimaryKey="true" enableCountByExample="true"enableUpdateByExample="true"><!--   类的属性是否用数据库中的真实字段名做为属性名, 不指定这个属性会自动转换 _ 为驼峰命名规则         --><property name="useActualColumnNames" value="false" /><!-- 数据库表主键 --><generatedKey column="id" sqlStatement="Mysql" identity="true" /></table><table tableName="book_info" domainObjectName="BookInfo" enableSelectByExample="true"enableDeleteByExample="true" enableDeleteByPrimaryKey="true" enableCountByExample="true"enableUpdateByExample="true"><!--   类的属性是否用数据库中的真实字段名做为属性名, 不指定这个属性会自动转换 _ 为驼峰命名规则         --><property name="useActualColumnNames" value="false" /><!-- 数据库表主键 --><generatedKey column="id" sqlStatement="Mysql" identity="true" /></table></context>
</generatorConfiguration>
  • targetRuntime="MyBatis3Simple":"MyBatis3Simple" 生成的 SQL 的 xml 语句比较简单;"MyBatis3" 比较复杂。
  • targetPackage="com.edu.generator.model":生成在哪个包。
  • tableName="user_info":数据库对应的表名。
  • domainObjectName="BookInfo":对应的实体类名。
  • <generatedKey column="id":主键名。
  • <property name="useActualColumnNames" value="false" />:属性名自动转换成驼峰命名规则。

        只生成实体类的版本:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration><!-- 一个数据库一个context --><context id="MysqlTables" targetRuntime="MyBatis3Simple"><!-- 禁用自动生成的注释 --><commentGenerator><property name="suppressDate" value="true"/><property name="suppressAllComments" value="true" /></commentGenerator><!-- 数据库连接信息 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis_test?serverTimezone=Asia/Shanghai&amp;nullCatalogMeansCurrent=true"userId="root"password="123456"></jdbcConnection><!-- 生成实体类配置 --><javaModelGenerator targetPackage="com.edu.mybatis.plus.model" targetProject="src/main/java" ><property name="enableSubPackages" value="false"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- 移除SQL映射文件生成器(不生成Mapper XML) --><!-- 移除Java客户端生成器(不生成Mapper接口) --><!-- 表配置 --><table tableName="user_info" domainObjectName="UserInfo"><property name="useActualColumnNames" value="false" /><generatedKey column="id" sqlStatement="Mysql" identity="true" /></table></context>
</generatorConfiguration>

3、生成代码

        在 maven 中运行插件,自动生成代码:

        生成的文件:

        实体类把 getter、setter 都生成了,为了好看,可以调整为 @Data:

        Mapper 接口、xml 文件生成了一些基础的数据库操作。(不建议用,mxl 文件代码太乱了,看着很复杂)

        该插件的使用,需要配置很多东西,比如数据库连接的信息,但是这些信息已经在 spring boot 的配置文件中配置过了,因此该插件还不够方便。对于 mapper、xml 的编写,Mybatis-plus 框架才是我们学习的重点。用用 MyBatis Generator 的实体类自动生成即可。

二、MyBatis-plus

        MyBatis-plus 在 MyBatis 的基础上扩展功能,跟 MyBatis 不冲突。直接在 Spring Boot 项目的POM 文件中引入依赖即可。

        官方文档:

快速开始 | MyBatis-Plushttps://baomidou.com/getting-started/

1、快速上手

创建一个 Spring Boot 项目:

引入依赖:spring boot3 对应的版本

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.12</version>
</dependency>

配置数据库连接信息(.yml)。

启动类加入 @MapperScan,指定要扫描的 Mapper 文件路径。或者每个 mapper 类加@Mapper,二选其一

创建要操作的表对应的实体类。

编写 Mapper 接口类:

2、简单 CRUD 单元测试

(1)查

    @Testpublic void testSelectAll() {System.out.println(("----- 查询所有 ------"));List<UserInfo> userList = userInfoMapper.selectList(null);userList.forEach(System.out::println);}@Testvoid testSelectById(){System.out.println(("----- 按 主键 查询 ------"));UserInfo userInfo = userInfoMapper.selectById(2);System.out.println(userInfo);}@Testvoid testSelectByIds(){System.out.println(("----- 按 主键 集合查询 ------"));List<UserInfo> userInfos = userInfoMapper.selectByIds(List.of(1,2));userInfos.forEach(System.out::println);}

(2)增

    @Testvoid testInsert(){System.out.println(("----- 插入一条数据 ------"));UserInfo userInfo = new UserInfo();userInfo.setUserName("Jay");userInfo.setPassword("Chou");int insert = userInfoMapper.insert(userInfo);System.out.println("影响行数:"+ insert);}

id 生成了随机数:

想自增需要使用 @TableId 设置:

id 会从最大值 2 开始自增:

如果想修改最大值:表上右键 >> 设计表 >> 选项 修改

(3)改

    @Testvoid testUpdate(){System.out.println(("----- 按 主键 更新一条数据 ------"));UserInfo userInfo = new UserInfo();userInfo.setId(2);userInfo.setUserName("lisi");userInfo.setDeleteFlag(1);userInfoMapper.updateById(userInfo);}

(4)删

    @Testvoid testDelete(){System.out.println(("----- 按 主键 删除一条数据 ------"));userInfoMapper.deleteById(-2019921918);}

3、命名映射注解

        MyBatis-plus 如何将类名、属性名与数据库表、主键字段、普通字段对应:

  • 根据实体类名推断表名。(@TableName
  • 默认 id 属性是主键。(@TableId
  • 驼峰规则的属性名对应的蛇形命名,就是表字段。(@TableField
  • 如果 java 命名不符合自动对应的的规则,可以用注解进行绑定

4、打印日志

        把 mybatis 改成 mybatis-plus 即可:

mybatis-plus:configuration: # 配置打印 MyBatis ⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

5、自动生成代码(了解)

参考:代码生成器 | MyBatis-Plus

引入依赖:generator + 模板引擎

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.12</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency>

自动生成代码:

​public void test() {FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8" +"&useSSL=false&allowPublicKeyRetrieval=true","root", "123456").globalConfig(builder -> builder.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")).packageConfig(builder -> builder.parent("com.edu.mybatis.plus.generator").entity("entity").mapper("mapper").service("service").xml("mapper.xml")).strategyConfig(builder -> builder.entityBuilder().enableLombok()).templateEngine(new FreemarkerTemplateEngine()).execute();}​

6、复杂 CRUD 操作

(1)什么是条件构造器

        条件构造器(Wrapper 类)允许链式构造条件(用 . 的方式直接引用条件构造方法),避免编写复杂 SQL,同时减少 SQL 注入风险。

  • AbstractWrapper:抽象类,提供 Wrapper 类共有的方法和属性。
  • QueryWrapper:构造查询条件。
  • UpdateWrapper:构造更新条件,可以不用构造实体类设置 set。
  • LambdaQueryWrapper:基于 Lambda 表达式构造查询条件。
  • LambdaUpdateWrapper:基于 Lambda 表达式构造更新条件。

        AbstractWrapper 实现了 Compare 接口,包含了各种条件构造器,比如大于、等于、模糊查询等,这些操作是四种 Wrapper 共有的:(更多详情参考官方文档)

        (Lambda)QueryWrapper 和 (Lambda)UpdateWrapper 的不同之处就是红框的部分。绿框是构造函数,其余方法都是差不多一样的。

(2)QueryWrapper

        增删改查都能用 QueryWrapper 实现。

查询

SELECT id,user_name,password FROM user_info WHERE delete_flag = 0 AND user_name 
LIKE "%min%"
    @Testvoid testQueryWrapper(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.select("id", "user_name", "password").eq("delete_flag", 0).like("user_name", "min");List<UserInfo> userList = userInfoMapper.selectList(queryWrapper);userList.forEach(System.out::println);}

更新:需要构造实体类,设置修改值。

UPDATE user_info SET delete_flag=1 WHERE id < 3
    @Testvoid testQueryWrapper2(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();UserInfo userInfo = new UserInfo();userInfo.setDeleteFlag(1);queryWrapper.lt("id", 3);userInfoMapper.update(userInfo, queryWrapper);}

DELETE FROM user_info WHERE user_name = Jay2
    @Testvoid testQueryWrapper3(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_name", "Jay2");userInfoMapper.delete(queryWrapper);}

(3)UpdateWrapper

更新:不用构造实体类,直接 set。

 UPDATE user_info SET delete_flag=0 WHERE id IN (1,2)
    @Testvoid testUpdateWrapper(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.set("delete_flag", 0).in("id", List.of(1,2));userInfoMapper.update(updateWrapper);}

直接 set sql 语句更新

 UPDATE user_info SET delete_flag=delete_flag+1 WHERE id IN (1,2)
    @Testvoid testUpdateWrapper2(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.setSql("delete_flag = delete_flag + 1").in("id", List.of(1,2));userInfoMapper.update(updateWrapper);}

(4)LambdaQueryWrapper

        字段名容易写错,Lambda 的版本就是用 实体类名::get属性名替代字段名字符串

        可以直接 new Lambda 版本 new 普通版本再使用 lambda 方法转为 Lambda 版本

SQL:

SELECT id,user_name,password FROM user_info WHERE delete_flag = 0 AND user_name 
LIKE "%min%"
    @Testvoid testLambdaQueryWrapper(){
//        LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().select(UserInfo::getId, UserInfo::getUserName, UserInfo::getPassword).eq(UserInfo::getDeleteFlag, 0).like(UserInfo::getUserName, "min");List<UserInfo> userList = userInfoMapper.selectList(queryWrapper);userList.forEach(System.out::println);}

(5)LambdaUpdateWrapper

SQL:

 UPDATE user_info SET delete_flag=0 WHERE id IN (1,2)
    @Testvoid testLambdaUpdateWrapper(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.lambda().set(UserInfo::getDeleteFlag, 1).in(UserInfo::getId, List.of(1,2));userInfoMapper.update(updateWrapper);}

setIncrBy:递增

setDecrBy:递减

示例:

UPDATE user_info SET delete_flag = delete_flag + 1
    @Testvoid testLambdaUpdateWrapper(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.lambda().set(UserInfo::getDeleteFlag, 1).in(UserInfo::getId, List.of(1,2));userInfoMapper.update(updateWrapper);}

(6)自定义 SQL

        MyBatis-plus 框架提供的操作不能满足所有的需求,我们可以利用 Wrapper 构造条件,在 Mapper 自定义 SQL。

  • 条件构造器传参:参数名 ew 或者重命名 @Param(Constants.WRAPPER)

  • 构造器使用:${ew.customSqlSegment} 引用。

SQL:

select id,username,password FROM user_info WHERE user_name = "admin"

注解方式:

    @Select("SELECT id, user_name, password FROM user_info ${ew.customSqlSegment}")UserInfo selectByCustom(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);

XML 方式:

    <select id="selectByCustom2" resultType="com.edu.mybatis.plus.model.UserInfo">SELECT id, user_name, password FROM user_info ${ew.customSqlSegment}</select>

测试代码:

    @Testvoid testSelectByCustom(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(UserInfo::getUserName, "admin");userInfoMapper.selectByCustom(queryWrapper);}
http://www.dtcms.com/a/351118.html

相关文章:

  • 基于SpringBoot的考研资讯平台
  • 没有cpolar:会议记录手忙脚乱;有了cpolar:CapsWriter语音转文字轻松搞定
  • 如何在GitHub找到10k+个stars的仓库
  • USB摄像头驱动完整分析 (从插入到出画)
  • 飞算JavaAI:Java开发新时代的破晓之光
  • 基于印染数据的可视化系统设计与实现
  • 【笔记】大模型业务场景流程综述
  • (论文速读)MBQ:大型视觉语言模型的模态平衡量化
  • 深度学习在金融订单簿分析与短期市场预测中的应用
  • 力扣hot100:搜索旋转排序数组和寻找旋转排序数组中的最小值(33,153)
  • 大语言模型(LLM)基本原理浅析:从“冰箱做菜“到多模型对比实战
  • 理解SSH服务
  • onnx入门教程(七)——如何添加 TensorRT 自定义算子
  • 深度剖析初始化vue项目文件结构!!【前端】
  • 【分布式技术】Kafka 数据积压全面解析:原因、诊断与解决方案
  • 前沿技术借鉴研讨-2025.8.26(多任务分类/预测)
  • 极简 useState:手写 20 行,支持多次 setState 合并
  • 常用Nginx正则匹配规则
  • HTML的form表单
  • 状态模式与几个经典的C++例子
  • 《分布式任务调度中“任务重复执行”的隐性诱因与根治方案》
  • 记一次clickhouse查询优化之惰性物化
  • 手机移动代理IP:使用、配置、维护的10问10答
  • 通义灵码插件——AI 重构表单开发!半小时搭建可视化拖拽系统,效率碾压传统模式
  • 如何了解云手机的兼容性?
  • TikTok广告投放革命:指纹云手机如何实现智能群控与降本增效
  • 云手机和模拟器之间的区别
  • Windows下的异步IO通知模型
  • Tomcat下载历史版本
  • 深入浅出理解支持向量机(SVM):从原理到实践