我们只实现连接层就行,无需创建web应用。
首先准备好要连接的表。
首先创建一个新的springboot模块,勾选SQL Driver依赖,springboot没有收录mybatisplus依赖,需要后面在pom文件手动添加坐标。
添加完依赖后,之后的操作与先前差别不大,在yml文件配置连接信息,创建User类,创建UserDao接口。
使用mybatisplus,只需将UserDao继承接口BaseMapper,泛型内写User。再加上注解@Mapper。
BaseMapper实际将一些常见的SQL接口方法都写好了,以下是BaseMapper的源码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BaseMapper extends Mapper {
int insert(T entity);
int deleteById(Serializable id);
int deleteByMap(@Param("cm") Map columnMap);
int delete(@Param("ew") Wrapper queryWrapper);
int deleteBatchIds(@Param("coll") Collection extends Serializable> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper updateWrapper);
T selectById(Serializable id);
List selectBatchIds(@Param("coll") Collection extends Serializable> idList);
List selectByMap(@Param("cm") Map columnMap);
T selectOne(@Param("ew") Wrapper queryWrapper);
Integer selectCount(@Param("ew") Wrapper queryWrapper);
List selectList(@Param("ew") Wrapper queryWrapper);
List
此时springboot整合mybatis的程序即做好,可以直接测试。
在测试类里调用userDao的selectById方法:
测试成功!
mybatis是咱中国人开发的软件,确实挺不错的。
无需多言:
mybatisplus官网链接
不多废话,演示:
lombok是一个小插件,可以用来简化开发,先导入坐标,其中提供的
@Data可以为当前实体类在编译时设置get set toString等方法,但不包括构造方法。
@NoArgsConstructor 和@AllArgsConstructor分别对应无参有参构造方法。
首先先要了解分页查询方法接收的参数:
一个是page对象,另一个是Wrapper对象,
所以我们先new一个Page对象,传参即为limit的两个参数,当前页码和一页显示的数据数。
Wrapper传null过去,咱目前也不知道他干嘛的。
写好测试方法开始运行:
跑出的结果不尽人意:
为什么会产生这样的结果呢?
其实MP分页功能的实现是在sql语句的最后追加的limit语句,使用到了拦截器,而这个拦截器默认不开启,需要我们自行配置。
新建拦截器类(要将拦截器设置为bean,交给IOC管理):
我们可以在yml文件配置打开mp的输出日志:
再次测试用例:
得到了想要的结果,发现总共查询了两次,一次是查总数,另一次是分页查询
明白了 先前在介绍分页查询时的Wrapper是用来封装查询条件的。
这个涉及了一些xml的语法,还得懂xml才行看来。
xml转义字符:
会了这些,其他的条件查询也就都差不多会了。
查询name为Jerry的所有属性:
假设我们设置的查询条件,前端并未全部赋值,此时存在null的情况,这种情况也应能处理。
按照先前的写法,这样是查询不出结果的。
其实在lt和gt的源码中,还有一个参数可选。
这个boolean的参数,就是用来处理这种特殊情况的。
@Test
void testGetExistNull(){
//模拟页面传送过来的筛选数据
UserQuery uq=new UserQuery();
uq.setAge(10);
//uq.setAge2(30);
LambdaQueryWrapper lqw=new LambdaQueryWrapper<>();
lqw.lt(null!=uq.getAge2(),User::getAge,uq.getAge2())
.ge(null!=uq.getAge(),User::getAge,uq.getAge());
List userList = userDao.selectList(lqw);
System.out.println(userList);
}
先前的查询都是将数据所有的字段全部查询出来,实际开发可不会这样。
我们可以使用QueryWrapper的select方法,这是专门控制查询字段的方法。
lambda写法:
普通写法:
分组查询:
等值查询:
范围查询:
模糊匹配:
模糊匹配好多方法,相关百分号位置(likeRight,百分号在右边),以及是否为空。
select()映射的优先级更高。
当我们的类名与数据库中的表名不一致时,需要使用@TableName去设定表名映射。
当属性名与数据库中字段名不一致时,需要使用@TableFiled的value去设定映射。
当查询时属性不宜展示时,需要使用@TableFile的select=false去设定不查询。
当属性在数据库中不存在时,需要使用@TableFiled的exist=false去设定不查询。
这些配置也可以在yml文件中去配置,包括表名前缀什么的:
deleted设置默认值为0,代表未删除。
如此操作完后,mybatisplus会将所有的删除操作变为更新操作,将所有的删除了的数据的deleted字段赋值为1。
并且,添加了该字段后,查询的语句也会发生变化:
若我们想查询到所有的数据,就要自己编写SQL语句了。
乐观锁是用于修改数据过程中的并发控制,通过给操作加上一个version值来实现的。
每次修改数据,拦截器会对version值进行判断,并且会对version进行+1的操作,若update传入的对象version值与修改数据where判断的version值不一致,则update操作进行失败。
代码生成器是mybatisplus提供的便捷生成代码的方法,在实际开发中或许会接触到。
先导入代码生成器所需坐标。
com.baomidou
mybatis-plus-generator
3.4.1
org.apache.velocity
velocity-engine-core
2.3
再创建代码生成器对象
数据源配置:
DataSourceConfig datasource=new DataSourceConfig();
datasource.setDriverName("com.mysql.cj.jdbc.Driver");
datasource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_tb?serverTimezone=UTC");
datasource.setUsername("???");
datasource.setPassword("???");
一些核心配置:
GlobalConfig globalConfig =new GlobalConfig();
globalConfig.setOutputDir("D:\\all.java\\java.codes\\learning\\mybatisplus\\mybatisplus_04_generator\\src\\main\\java");
globalConfig.setOpen(false);
globalConfig.setAuthor("Ys"); //设置作者
globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
globalConfig.setIdType(IdType.ASSIGN_ID); //设置ID生成策略
autoGenerator.setGlobalConfig(globalConfig);
PackageConfig packageConfig =new PackageConfig();
packageConfig.setParent("com.example"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageConfig.setEntity("domain"); //设置实体类包名
packageConfig.setMapper("dao"); //设置数据层包名
autoGenerator.setPackageInfo(packageConfig);
StrategyConfig strategyConfig=new StrategyConfig();
strategyConfig.setInclude("tb_user"); //设置哪些表对应的操作
strategyConfig.setTablePrefix("tb_"); //设置数据库表名前缀名称
strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格
strategyConfig.setVersionFieldName("version"); //设置乐观锁字段
strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
strategyConfig.setEntityLombokModel(true);
autoGenerator.setStrategy(strategyConfig);
跑!
原先的目录结构:
运行之后:
可以说是十分便捷了,我们在后续的开发中若使用,则只需略加修改,再填上所需要的内容即可。
以上内容均学自b站黑马教学视频