• 像mybatis-plus一样自定义封装BaseMapper方法


    今天刷视频的时候看到说判断是否存在使用select 1 from table where *** limit 1这种语句要比,select count 好。所以我看一下mybatis-plus的BaseMapper中的exists方法,发现也是用的select count来判断的

    1. default boolean exists(Wrapper queryWrapper) {
    2. Long count = this.selectCount(queryWrapper);
    3. return null != count && count > 0L;
    4. }

    好吧,我们自己来写一个吧。

    一、首先写一个接口继承BaseMapper,添加一个select1limit1(Wrapper)方法如下:

    1. package com.chhuang.core.mapper;
    2. import com.baomidou.mybatisplus.core.conditions.Wrapper;
    3. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    4. import com.baomidou.mybatisplus.core.toolkit.Constants;
    5. import org.apache.ibatis.annotations.Param;
    6. /**
    7. * @ClassName InterfaceMapper
    8. * @Description Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
    9. * @Author Darren Huang
    10. * @Date 2022/11/23 22:56
    11. * @Version 1.0
    12. */
    13. public interface InterfaceMapper extends BaseMapper {
    14. /**
    15. * 根据 Wrapper 条件,判断是否存在记录,存在返回1,不存在为null
    16. *
    17. * @param queryWrapper 实体对象封装操作类
    18. * @return 是否存在记录
    19. */
    20. Integer select1Limit1(@Param(Constants.WRAPPER) Wrapper queryWrapper);
    21. /**
    22. * 根据 Wrapper 条件,判断是否存在记录, 存在true,不存在false
    23. * @param queryWrapper
    24. * @return
    25. */
    26. default boolean exists(Wrapper queryWrapper){
    27. if(select1Limit1(queryWrapper)==null)
    28. return false;
    29. else
    30. return true;
    31. }
    32. }

    注意:一定要加"@Param(Constants.WRAPPER)",不然运行时会报找不到ew的异常。

    二、接下来,学习mybatis-plus的原码,写一下select1limi1的方法类和sql语句的枚举。

    1. package com.chhuang.core.method;
    2. import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    3. import com.baomidou.mybatisplus.core.metadata.TableInfo;
    4. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    5. import org.apache.ibatis.mapping.MappedStatement;
    6. import org.apache.ibatis.mapping.SqlSource;
    7. /**
    8. * @ClassName IsExist
    9. * @Description 根据条件判断是否存在
    10. * @Author Darren Huang
    11. * @Date 2022/11/23 23:26
    12. * @Version 1.0
    13. */
    14. public class Select1Limit1 extends AbstractMethod {
    15. public Select1Limit1() {
    16. super(ChSqlMethod.SELECT1_LIMIT1.getMethod());
    17. }
    18. /**
    19. * @param name 方法名
    20. * @since 3.5.0
    21. */
    22. public Select1Limit1(String name) {
    23. super(name);
    24. }
    25. @Override
    26. public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) {
    27. ChSqlMethod sqlMethod = ChSqlMethod.SELECT1_LIMIT1;
    28. String sql = String.format(sqlMethod.getSql(), sqlFirst(), tableInfo.getTableName(),
    29. sqlWhereEntityWrapper(true, tableInfo), sqlComment());
    30. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
    31. return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Integer.class);
    32. }
    33. public String getMethod(ChSqlMethod sqlMethod) {
    34. return StringUtils.isBlank(methodName) ? sqlMethod.getMethod() : this.methodName;
    35. }
    36. }
    1. package com.chhuang.core.method;
    2. /**
    3. * @ClassName ChSqlMethod
    4. * @Description 支持sql方法
    5. * @Author Darren Huang
    6. * @Date 2022/11/23 23:28
    7. * @Version 1.0
    8. */
    9. public enum ChSqlMethod {
    10. SELECT1_LIMIT1("select1Limit1", "查询是否存在满足条件记录", "");
    11. private final String method;
    12. private final String desc;
    13. private final String sql;
    14. ChSqlMethod(String method, String desc, String sql) {
    15. this.method = method;
    16. this.desc = desc;
    17. this.sql = sql;
    18. }
    19. public String getMethod() {
    20. return method;
    21. }
    22. public String getDesc() {
    23. return desc;
    24. }
    25. public String getSql() {
    26. return sql;
    27. }
    28. }

    当然可以不用这么麻烦可以直接把sql写到Select1limi1类里去,这里是为了学习一下mybatis-plus。

    三、现在就需要自己写一个sql注入器了,不然mapper里的select1limit1方法也不知道自己的实现是Select1limi1这个方法。

    1. package com.chhuang.core.injector;
    2. import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    3. import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
    4. import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
    5. import com.baomidou.mybatisplus.core.injector.methods.*;
    6. import com.baomidou.mybatisplus.core.metadata.TableInfo;
    7. import com.chhuang.core.method.Select1Limit1;
    8. import java.util.List;
    9. import java.util.stream.Stream;
    10. import static java.util.stream.Collectors.toList;
    11. /**
    12. * @ClassName ChSqlInjector
    13. * @Description 实现SqlInjector
    14. * @Author Darren Huang
    15. * @Date 2022/11/24 0:31
    16. * @Version 1.0
    17. */
    18. public class ChSqlInjector extends DefaultSqlInjector {
    19. @Override
    20. public List getMethodList(Class mapperClass, TableInfo tableInfo) {
    21. List methodList = super.getMethodList(mapperClass, tableInfo);
    22. methodList.add(new Select1Limit1());
    23. return methodList;
    24. // Stream.Builder builder = Stream.builder()
    25. // .add(new Select1Limit1());
    26. // return builder.build().collect(toList());
    27. }
    28. }

    四、现在需要把sql注入器,添加到springboot的配置中,这样就可以在springboot项目中使用自己定义的接口InterfaceMapper了。

    1. package com.chhuang.config;
    2. import com.chhuang.core.injector.ChSqlInjector;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. /**
    6. * @ClassName SqlInjectorConfig
    7. * @Description 配置sql注入器
    8. * @Author Darren Huang
    9. * @Date 2022/11/24 0:40
    10. * @Version 1.0
    11. */
    12. @Configuration
    13. public class SqlInjectorConfig {
    14. @Bean
    15. public ChSqlInjector sqlInjector(){
    16. return new ChSqlInjector();
    17. }
    18. }

    五、最后,我们再自定义一个service接口,我这里叫InterfaceService,把自己数据库表实例对象对应的的mapper实现BaseMapper改成实现InterfaceMapper,把对应的service接口改为实现我们自定义的InterfaceService接口。

    1. package com.chhuang.core.service;
    2. import com.baomidou.mybatisplus.core.conditions.Wrapper;
    3. import com.baomidou.mybatisplus.extension.service.IService;
    4. /**
    5. * @ClassName InterfaceService
    6. * @Description 又一个顶级 Service
    7. * @Author Darren Huang
    8. * @Date 2022/11/24 0:10
    9. * @Version 1.0
    10. */
    11. public interface InterfaceService extends IService {
    12. /**
    13. * 根据 Wrapper 条件,判断是否存在记录, 存在true,不存在false
    14. * @param queryWrapper
    15. * @return
    16. */
    17. default boolean exists(Wrapper queryWrapper){
    18. return getBaseMapper().exists(queryWrapper);
    19. }
    20. }

    上面都是需要封装的代码,比如可以放到叫core的module中,下面自己的业务代码:

    1. package com.chhuang.mapper;
    2. import com.chhuang.core.mapper.InterfaceMapper;
    3. import com.chhuang.model.ChUser;
    4. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    5. import org.apache.ibatis.annotations.Mapper;
    6. import org.springframework.stereotype.Repository;
    7. /**
    8. * @ClassName ChUserMapper
    9. * @Description 表数据库访问层(ChUserMapper)
    10. * @Author Darren Huang
    11. * @Date 2022-11-19 01:12:42
    12. * @Version 1.0
    13. */
    14. @Mapper
    15. @Repository
    16. public interface ChUserMapper extends InterfaceMapper {
    17. }
    1. package com.chhuang.service;
    2. import com.chhuang.core.service.InterfaceService;
    3. import com.chhuang.model.ChUser;
    4. import com.chhuang.mapper.ChUserMapper;
    5. import com.baomidou.mybatisplus.extension.service.IService;
    6. /**
    7. * @ClassName ChUserService
    8. * @Description ch_user表服务层(ChUserService)
    9. * @Author Darren Huang
    10. * @Date 2022-11-19 01:13:03
    11. * @Version 1.0
    12. */
    13. public interface ChUserService extends InterfaceService {
    14. }
    1. package com.chhuang.service.impl;
    2. import com.chhuang.model.ChUser;
    3. import com.chhuang.mapper.ChUserMapper;
    4. import com.chhuang.service.ChUserService;
    5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Service;
    8. import org.springframework.transaction.annotation.Transactional;
    9. /**
    10. * @ClassName ChUserServiceImpl
    11. * @Description ch_user表服务层实现类(ChUserServiceImpl)
    12. * @Author Darren Huang
    13. * @Date 2022-11-19 18:56:32
    14. * @Version 1.0
    15. */
    16. @Transactional
    17. @Service("chUserService")
    18. public class ChUserServiceImpl extends ServiceImpl implements ChUserService {
    19. @Autowired
    20. private ChUserMapper chUserMapper;
    21. }
    1. @GetMapping("/test")
    2. @ApiOperation(value = "test", notes = "test")
    3. public boolean test(String name){
    4. log.info("ID存在{}",chUserService.exists(new QueryWrapper().eq("user_id", name)));
    5. return chUserService.exists(new LambdaQueryWrapper().eq(ChUser::getUsername, name));
    6. }

    在controller测试一下是不是能用。还是不错的。大家互相学习一下。

  • 相关阅读:
    python的time各种用法
    卷积神经网络创新点思考
    leetcode 1742. 盒子中小球的最大数量
    基于遗传优化算法的TSP问题求解matlab仿真
    Maven第三章:IDEA集成与常见问题
    docker版jxTMS使用指南:使用webSocket
    mysql 5.7 修改密码
    前端 js 之 面向对象(原型、原型链及继承) 06
    众昂矿业:新能源或成萤石最大应用领域
    Unreal 和 Unity 3D 各有什么特点?如何选择?
  • 原文地址:https://blog.csdn.net/ihchenchen/article/details/128011254