Mybatis

您所在的位置:网站首页 querywrapper大于等于小于等于 Mybatis

Mybatis

2023-06-15 13:19| 来源: 网络整理| 查看: 265

简介

Mybaits-plus 是mybits 的升级版,从mybaits 升级到mybaits-plus 可以实现平滑升级

Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper ,使用Wrapper 基本已经可以构建大部分条件了。

几乎可以实现很少代码,很多功能自动提供

使得一般的查询几乎不需要写 XML 直接使用代码包装完成。

同时支持各类注解帮助完成实体以及查询语句的构建。

环境

spring-boot

Maven 依赖

可以使用properties 的方式指定版本也可以去除perperties 直接写入版本到下面的 version 中

3.5.23.5.2com.baomidoumybatis-plus-boot-starter${mybatis-plus.version}com.baomidoumybatis-plus-generator${mybatis-plus-generator.version}org.apache.velocityvelocity-engine-core${velocity.version} 使用分页时需要添加的配置类

注意下面的导包来源路径,不要导错

import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 新增mybatis-plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 新增分页插件 并指定数据库类型PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setOptimizeJoin(true);// 查询分页最大限制 -1 时不做限制paginationInnerInterceptor.setMaxLimit(500L);// 加入分页插件interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;} }

到这里基本完成配置

同时也可以在这里使用注解指出配置的实体类扫描路径和基本Mapper 类的路径 上面也可以如下示例:

@Configuration // 指定实体类(就是和数据库中表对应的类)扫描路径 类所在包路径 @EntityScan("org.aurora.entity") // 基本的Mapper 类的所在包路径 @MapperScan(basePackages = "org.aurora.mapper", markerInterface = BaseMapper.class) public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 新增mybatis-plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 新增分页插件 并指定数据库类型PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setOptimizeJoin(true);// 查询分页最大限制 -1 时不做限制paginationInnerInterceptor.setMaxLimit(500L);// 加入分页插件interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;} }

包路径为多个同级目录下的多个mapper 时可以使用 ** 指代所有 例如:org.aurora.**.mapper 说明是 org.aurora 下所有的第一层同级包下,每个包下的 mapper 包下

例如我的测试用包路径如下 在这里插入图片描述 同时:上面的 @MapperScan 也可以加到 springboot的启动类上

如下: (注意:Application 启动类一定在 最外层,从图上可以看出和项目 resources 的层级关系,java 和 resources 同级,该类一定在一层包的最外面一层) 在这里插入图片描述 @MapperScan 也可以如下加入

@MapperScan("org.aurora.mapper") // spring 中其他通过注解等方法注入spring容器的类的扫描路径 一般放到最大的路径上 让扫描整个项目也省事 @ComponentScan(value = {"org.aurora"}) @SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

@ComponentScan 中的路径最好放在最大的,这样 config 类也能扫描到,否则你可能会发现自己的部分类配置了但是不起作用。

上方 @EntityScan(“org.aurora.entity”) 也可以加入到 spring-boot 配置文件中 而不写在文件里 例如: 在spring-boot 的 application.properties 或者 applicaiton.yml 中如下: 两种文件仅仅是排版格式不同而已,值一致 mybatis-plus 配置中,这里是 yml 如下:

mybatis-plus: # mybaits 和mybaits-plus 都可以使用的xml 文件类的扫描加载路径mapper-locations: classpath:mapper/*Mapper.xml # 上面的 EntityScan 可以替代,也可以写在这里typeAliasesPackage: org.aurora.entity

properties类文件可以如下参考

# mybaits 和mybaits-plus 都可以使用的xml 文件类的扫描加载路径 mybatis-plus.mapper-locations = classpath:mapper/*Mapper.xml# 上面的 EntityScan 可以替代,也可以写在这里 mybatis-plus.typeAliasesPackage= org.aurora.entity

mapper-locations:classpath: 后为路径,可以理解为这里扫描 resources 下一个叫 mapper 的文件加里面 所有以 Mapper为文件名后缀的 xml 文件。

一般实体类定义

(在上面定义的实体类扫描路径包下创建) 以下所有注解均来源于mybaits-plus 以及 lombok

import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.Date;@TableName("t_person") @Data @NoArgsConstructor @AllArgsConstructor public class PersonEntity {@TableId(type = IdType.AUTO)private Long id;protected boolean flag;@TableField(value="create_time")protected Date createTime;@TableField(value = "person_name")private String personName;@TableField(value = "person_id")private String personId;@TableField(value = "person_pre")private String personPre; }

@Data @NoArgsConstructor @AllArgsConstructor 为lombok 注解用于简化 get set 以及构造方法等,可以使用一般的 get set 构建函数替代而不使用注解

@TableId : 用于指定当前表的主键Id 如果自己设置了自增,不要忘了在建表时也设置主键自增否则会出现保存失败的情况

@TableName: 指定当前表的表名

@TableField: 指定当前属性在表中的字段名称 其中 flag 字段没有指定,可以认为单个单词时不用指定 table_field 默认使用属性名。

建立实体对应的Mapper 接口类 (dao 层)

(在上面指定的Mapper 扫描路径包下定义)

import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.aurora.entity.PersonEntity; import org.springframework.stereotype.Repository;// 定义为持久层 数据库交互 @Repository public interface PersonMapper extends BaseMapper {}

是的 只需要这一点就可以了 这样 Mybaits 就提供了 PersonEntity 对应表的基本查询的所有方法,当然也可以像 mybatis 一样继续定义抽象方法,然后**在 resources 下的 mapper 包内添加对应 Mapper.xml 文件的SQL实现

Mapper 接口类的实际使用

在某一Service 中我可以如下定义

基本新增数据 import org.aurora.mapper.PersonMapper; import org.aurora.entity.PersonEntity; import org.aurora.service.PersonService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.Date;@Service @Slf4j public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonMapper personMapper;@Overridepublic void test() {PersonEntity personEntity = new PersonEntity();personEntity.setFlag(true);personEntity.setCreateTime(new Date());personEntity.setPersonId("*************");personEntity.setPersonName("jack");personEntity.setPersonPre("king");personMapper.insert(personEntity);} }

这是接口类 继承 BaseMapper 后提供的基本方法,只需要实体即可。 在这里插入图片描述

基本查询

继承 baseMapper 后即提供以下查询方法 在这里插入图片描述 selectByMap: 入参为普通的 Map 其中 map 的key 需要放入实际表的字段名例如上面的(“person_name”), value 是某一个字段等于的值,相当于普通的条件查询。

selectCount: 该方法为条件下计算总数 入参为 wrapper 类。wrapper 是mybaits-plus 的条件包装类,暂时可以当作Map 但是比 Map 更强大,提供了大于,等于,小于,like 等等,方法介绍完成后下面做具体说明。

selectList: 查询满足某些条件的实体集合。

selectPage: 查询满足某些条件的实体集合。同时支持分页,可以放入分页对象,自动完成分页查询。 分页下面与 wrapper 同时介绍

selectBatchIds: 查询某一个id 集合下的所有实体。

selectById: 通过主键查询

selectMaps: 获取的结果转为 Map 的集合,可以用于单独几个字段或自定义结果查询。

selectMapsPage: 与上面比多了分页而已

selectObjs: 同样的返回自定义结果集合

selectOne: 查询某些条件下唯一的实体

Wrapper 介绍 以及分页的基本使用

查询时使用 QueryWrapper 在这里插入图片描述 在这里插入图片描述 可以看的出wrapper 提供了很多包装功能,其中入参的 column 为列名,Object 即为值,condition 为当前语句加入实际查询语句的条件可以如下理解:

即最简单的我们某一个值不存在时某一句是不需要加入的,condition 就完成了整个封装过程减少了 if 的判断

eq: 相等 in: 一般的 in 条件 ge: 大于等于 gt: 大于 le: 小于等于 lt: 小于 between : 某一列 在某两个值之间 or: 或者

以及排序 在这里插入图片描述 like 模糊查询: 在这里插入图片描述 groupBy: 在这里插入图片描述 haveing: 在这里插入图片描述

一般的使用可以如下参考:

在这里插入图片描述

分页查询

示例: 注意Page的来源 也是mybatis-plus 不要用其他的,内部已经提供了总页数,总数,当前页,页容量,

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;@Service @Slf4j public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonMapper personMapper;@Overridepublic void test() {String personName = null;Page page = new Page();// 查询的当前页码 第一页page.setCurrent(1);// 查询条数page.setSize(10);QueryWrapper queryWrapper = new QueryWrapper();queryWrapper.eq("flag", true);queryWrapper.eq(StringUtils.isNotEmpty(personName), "person_name", personName);queryWrapper.like("person_id", "4567");Page pageList = personMapper.selectPage(page, queryWrapper);} }

在这里插入图片描述

更新时 updateWrapper

当使用更新时使用 updateWrapper 但与 queryWrapper 不同的是有 set 方法,即更新某一个字段的值 同样存在 condition 的用法,免去 if 的书写。 在这里插入图片描述 例如: 在这里插入图片描述 可以看的出可以直接将实体放入后自动通过Id 更新,也可以将wrapper 放入 经过尝试,第一个方法中的entity 可以不放入填写 null ,则会根据 wrapper 中的条件更新所有符合条件的数据。

删除

同样的删除也使用 updateWrapper 方法见名知意,都很简单。 在这里插入图片描述

到此所有的基本方法基本都可以无代码自动支持了! 不得不说,真的十分简化操作!

连表查询-连表分页 注解+sql实现

首先需要在 mapper 中额外定义抽象方法

下面第一个为分页,第二个为不分页

import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository;@Repository public interface XxxxxMapper extends BaseMapper {@Select("SELECT r.id, r.dept_id, r.person_id," +"s.secret_name, t.state, f.error FROM t_person AS r "+ " LEFT JOIN t_secret AS s ON r.id = s.per_id "+ " LEFT JOIN t_xxxx AS f ON r.id = f.id "+ " LEFT JOIN t_xxxxxxxx AS t ON f.flow_id = t.id "+ " ${ew.customSqlSegment}")IPage getListPageByConditions(IPage pageDtoIPage, @Param("ew") Wrapper wrapper);@Select("SELECT r.id, r.dept_id, r.person_id," +"s.secret_name, t.state, f.error FROM t_person AS r "+ " LEFT JOIN t_secret AS s ON r.id = s.per_id "+ " LEFT JOIN t_xxxx AS f ON r.id = f.id "+ " LEFT JOIN t_xxxxxxxx AS t ON f.flow_id = t.id "+ " ${ew.customSqlSegment}")XxxxxxDTO getListByConditions(@Param("ew") Wrapper wrapper); }

解读: 第一个方法 getListPageByConditions 的分页方法需要我们将 mybatis-plus 的分页对象作为入参传入,外面调用时记得指定分页的当前页码以及页容量。

其他的条件可以通过 queryWrapper 对象传入。 ew.customSqlSegment: ew 为别名 用于识别wrapper 对象,customSqlSegment 为queryWrapper 中的 方法 在这里插入图片描述 customSqlSegment 应该是用于获取queryWrapper 构建完成的 SQL 语句,所以在实际queryWrapper 时指定的列名也要用 表别名之类的指定才行 类似于: 在这里插入图片描述 这里查询出的字段名可以和对应实体定义的属性名一致即可,最终返回时会自动匹配列名。

例如上面查询了 secret_name 但是实体中我定义的是这样

@TableField(value = "secret_name")private String secretName;

那么返回的自定义类中也使用 secretName 即可。

其他内容后续不定期继续加入,都在同一专题下



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3