今天刷视频的时候看到说判断是否存在使用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;elsereturn 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);}@Overridepublic 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 {@Overridepublic 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 {@Beanpublic 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 {@Autowiredprivate 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测试一下是不是能用。还是不错的。大家互相学习一下。
上一篇:JS表达式完全攻略