MybatisPlus笔记:无废话实践代码纯享版

2024-04-23 22:12

本文主要是介绍MybatisPlus笔记:无废话实践代码纯享版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

条件构造器Wrapper

概述

我们在实际操作数据库的时候会涉及到很多的条件。所以MP为我们提供了一个功能强大的条件构造器 Wrapper 。使用它可以让我们非常方便的构造条件。

在其子类AbstractWrapper中提供了很多用于构造Where条件的方法。AbstractWrapper的子类QueryWrapper则额外提供了用于针对Select语法的select方法。可以用来设置查询哪些列AbstractWrapper的子类UpdateWrapper则额外提供了用于针对SET语法的set方法。可以用来设置对哪些列进行更新。

完整的AbstractWrapper方法可以参照:https://baomidou.com/pages/10c804/#abstractwrapper


常用AbstractWrapper方法

eq:equals,等于
gt:greater than ,大于 >
ge:greater than or equals,大于等于≥
lt:less than,小于<
le:less than or equals,小于等于≤
between:相当于SQL中的BETWEEN
like:模糊匹配。like("name","黄"),相当于SQL的name like '%黄%'
likeRight:模糊匹配右半边。likeRight("name","黄"),相当于SQL的name like '黄%'
likeLeft:模糊匹配左半边。likeLeft("name","黄"),相当于SQL的name like '%黄'
notLike:notLike("name","黄"),相当于SQL的name not like '%黄%'
isNull
isNotNull
and:SQL连接符AND
or:SQL连接符ORin: in(“age",{1,2,3})相当于 age in(1,2,3)groupBy: groupBy("id","name")相当于 group by id,nameorderByAsc :orderByAsc("id","name")相当于 order by id ASC,name ASCorderByDesc :orderByDesc ("id","name")相当于 order by id DESC,name DESC
示例一

SQL语句如下。

SELECT id,user_name,PASSWORD,NAME,age,address 
FROM USER 
WHERE age > 18 AND address = '杭州'

Wrapper写法如下。

    @Testpublic void testWrapper01(){QueryWrapper wrapper = new QueryWrapper();wrapper.gt("age",18);wrapper.eq("address","杭州");List<User> users = userMapper.selectList(wrapper);System.out.println(users);}

示例二

SQL语句。

SELECT id,user_name,PASSWORD,NAME,age,address 
FROM USER 
WHERE id IN(1,2,3) AND age BETWEEN 12 AND 29 AND address LIKE '%山%'

Wrapper写法。

  @Testpublic void testWrapper1 (){QueryWrapper wrapper = new QueryWrapper<>();wrapper.in("id",1,2,3);wrapper.between("age",12,29);wrapper.like("address","山");List<User> users = userMapper.selectList(wrapper);System.out.println(users);}

示例三

SQL语句。

SELECT id,user_name,PASSWORD,NAME,age,address 
FROM USER 
WHERE id IN(1,2,3) AND age > 10 
ORDER BY age DESC

Wrapper写法。

    @Testpublic void testWrapper03(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.in("id",1,2,3);queryWrapper.gt("age",10);queryWrapper.orderByDesc("age");List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);}

常用QueryWrapper方法

QueryWrapperselect 可以设置要查询的列。

示例一

select(String… sqlSelect) 方法的参数为要查询的列名

SQL语句。

SELECTid,user_name
FROM USER

Wrapper写法。

   @Testpublic void testSelect01(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("id","user_name");List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);}

示例二

select(Class entityClass, Predicate predicate)

方法的第一个参数为实体类的字节码对象,第二个参数为Predicate类型,可以使用lambda的写法,过滤要查询的字段 (主键除外) 。

SQL语句。

SELECT id,user_name
FROM USER 

Wrapper写法。

    @Testpublic void testSelect02(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select(User.class, new Predicate<TableFieldInfo>() {@Overridepublic boolean test(TableFieldInfo tableFieldInfo) {return "user_name".equals(tableFieldInfo.getColumn());}});List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);}
//Lambda写法
@Test
public void testSelect03(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select(User.class, (TableFieldInfo->TableFieldInfo.getColumn().equals("user")));List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);
}

示例三

select(Predicate predicate)

方法第一个参数为Predicate类型,可以使用lambda的写法,过滤要查询的字段 (主键除外) 。

SQL语句。

SELECT id,user_name,password,name,age 
FROM USER

Wrapper写法。

    @Testpublic void testSelect04() {QueryWrapper<User> queryWrapper = new QueryWrapper<>(new User());queryWrapper.select(new Predicate<TableFieldInfo>() {@Overridepublic boolean test(TableFieldInfo tableFieldInfo) {return !"address".equals(tableFieldInfo.getColumn());}});List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);}
//Lmabda@Testpublic void testSelect04_lambda() {QueryWrapper<User> queryWrapper = new QueryWrapper<>(new User());queryWrapper.select(TableFieldInfo->!"address".equals(TableFieldInfo.getColumn()));List<User> users = userMapper.selectList(queryWrapper);System.out.println(users);}

常用UpdateWrapper方法

我们前面在使用update方法时需要创建一个实体类对象传入,用来指定要更新的列及对应的值。但是如果需要更新的列比较少时,创建这么一个对象显的有点麻烦和复杂。我们可以使用UpdateWrapper的set方法来设置要更新的列及其值。同时这种方式也可以使用Wrapper去指定更复杂的更新条件。

示例

SQL语句。

UPDATE USER
SET age = 99
where id > 1

Wrapper写法。

    @Testpublic void testUpdateWrapper() {UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.gt("id",1);updateWrapper.set("age",99);int update = userMapper.update(null, updateWrapper);System.out.println(update);}

Lambda条件构造器

我们前面在使用条件构造器时列名都是用字符串的形式去指定。这种方式无法在编译期确定列名的合法性。

所以MP提供了一个Lambda条件构造器可以让我们直接以实体类的方法引用的形式来指定列名。这样就可以弥补上述缺陷。

示例一

SQL语句。

SELECT id,user_name,PASSWORD,NAME,age,address 
FROM USER 
WHERE age > 18 AND address = '山东'

Wrapper之前的写法

    @Testpublic void testLambdaWrapper(){QueryWrapper<User> queryWrapper = new QueryWrapper();queryWrapper.gt("age",18);queryWrapper.eq("address","山东");List<User> users = userMapper.selectList(queryWrapper);}

使用Lambda构造器的写法。

    @Testpublic void testLambdaWrapper() {LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.gt(User::getAge,11);queryWrapper.eq(User::getAddress,"山东");List<User> users = userMapper.selectList(queryWrapper);}

自定义SQL

虽然MP为我们提供了很多常用的方法,并且也提供了条件构造器。但是如果真的遇到了复杂的SQL时,我们还是需要自己去定义方法,自己去写对应的SQL,这样SQL也更有利于后期维护。因为MP是对mybatis做了增强,所以还是支持之前Mybatis的方式去自定义方法。

同时也支持在使用Mybatis的自定义方法时使用MP的条件构造器帮助我们进行条件构造。


准备工作

数据

CREATE TABLE `orders` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`price` int(11) DEFAULT NULL COMMENT '价格',`remark` varchar(100) DEFAULT NULL COMMENT '备注',`user_id` int(11) DEFAULT NULL COMMENT '用户id',`update_time` timestamp NULL DEFAULT NULL COMMENT '更新时间',`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',`version` int(11) DEFAULT '1' COMMENT '版本',`del_flag` int(1) DEFAULT '0' COMMENT '逻辑删除标识,0-未删除,1-已删除',`create_by` varchar(100) DEFAULT NULL COMMENT '创建人',`update_by` varchar(100) DEFAULT NULL COMMENT '更新人',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;/*Data for the table `orders` */insert  into `orders`(`id`,`price`,`remark`,`user_id`,`update_time`,`create_time`,`version`,`del_flag`,`create_by`,`update_by`) values (1,2000,'无',2,'2021-08-24 21:02:43','2021-08-24 21:02:46',1,0,NULL,NULL),(2,3000,'无',3,'2021-08-24 21:03:32','2021-08-24 21:03:35',1,0,NULL,NULL),(3,4000,'无',2,'2021-08-24 21:03:39','2021-08-24 21:03:41',1,0,NULL,NULL);

实体

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Orders  {private Long id;/*** 价格*/private Integer price;/*** 备注*/private String remark;/*** 用户id*/private Integer userId;/*** 更新时间*/private LocalDateTime updateTime;/*** 创建时间*/private LocalDateTime createTime;/*** 版本*/private Integer version;/*** 逻辑删除标识,0-未删除,1-已删除*/private Integer delFlag;
}

Mybatis的方式

接口方法定义

在对应的接口mapper中定义方法。

public interface UserMapper extends BaseMapper<User> {User findMyUser(Long id);
}

配置mapper.xml路径

application.yml中

mybatis-plus:mapper-locations: classpath*:/mapper/**/*.xml

编写Mapper.xml,自定义SQL

<?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.waer.demo.mapper.UserMapper"><select id="findMyUser" resultType="com.waer.demo.pojo.User">select * from user where id = #{id}</select>
</mapper>

Mybatis方式结合条件构造器

我们在使用上述方式自定义方法时。如果也希望我们的自定义方法能像MP自带方法一样使用条件构造器来进行条件构造的话只需要使用如下方式即可。

方法定义中添加Warpper类型的参数,添加Warpper类型的参数,并且要注意给其指定参数名。

    User findUserByWrapper(@Param(Constants.WRAPPER) Wrapper<User> wrapper);

SQL编写

<select id="findUserByWrapper" resultType="com.waer.demo.pojo.User">select * from user ${ew.customSqlSegment}
</select>

两种方式的测试。

    @Testpublic void testSQL1() {User myUser = userMapper.findMyUser(1L);System.out.println(myUser);}@Testpublic void testSQL2() {LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.gt(User::getAge,11);queryWrapper.eq(User::getAddress,"山东");User user = userMapper.findUserByWrapper(queryWrapper);System.out.println(user);}

【注意】不能使用#{}应该用${}


分页查询

配置分页拦截器

/*** @author: 八尺妖剑* @date: 2022/9/5 12:11* @email: ilikexff@gmail.com* @blog: https://www.waer.ltd*/
@Configuration
public class PageConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}

分页查询

其实就是将查询的数据封装到Page对象中。

    @Testpublic void testPage() {Page<User> page = new Page<>();/*设置每页条数*/page.setSize(2);/*查询到第几页*/page.setCurrent(1);userMapper.selectPage(page,null);/*获取当前页的数据*/System.out.println("当前页的数据:"+page.getRecords());/*获取总记录数*/System.out.println("总记录数:"+page.getTotal());/*当前页码*/System.out.println("当前页码:"+page.getCurrent());   }

多表分页查询

如果需要在多表查询时进行分页查询的话,就可以在mapper接口中自定义方法,然后让方法接收Page对象。

示例

我们需要去查询Orders表,并且要求查询的时候除了要获取到Orders表中的字段,还要获取到每个订单的下单用户的用户名。

准备

SQL语句

SELECT o.*,u.`user_name`
FROM USER u,orders o
WHERE o.`user_id` = u.`id`

在实体类Orders中新增一个userName字段。

private String userName;
//已省略其他未变动代码

实现

定义接口方法,方法第一个参数为Page类型。

 IPage<Orders> findAllOrders(Page<Orders> page);

xml中不需要关心分页操作,MP会帮我们完成。

<?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.waer.demo.mapper.OrdersMapper"><select id="findAllOrders" resultType="com.waer.demo.pojo.Orders">SELECTo.*,u.`user_name`FROMUSER u,orders oWHEREo.`user_id` = u.`id`</select>
</mapper>

测试。

    @Testpublic void testOrdersPage(){Page<Orders> page = new Page<>();//设置每页大小page.setSize(2);//设置当前页码page.setCurrent(2);ordersMapper.findAllOrders(page);/*获取当前页的数据*/System.out.println("当前页的数据:"+page.getRecords());/*获取总记录数*/System.out.println("总记录数:"+page.getTotal());/*当前页码*/System.out.println("当前页码:"+page.getCurrent());}

Service层的接口

基本使用

MP也为我们提供了Service层的实现。我们只需要编写一个接口,继承IService,并创建一个接口实现类继承ServiceImpl,即可使用。相比于Mapper接口,Service层主要是支持了更多批量操作的方法。

接口。

public interface UserService extends IService<User> {}

实现类。

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}

测试

    @Testpublic void testSeervice(){List<User> list = userService.list();System.out.println(list);}

自定义方法

public interface UserService extends IService<User> {User test();
}

自定义方法实现。

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Autowiredprivate OrdersMapper ordersMapper;@Overridepublic User test() {UserMapper userMapper = getBaseMapper();List<Orders> orders = ordersMapper.selectList(null);User user = userMapper.selectById(3);/*查询用户对应的订单*/QueryWrapper<Orders> wrapper  = new QueryWrapper<>();wrapper.eq("user_id",3);List<Orders> ordersList = ordersMapper.selectList(wrapper);return user;}
}

代码生成器

MP提供了一个代码生成器,可以让我们一键生成实体类,Mapper接口,Service,Controller等全套代码 。使用方式如下。

添加依赖。

<!--mybatisplus代码生成器-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version>
</dependency>
<!--模板引擎-->
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId>
</dependency>

生成规则配置

在下面的代码中自定义自己的项目信息即可。

    @Testpublic void generate() {AutoGenerator generator = new AutoGenerator();// 全局配置GlobalConfig config = new GlobalConfig();String projectPath = System.getProperty("user.dir");// 设置输出到的目录config.setOutputDir(projectPath + "/src/main/java");config.setAuthor("八尺妖剑");// 生成结束后是否打开文件夹config.setOpen(false);// 全局配置添加到 generator 上generator.setGlobalConfig(config);// 数据源配置DataSourceConfig dataSourceConfig = new DataSourceConfig();dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&serverTimezone=UTC");dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");dataSourceConfig.setUsername("root");dataSourceConfig.setPassword("123456");// 数据源配置添加到 generatorgenerator.setDataSource(dataSourceConfig);// 包配置, 生成的代码放在哪个包下PackageConfig packageConfig = new PackageConfig();packageConfig.setParent("com.waer.demo.generator");// 包配置添加到 generatorgenerator.setPackageInfo(packageConfig);// 策略配置StrategyConfig strategyConfig = new StrategyConfig();// 下划线驼峰命名转换strategyConfig.setNaming(NamingStrategy.underline_to_camel);strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);// 开启lombokstrategyConfig.setEntityLombokModel(true);// 开启RestControllerstrategyConfig.setRestControllerStyle(true);generator.setStrategy(strategyConfig);generator.setTemplateEngine(new FreemarkerTemplateEngine());// 开始生成generator.execute();}

参考&引用:

  • https://baomidou.com/
  • https://space.bilibili.com/663528522?spm_id_from=333.337.0.0

这篇关于MybatisPlus笔记:无废话实践代码纯享版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/930019

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear