窥探系列之Mybatis-plus BaseMapper实现

我们知道,mybatisplus的BaseMapper接口中提供了一些如updateById的方法,框架本身已经实现了这些CRUD功能,基本的CRUD我们就没必要写sql,直接使用java语法就能对数据进行操控,很方便。那么这些功能是如何被实现的呢?这是我研读源码的动机
在这里插入图片描述

关键类

  1. AbstractSqlInjector及其子类DefaultSqlInjector
  2. AbstractMethod及其子类
  3. SqlMethod
  4. mapper代理:MybatisMapperProxy
  5. Configuration

MybatisMapperProxy 以代理类作为切入点

BaseMapper是一个接口,里面的方法都是抽象方法,所以很明显框架是通过代理的方式去实现这些抽象方法。

public class MybatisMapperProxy<T> implements InvocationHandler, Serializable {

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            if (Object.class.equals(method.getDeclaringClass())) {
                return method.invoke(this, args);
            } else if (method.isDefault()) {
                return invokeDefaultMethod(proxy, method, args);
            }
        } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
        }
        final MybatisMapperMethod mapperMethod = cachedMapperMethod(method);
        return mapperMethod.execute(sqlSession, args);
    }
    ......省略
}

这段代码是来自 MyBatis 库中的 MapperProxy 类,用于为 Mapper 接口创建动态代理实例,通过该实例调用实际的 SQL 语句。

invoke 方法会在动态代理实例上调用,当 Mapper 接口中的方法被调用时,该方法将被执行。其中,proxy 参数是动态代理实例本身,method 参数是被调用的方法,args 参数包含传递给方法的参数。

第一个 if 语句检查方法是否属于 Object 类。如果是,则在 MapperProxy 实例本身上调用该方法,并将 args 数组作为参数传递。

第二个 else if 语句检查方法是否为默认方法,这是在 Java 8 中引入的。如果是默认方法,则使用 invokeDefaultMethod 方法调用它,传递 proxy、method 和 args 参数。

如果方法既不属于 Object 类也不是默认方法,则使用 method 参数从缓存中获取一个 MybatisMapperMethod 实例,并在其上调用 execute 方法,传递 sqlSession 和 args 参数。execute 方法负责使用 SqlSession 对象执行实际的 SQL 语句,并返回结果。

可以看到,BaseMapper的抽象方法的实现是在这两步:
final MybatisMapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);


MybatisMapperMethod#execute主要是一下逻辑
  1. 判断command类型,可以看到类型包括INSERT、UPDATE等;
  2. 转化参数;
  3. command.getName()作为入参执行sqlSession对应方法;
public class MybatisMapperMethod {
    private final MapperMethod.SqlCommand command;
    private final MapperMethod.MethodSignature method;

    public MybatisMapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
        this.command = new MapperMethod.SqlCommand(config, mapperInterface, method);
        this.method = new MapperMethod.MethodSignature(config, mapperInterface, method);
    }

    public Object execute(SqlSession sqlSession, Object[] args) {
        Object result;
        switch (command.getType()) {
            case INSERT: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.insert(command.getName(), param));
                break;
            }
            case UPDATE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.update(command.getName(), param));
                break;
            }
            case DELETE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.delete(command.getName(), param));
                break;
            }
            case SELECT:
......
    }
}

接下来,要看一下command的type和name具体是什么?

可以看到,将mapper的接口类和方法作为入参,调用resolveMappedStatement方法得到一个
MappedStatement 对象,取出id作为command的name,sqlCommandType作为command的type;

在resolveMappedStatement中,String statementId = mapperInterface.getName() + "." + methodName;将mapper的完全限定名和调用方法名拼接起来,作为statementId;

configuration.getMappedStatement(statementId);然后根据statementId从configuration对象中获取到对应的MappedStatement对象;

另外,这里引申出了一个关键的类com.baomidou.mybatisplus.core.MybatisConfiguration,很显然MybatisConfiguration对象维护了MappedStatement对象集合,所以要想弄明白对应sqlCommandType,需要研究MappedStatement对象如何被加载到MybatisConfiguration中;

  public static class SqlCommand {

    private final String name;
    private final SqlCommandType type;

    public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
      final String methodName = method.getName();
      final Class<?> declaringClass = method.getDeclaringClass();
      MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
          configuration);
      if (ms == null) {
        if (method.getAnnotation(Flush.class) != null) {
          name = null;
          type = SqlCommandType.FLUSH;
        } else {
          throw new BindingException("Invalid bound statement (not found): "
              + mapperInterface.getName() + "." + methodName);
        }
      } else {
        name = ms.getId();
        type = ms.getSqlCommandType();
        if (type == SqlCommandType.UNKNOWN) {
          throw new BindingException("Unknown execution method for: " + name);
        }
      }
    }
# 类:org.apache.ibatis.binding.MapperMethod
    private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
        Class<?> declaringClass, Configuration configuration) {
      String statementId = mapperInterface.getName() + "." + methodName;
      if (configuration.hasStatement(statementId)) {
        return configuration.getMappedStatement(statementId);
      } else if (mapperInterface.equals(declaringClass)) {
        return null;
      }
      for (Class<?> superInterface : mapperInterface.getInterfaces()) {
        if (declaringClass.isAssignableFrom(superInterface)) {
          MappedStatement ms = resolveMappedStatement(superInterface, methodName,
              declaringClass, configuration);
          if (ms != null) {
            return ms;
          }
        }
      }
      return null;
    }

以insert为例,继续往下看sqlSession.insert做了哪些操作?

  1. 根据statementId,从configuration对象中获取到对应的MappedStatement,然后调用执行器执行MappedStatement对象;
  2. MybatisSimpleExecutor#doUpdate 中调用configuration对象的newStatementHandler方法创建一个StatementHandler 对象;
  3. prepareStatement(handler, ms.getStatementLog(), false) 生成PreparedStatement对象;
  4. ps.execute()执行sql;
# org.apache.ibatis.session.defaults.DefaultSqlSession

  public int insert(String statement, Object parameter) {
    return update(statement, parameter);
  }
 
  public int update(String statement, Object parameter) {
    try {
      dirty = true;
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
public class MybatisSimpleExecutor extends AbstractBaseExecutor {

    public MybatisSimpleExecutor(Configuration configuration, Transaction transaction) {
        super(configuration, transaction);
    }


    @Override
    public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
        Statement stmt = null;
        try {
            Configuration configuration = ms.getConfiguration();
            StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
            stmt = prepareStatement(handler, ms.getStatementLog(), false);
            return stmt == null ? 0 : handler.update(stmt);
        } finally {
            closeStatement(stmt);
        }
    }
    
    private Statement prepareStatement(StatementHandler handler, Log statementLog, boolean isCursor) throws SQLException {
        Statement stmt;
        Connection connection = getConnection(statementLog);
        stmt = handler.prepare(connection, transaction.getTimeout());
        //游标不支持返回null.
        if (stmt == null && !isCursor) {
            return null;
        } else {
            handler.parameterize(stmt);
            return stmt;
        }
    }
    
......

public class PreparedStatementHandler extends BaseStatementHandler {

  @Override
  public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
    return rows;
  }
......


PreparedStatement对象的创建

  1. boundSql.getSql()获取sql模版;
  2. connection.prepareStatement创建PreparedStatement对象;
  3. BaseStatementHandler#BaseStatementHandler中,获取BoundSql对象;
# org.apache.ibatis.executor.statement.PreparedStatementHandler

  protected Statement instantiateStatement(Connection connection) throws SQLException {
    String sql = boundSql.getSql();
    if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
      String[] keyColumnNames = mappedStatement.getKeyColumns();
      if (keyColumnNames == null) {
        return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
      } else {
        return connection.prepareStatement(sql, keyColumnNames);
      }
    } else if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
      return connection.prepareStatement(sql);
    } else {
      return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
    }
  }
# org.apache.ibatis.executor.statement.BaseStatementHandler

  protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    this.configuration = mappedStatement.getConfiguration();
    this.executor = executor;
    this.mappedStatement = mappedStatement;
    this.rowBounds = rowBounds;

    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
    this.objectFactory = configuration.getObjectFactory();

    if (boundSql == null) { // issue #435, get the key before calculating the statement
      generateKeys(parameterObject);
      boundSql = mappedStatement.getBoundSql(parameterObject);
    }

    this.boundSql = boundSql;

    this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
    this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
  }

注入抽象方法

事实:
mybatis的mapper类不能有重载方法Mapper类中存在名称相同的方法重载报错,所以生成的MappedStatement的id只由完全类限定名 + 方法名构成。

  1. com.baomidou.mybatisplus.core.injector.AbstractSqlInjector#inspectInject
  2. com.baomidou.mybatisplus.core.injector.AbstractMethod#injectMappedStatement

AbstractSqlInjector#inspectInject 往Mapper类中自动注入自定义方法

# com.baomidou.mybatisplus.core.injector.AbstractSqlInjector#inspectInject

    @Override
    public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
        Class<?> modelClass = extractModelClass(mapperClass);
        if (modelClass != null) {
            String className = mapperClass.toString();
            Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
            if (!mapperRegistryCache.contains(className)) {
                List<AbstractMethod> methodList = this.getMethodList(mapperClass);
                if (CollectionUtils.isNotEmpty(methodList)) {
                    TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
                    // 循环注入自定义方法
                    methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
                } else {
                    logger.debug(mapperClass.toString() + ", No effective injection method was found.");
                }
                mapperRegistryCache.add(className);
            }
        }
    }

自定义方法列表

public class DefaultSqlInjector extends AbstractSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        return Stream.of(
            new Insert(),
            new Delete(),
            new DeleteByMap(),
            new DeleteById(),
            new DeleteBatchByIds(),
            new Update(),
            new UpdateById(),
            new SelectById(),
            new SelectBatchByIds(),
            new SelectByMap(),
            new SelectOne(),
            new SelectCount(),
            new SelectMaps(),
            new SelectMapsPage(),
            new SelectObjs(),
            new SelectList(),
            new SelectPage()
        ).collect(toList());
    }
}

以deleteById为例

  1. SqlMethod保存了一些Sql模版,如DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>\nDELETE FROM %s WHERE %s=#{%s}\n</script>")

  2. sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(), tableInfo.getKeyProperty());TableInfo对象中取出表名称、主键列名名称以及主键属性名填充Sql模版;

  3. 如何理解SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class)

    这段代码是 MyBatis 中用于创建 SqlSource 对象的代码。SqlSource 对象是用于封装 SQL 语句的对象,其中包含了 SQL 语句和参数映射信息等元数据。

    在 MyBatis 中,可以使用不同的语言驱动(Language Driver)来支持不同的 SQL 语言,例如 XML、注解或者纯文本等。languageDriver.createSqlSource() 方法就是用于创建相应语言的 SqlSource 对象的。

    具体来说,languageDriver 是一个实现了 LanguageDriver 接口的类的实例,它负责解析 SQL 语句并生成对应的 SqlSource 对象。createSqlSource() 方法接受三个参数:

    • configurationConfiguration 对象,表示 MyBatis 的全局配置信息。
    • sql:表示 SQL 语句的字符串。
    • parameterType:表示 SQL 语句的参数类型,在 SQL 语句中使用 #{} 占位符表示,可以是任意 Java 类型。

    执行该方法后,会根据给定的 SQL 语句和参数类型,使用对应的语言驱动解析 SQL 语句并生成 SqlSource 对象,最后返回该对象。该对象可以被用于执行 SQL 语句,例如在 MappedStatement 中使用。

    在 MyBatis 中,语言驱动(Language Driver)是一个接口,用于支持不同的 SQL 语言,例如 XML、注解或纯文本等。每种 SQL 语言都需要一个对应的语言驱动来解析和处理,从而生成对应的 SqlSource 对象。

    LanguageDriver 接口中定义了两个方法:

    • SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType):用于创建 SqlSource 对象。
    • ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql):用于创建参数处理器,用于处理 SQL 语句中的参数。

    在 MyBatis 中,有三种默认的语言驱动:

    • XMLLanguageDriver:用于解析 XML 格式的 SQL 语句。
    • AnnotationLanguageDriver:用于解析注解格式的 SQL 语句。
    • RawLanguageDriver:用于解析纯文本格式的 SQL 语句。

    可以通过在 Mapper 接口上添加 @Lang 注解来指定使用的语言驱动,例如:

    @Lang(XMLLanguageDriver.class) // 指定使用 XML 格式的 SQL 语句 public interface UserMapper {
        // ... }   
    

    在自定义语言驱动时,需要实现 LanguageDriver 接口并实现其中的方法,从而实现对新格式的 SQL 语句的支持。通常需要重写 createSqlSource() 方法和 createParameterHandler() 方法,分别用于解析 SQL 语句和处理参数。自定义的语言驱动可以通过在 MyBatis 的配置文件中配置来启用。

public class DeleteById extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String sql;
        SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_BY_ID;
        if (tableInfo.isLogicDelete()) {
            sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlLogicSet(tableInfo),
                tableInfo.getKeyColumn(), tableInfo.getKeyProperty(),
                tableInfo.getLogicDeleteSql(true, false));
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
            return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
        } else {
            sqlMethod = SqlMethod.DELETE_BY_ID;
            sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(),
                tableInfo.getKeyProperty());
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
            return this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
        }
    }
}

XMLLanguageDriver 是 MyBatis 中默认的语言驱动,用于解析 XML 格式的 SQL 语句。

在 MyBatis 中,可以通过在 Mapper 接口对应的 XML 文件中编写 SQL 语句,从而实现数据访问操作。例如,在 UserMapper.xml 文件中,可以定义一个名为 deleteById 的 SQL 语句:

<script>
	DELETE FROM %s WHERE %s=#{%s}
</script>

在上述 XML 文件中, 元素表示要执行一个删除操作,id 属性指定了该操作的 ID,即 deleteById,#{id} 表示 SQL 语句中的参数。

当使用 XMLLanguageDriver 作为语言驱动时,MyBatis 会解析 XML 文件中的 SQL 语句,并将其转换为对应的 SqlSource 对象,从而实现数据访问操作。

需要注意的是,虽然 XMLLanguageDriver 是 MyBatis 的默认语言驱动之一,但并不是所有的 SQL 方言都可以使用 XML 格式的 SQL 语句来表示。如果需要使用非默认的语言驱动来支持某种 SQL 方言,可以自定义语言驱动并在 MyBatis 的配置文件中进行配置。

  1. this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);这段代码调用了 MapperBuilderAssistant 的 addDeleteMappedStatement() 方法,用于向 MyBatis 的配置对象中添加一个映射语句(MappedStatement)。

    MapperBuilderAssistant 是 MyBatis 中用于辅助构建 Mapper 映射器(Mapper)的类,是向 MyBatis 中添加 Mapper 映射器的关键类之一 。addMappedStatement() 是 MapperBuilderAssistant 类中的一个方法,用于向 MyBatis 的配置对象中添加一个映射语句(MappedStatement)。
    该方法的参数比较多,主要包括:

    1. id:映射语句的唯一标识符,格式为 namespace.<select|insert|update|delete>Id,其中 是 Mapper 接口的命名空间,<select|insert|update|delete>Id 是映射语句的名称,例如 com.example.dao.UserMapper.selectUserById。
    2. sqlSource:封装了 SQL 语句和参数类型的 SqlSource 对象。
    3. statementType:SQL 语句的执行类型(STATEMENT 或 PREPARED)。
    4. sqlCommandType:SQL 语句的类型(SELECT、INSERT、UPDATE 或 DELETE)。
    5. fetchSize:结果集的大小。
    6. timeout:SQL 语句的超时时间。
    7. parameterMap:参数映射器的唯一标识符。
    8. parameterType:参数类型的 Class 对象。
    9. resultMap:结果映射器的唯一标识符。
    10. resultType:结果类型的 Class 对象。
    11. resultSetType:结果集的类型(FORWARD_ONLY、SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE)。
    12. flushCache:是否清空缓存。
    13. useCache:是否使用缓存。
    14. resultOrdered:是否按照结果集顺序返回结果。
    15. keyGenerator:主键生成器。
    16. keyProperty:主键属性。
    17. keyColumn:主键列名。
    18. databaseId:数据库标识符。
    19. lang:语言驱动器。
    20. resultSets:多结果集配置。

    通过调用 addMappedStatement() 方法,我们可以向 MyBatis 的配置对象中添加一个映射语句,从而使得 MyBatis 能够根据该映射语句的配置信息执行相应的 SQL 语句,并将执行结果映射成 Java 对象。

    com.baomidou.mybatisplus.core.injector.AbstractMethod#addMappedStatement
    
       protected MappedStatement addMappedStatement(Class<?> mapperClass, String id, SqlSource sqlSource,
                                                 SqlCommandType sqlCommandType, Class<?> parameterType,
                                                 String resultMap, Class<?> resultType, KeyGenerator keyGenerator,
                                                 String keyProperty, String keyColumn) {
        String statementName = mapperClass.getName() + DOT + id;
        if (hasMappedStatement(statementName)) {
            logger.warn(LEFT_SQ_BRACKET + statementName + "] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [" + getClass() + RIGHT_SQ_BRACKET);
            return null;
        }
        /* 缓存逻辑处理 */
        boolean isSelect = false;
        if (sqlCommandType == SqlCommandType.SELECT) {
            isSelect = true;
        }
        return builderAssistant.addMappedStatement(id, sqlSource, StatementType.PREPARED, sqlCommandType,
            null, null, null, parameterType, resultMap, resultType,
            null, !isSelect, isSelect, false, keyGenerator, keyProperty, keyColumn,
            configuration.getDatabaseId(), languageDriver, null);
    }
    
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Mybatis-Plus BaseMapper 是一个基础的 Mapper 接口,提供了一些常用的 CRUD 操作方法,可以让我们快速地进行数据库操作。使用 BaseMapper 需要继承它,然后就可以直接使用其的方法了。同时,Mybatis-Plus 还提供了很多其他的功能,比如自动生成代码、分页查询、条件构造器等等,可以大大提高开发效率。 ### 回答2: Mybatis-plus是Mybatis的增强工具包,其包含了基于Mybatis的BasemapperBasemapper 是一个范型,提供了一组基础的CRUD操作,可以让我们在开发过程避免大量的重复代码,尤其是针对单表的操作。下面详细介绍Basemapper的使用方法: 1. 引入依赖:在pom.xml文件添加如下依赖 ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> ``` 2. 继承BaseMapper:创建DAO层接口,继承BaseMapper<T>,T表示实体 ```java public interface UserMapper extends BaseMapper<User> { } ``` 3. 接口调用:在Service注入mapper,就可以使用了。以下是常用方法: - 插入数据 ```java int result = userMapper.insert(user); ``` - 根据ID删除 ```java int result = userMapper.deleteById(1); ``` - 更新数据 ```java User user = new User(); user.setId(1); user.setNickname("test"); int result = userMapper.updateById(user); ``` - 根据ID查询 ```java User user = userMapper.selectById(1); ``` - 分页查询 ```java Page<User> page = new Page<>(1, 5); QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.lambda().gt(User::getId, 0); IPage<User> iPage = userMapper.selectPage(page, wrapper); ``` 以上就是Mybatis-plus Basemapper 的基本使用方法,大大简化了对单表的CRUD操作。而且Mybatis-plus还提供了更多的查询、更新、删除、分页等高级功能,可以根据具体需求自行选择使用。 ### 回答3: Mybatis-Plus是基于Mybatis的增强框架,它提供了很多良好的功能拓展,其mybatis-plus basemapper是其的一个模块。它实现Mybatis-Plus框架的通用Mapper接口,优化了数据访问,提高了代码效率。 Mybatis-Plusbasemapper模块提供了许多注解和方法,最基本的CRUD操作都可以通过这个模块完成。在使用mybatis-plus basemapper时需要在Mapper接口使用特殊的泛型,并且需要使用具有该泛型的Mapper接口进行扩展。例如: ``` public interface UserMapper extends BaseMapper<User> { } ``` 通过继承BaseMapper<User>,UserMapper可以继承到BaseMapper定义的基本的CRUD方法,也可以使用注解和查询构建器等方式执行高级查询。以下是基本的使用方法: 1.添加依赖 在项目的pom.xml文件添加mybatis-plus-boot-starter的依赖: ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.1</version> </dependency> ``` 2.配置文件 在应用程序的配置文件添加以下配置信息: ``` spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8&serverTimezone=GMT%2B8 username: root password: root mybatis-plus: configuration: map-underscore-to-camel-case: true ``` 3.实体定义 定义需要进行CRUD操作的实体,例如User: ``` @Data public class User { private Long id; private String name; private Integer age; private String email; } ``` 4.Mapper接口定义 定义UserMapper,并继承BaseMapper<User>: ``` public interface UserMapper extends BaseMapper<User> { } ``` 5.Service层定义 定义UserService,使用@Autowired注解装配UserMapper接口: ``` @Service public class UserService { @Autowired UserMapper userMapper; public void addUser(User user){ userMapper.insert(user); } public void updateUser(User user){ userMapper.updateById(user); } public User getUserById(Long id){ return userMapper.selectById(id); } public void deleteUserById(Long id){ userMapper.deleteById(id); } public List<User> getAllUser(){ return userMapper.selectList(null); } } ``` 上述方法都是一些基本的CRUD操作,这里只是展示了一小部分。 总之,Mybatis-PlusbasemapperMybatis-Plus框架的一个重要部分,它提供了很多方便和高效的数据访问方法,极大地简化了数据库操作代码。开发人员可以通过托管一些基本的数据操作来实现高效的数据访问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值