今天刷视频的时候看到说判断是否存在使用select 1 from table where *** limit 1这种语句要比,select count 好。所以我看一下mybatis-plus的BaseMapper中的exists方法,发现也是用的select count来判断的
- default boolean exists(Wrapper
queryWrapper) { - Long count = this.selectCount(queryWrapper);
- return null != count && count > 0L;
- }
好吧,我们自己来写一个吧。
一、首先写一个接口继承BaseMapper,添加一个select1limit1(Wrapper)方法如下:
- package com.chhuang.core.mapper;
-
- import com.baomidou.mybatisplus.core.conditions.Wrapper;
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import com.baomidou.mybatisplus.core.toolkit.Constants;
- import org.apache.ibatis.annotations.Param;
-
- /**
- * @ClassName InterfaceMapper
- * @Description Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
- * @Author Darren Huang
- * @Date 2022/11/23 22:56
- * @Version 1.0
- */
- public interface InterfaceMapper
extends BaseMapper { - /**
- * 根据 Wrapper 条件,判断是否存在记录,存在返回1,不存在为null
- *
- * @param queryWrapper 实体对象封装操作类
- * @return 是否存在记录
- */
- Integer select1Limit1(@Param(Constants.WRAPPER) Wrapper
queryWrapper) ; -
- /**
- * 根据 Wrapper 条件,判断是否存在记录, 存在true,不存在false
- * @param queryWrapper
- * @return
- */
- default boolean exists(Wrapper
queryWrapper) { - if(select1Limit1(queryWrapper)==null)
- return false;
- else
- return true;
- }
- }
注意:一定要加"@Param(Constants.WRAPPER)",不然运行时会报找不到ew的异常。
二、接下来,学习mybatis-plus的原码,写一下select1limi1的方法类和sql语句的枚举。
- package com.chhuang.core.method;
-
- import com.baomidou.mybatisplus.core.injector.AbstractMethod;
- import com.baomidou.mybatisplus.core.metadata.TableInfo;
- import com.baomidou.mybatisplus.core.toolkit.StringUtils;
- import org.apache.ibatis.mapping.MappedStatement;
- import org.apache.ibatis.mapping.SqlSource;
-
- /**
- * @ClassName IsExist
- * @Description 根据条件判断是否存在
- * @Author Darren Huang
- * @Date 2022/11/23 23:26
- * @Version 1.0
- */
- public class Select1Limit1 extends AbstractMethod {
-
- public Select1Limit1() {
- super(ChSqlMethod.SELECT1_LIMIT1.getMethod());
- }
-
- /**
- * @param name 方法名
- * @since 3.5.0
- */
- public Select1Limit1(String name) {
- super(name);
- }
-
- @Override
- public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
- ChSqlMethod sqlMethod = ChSqlMethod.SELECT1_LIMIT1;
- String sql = String.format(sqlMethod.getSql(), sqlFirst(), tableInfo.getTableName(),
- sqlWhereEntityWrapper(true, tableInfo), sqlComment());
- SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
- return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Integer.class);
- }
-
- public String getMethod(ChSqlMethod sqlMethod) {
- return StringUtils.isBlank(methodName) ? sqlMethod.getMethod() : this.methodName;
- }
- }
- package com.chhuang.core.method;
- /**
- * @ClassName ChSqlMethod
- * @Description 支持sql方法
- * @Author Darren Huang
- * @Date 2022/11/23 23:28
- * @Version 1.0
- */
-
- public enum ChSqlMethod {
-
- SELECT1_LIMIT1("select1Limit1", "查询是否存在满足条件记录", "");
-
- private final String method;
- private final String desc;
- private final String sql;
-
- ChSqlMethod(String method, String desc, String sql) {
- this.method = method;
- this.desc = desc;
- this.sql = sql;
- }
-
- public String getMethod() {
- return method;
- }
-
- public String getDesc() {
- return desc;
- }
-
- public String getSql() {
- return sql;
- }
- }
当然可以不用这么麻烦可以直接把sql写到Select1limi1类里去,这里是为了学习一下mybatis-plus。
三、现在就需要自己写一个sql注入器了,不然mapper里的select1limit1方法也不知道自己的实现是Select1limi1这个方法。
- package com.chhuang.core.injector;
-
- import com.baomidou.mybatisplus.core.injector.AbstractMethod;
- import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
- import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
- import com.baomidou.mybatisplus.core.injector.methods.*;
- import com.baomidou.mybatisplus.core.metadata.TableInfo;
- import com.chhuang.core.method.Select1Limit1;
-
- import java.util.List;
- import java.util.stream.Stream;
-
- import static java.util.stream.Collectors.toList;
-
- /**
- * @ClassName ChSqlInjector
- * @Description 实现SqlInjector
- * @Author Darren Huang
- * @Date 2022/11/24 0:31
- * @Version 1.0
- */
- public class ChSqlInjector extends DefaultSqlInjector {
-
- @Override
- public List
getMethodList(Class> mapperClass, TableInfo tableInfo) { - List
methodList = super.getMethodList(mapperClass, tableInfo); - methodList.add(new Select1Limit1());
- return methodList;
-
- // Stream.Builder
builder = Stream.builder() - // .add(new Select1Limit1());
- // return builder.build().collect(toList());
- }
- }
四、现在需要把sql注入器,添加到springboot的配置中,这样就可以在springboot项目中使用自己定义的接口InterfaceMapper了。
- package com.chhuang.config;
-
- import com.chhuang.core.injector.ChSqlInjector;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * @ClassName SqlInjectorConfig
- * @Description 配置sql注入器
- * @Author Darren Huang
- * @Date 2022/11/24 0:40
- * @Version 1.0
- */
-
- @Configuration
- public class SqlInjectorConfig {
-
- @Bean
- public ChSqlInjector sqlInjector(){
- return new ChSqlInjector();
- }
- }
五、最后,我们再自定义一个service接口,我这里叫InterfaceService,把自己数据库表实例对象对应的的mapper实现BaseMapper改成实现InterfaceMapper,把对应的service接口改为实现我们自定义的InterfaceService接口。
- package com.chhuang.core.service;
-
- import com.baomidou.mybatisplus.core.conditions.Wrapper;
- import com.baomidou.mybatisplus.extension.service.IService;
-
- /**
- * @ClassName InterfaceService
- * @Description 又一个顶级 Service
- * @Author Darren Huang
- * @Date 2022/11/24 0:10
- * @Version 1.0
- */
- public interface InterfaceService
extends IService { -
- /**
- * 根据 Wrapper 条件,判断是否存在记录, 存在true,不存在false
- * @param queryWrapper
- * @return
- */
- default boolean exists(Wrapper
queryWrapper) { - return getBaseMapper().exists(queryWrapper);
- }
- }
上面都是需要封装的代码,比如可以放到叫core的module中,下面自己的业务代码:
- package com.chhuang.mapper;
-
- import com.chhuang.core.mapper.InterfaceMapper;
- import com.chhuang.model.ChUser;
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import org.apache.ibatis.annotations.Mapper;
- import org.springframework.stereotype.Repository;
-
- /**
- * @ClassName ChUserMapper
- * @Description 表数据库访问层(ChUserMapper)
- * @Author Darren Huang
- * @Date 2022-11-19 01:12:42
- * @Version 1.0
- */
- @Mapper
- @Repository
- public interface ChUserMapper extends InterfaceMapper
{ -
- }
-
- package com.chhuang.service;
-
-
- import com.chhuang.core.service.InterfaceService;
- import com.chhuang.model.ChUser;
- import com.chhuang.mapper.ChUserMapper;
- import com.baomidou.mybatisplus.extension.service.IService;
-
- /**
- * @ClassName ChUserService
- * @Description ch_user表服务层(ChUserService)
- * @Author Darren Huang
- * @Date 2022-11-19 01:13:03
- * @Version 1.0
- */
- public interface ChUserService extends InterfaceService
{ -
- }
- package com.chhuang.service.impl;
-
- import com.chhuang.model.ChUser;
- import com.chhuang.mapper.ChUserMapper;
- import com.chhuang.service.ChUserService;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
-
- /**
- * @ClassName ChUserServiceImpl
- * @Description ch_user表服务层实现类(ChUserServiceImpl)
- * @Author Darren Huang
- * @Date 2022-11-19 18:56:32
- * @Version 1.0
- */
- @Transactional
- @Service("chUserService")
- public class ChUserServiceImpl extends ServiceImpl
implements ChUserService { - @Autowired
- private ChUserMapper chUserMapper;
- }
- @GetMapping("/test")
- @ApiOperation(value = "test", notes = "test")
- public boolean test(String name){
- log.info("ID存在{}",chUserService.exists(new QueryWrapper
().eq("user_id", name))); - return chUserService.exists(new LambdaQueryWrapper
().eq(ChUser::getUsername, name)); - }
在controller测试一下是不是能用。还是不错的。大家互相学习一下。