MyBatis-Plus 之通用Service

推荐:MyBatis Plus汇总

MyBatis-Plus 之通用Service

首先创建一个数据库表,如下图所示:
在这里插入图片描述

然后创建一个Spring Boot项目,pom.xml和配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.kaven</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
spring:
  application:
    name: mybatis-plus
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: ITkaven@123
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false

server:
  port: 8085

logging:
  level:
    root: warn
    com.kaven.mybatisplus.dao: trace
  pattern:
    console: '%p%m%n'

实体类User:

package com.kaven.mybatisplus.entity;

import com.baomidou.mybatisplus.annotation.SqlCondition;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("user")
@Data
public class User{

    @TableId
    private String id;

    @TableField(value = "username" , condition = SqlCondition.LIKE)
    private String username;

    @TableField("password")
    private String password;

    @TableField(value = "age" , condition = "%s&gt;#{%s}")
    private Integer age;

    /**
     * 使用 @TableField(exist = false) ,表示该字段在数据库中不存在 ,所以不会插入数据库中
     * 使用 transient 、 static 修饰属性也不会插入数据库中
     */
    @TableField(exist = false)
    private String phone;
}

Mapper接口UserMapper:

package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kaven.mybatisplus.entity.User;
import org.springframework.stereotype.Component;


@Component
public interface UserMapper extends BaseMapper<User> {}

启动类:

package com.kaven.mybatisplus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.kaven.mybatisplus.dao")
public class AppRun {
    public static void main(String[] args) {
        SpringApplication.run(AppRun.class , args);
    }
}

@MapperScan(basePackages = "com.kaven.mybatisplus.dao")这个一定要加上。

我们先在数据库中添加几行数据,方便演示。
在这里插入图片描述
想要使用MyBatis-Plus的通用Service,首先我们需要写一个Service,然后继承MyBatis-Plus的通用Service(IService<T>)。

package com.kaven.mybatisplus.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.kaven.mybatisplus.entity.User;

public interface UserService extends IService<User> {}

然后再写一个ServiceImpl并且继承MyBatis-Plus的ServiceImpl<M extends BaseMapper<T>, T>,当然还要实现我们写的Service。

package com.kaven.mybatisplus.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kaven.mybatisplus.dao.UserMapper;
import com.kaven.mybatisplus.entity.User;
import com.kaven.mybatisplus.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper , User> implements UserService {}

这样就可以使用MyBatis-Plus的通用Service了。

主要来看看ServiceImpl<M extends BaseMapper<T>, T>这个类,因为它实现了通用Service的CRUD方法,源码如下:

package com.baomidou.mybatisplus.extension.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
 *
 * @author hubin
 * @since 2018-06-23
 */
@SuppressWarnings("unchecked")
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {

    protected Log log = LogFactory.getLog(getClass());

    @Autowired
    protected M baseMapper;

    @Override
    public M getBaseMapper() {
        return baseMapper;
    }

    protected Class<?> entityClass = currentModelClass();

    protected Class<?> mapperClass = currentMapperClass();

    /**
     * 判断数据库操作是否成功
     *
     * @param result 数据库操作返回影响条数
     * @return boolean
     * @deprecated 3.3.1
     */
    @Deprecated
    protected boolean retBool(Integer result) {
        return SqlHelper.retBool(result);
    }

    protected Class<T> currentMapperClass() {
        return (Class<T>) ReflectionKit.getSuperClassGenericType(getClass(), 0);
    }

    protected Class<T> currentModelClass() {
        return (Class<T>) ReflectionKit.getSuperClassGenericType(getClass(), 1);
    }

    /**
     * 批量操作 SqlSession
     *
     * @deprecated 3.3.0
     */
    @Deprecated
    protected SqlSession sqlSessionBatch() {
        return SqlHelper.sqlSessionBatch(entityClass);
    }

    /**
     * 释放sqlSession
     *
     * @param sqlSession session
     * @deprecated 3.3.0
     */
    @Deprecated
    protected void closeSqlSession(SqlSession sqlSession) {
        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
    }

    /**
     * 获取 SqlStatement
     *
     * @param sqlMethod ignore
     * @return ignore
     * @see #getSqlStatement(SqlMethod)
     * @deprecated 3.4.0
     */
    @Deprecated
    protected String sqlStatement(SqlMethod sqlMethod) {
        return SqlHelper.table(entityClass).getSqlStatement(sqlMethod.getMethod());
    }

    /**
     * 批量插入
     *
     * @param entityList ignore
     * @param batchSize  ignore
     * @return ignore
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
    }

    /**
     * 获取mapperStatementId
     *
     * @param sqlMethod 方法名
     * @return 命名id
     * @since 3.4.0
     */
    protected String getSqlStatement(SqlMethod sqlMethod) {
        return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
    }

    /**
     * TableId 注解存在更新记录,否插入一条记录
     *
     * @param entity 实体对象
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdate(T entity) {
        if (null != entity) {
            TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
            Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
            String keyProperty = tableInfo.getKeyProperty();
            Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
            Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
            return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
        String keyProperty = tableInfo.getKeyProperty();
        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
        return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
            Object idVal = ReflectionKit.getFieldValue(entity, keyProperty);
            return StringUtils.checkValNull(idVal)
                || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
        }, (sqlSession, entity) -> {
            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
            param.put(Constants.ENTITY, entity);
            sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
        return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
            param.put(Constants.ENTITY, entity);
            sqlSession.update(sqlStatement, param);
        });
    }

    @Override
    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
        if (throwEx) {
            return baseMapper.selectOne(queryWrapper);
        }
        return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
    }

    @Override
    public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
        return SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper));
    }

    @Override
    public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
        return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
    }

    /**
     * 执行批量操作
     *
     * @param consumer consumer
     * @since 3.3.0
     * @deprecated 3.3.1 后面我打算移除掉 {@link #executeBatch(Collection, int, BiConsumer)} }.
     */
    @Deprecated
    protected boolean executeBatch(Consumer<SqlSession> consumer) {
        return SqlHelper.executeBatch(this.entityClass, this.log, consumer);
    }

    /**
     * 执行批量操作
     *
     * @param list      数据集合
     * @param batchSize 批量大小
     * @param consumer  执行方法
     * @param <E>       泛型
     * @return 操作结果
     * @since 3.3.1
     */
    protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
        return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer);
    }

    /**
     * 执行批量操作(默认批次提交数量{@link IService#DEFAULT_BATCH_SIZE})
     *
     * @param list     数据集合
     * @param consumer 执行方法
     * @param <E>      泛型
     * @return 操作结果
     * @since 3.3.1
     */
    protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
        return executeBatch(list, DEFAULT_BATCH_SIZE, consumer);
    }

}

来使用一下getOne(),它的源码如下:

    /**
     * 根据 Wrapper,查询一条记录 <br/>
     * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
     *
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    default T getOne(Wrapper<T> queryWrapper) {
        return getOne(queryWrapper, true);
    }

    /**
     * 根据 Wrapper,查询一条记录
     *
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     * @param throwEx      有多个 result 是否抛出异常
     */
    T getOne(Wrapper<T> queryWrapper, boolean throwEx);

一个参数的getOne()是通过调用getOne(queryWrapper, true)来实现的,所以我们需要来看一下两个参数的getOne()是怎么实现的,源码如下:

    @Override
    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
        if (throwEx) {
            return baseMapper.selectOne(queryWrapper);
        }
        return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
    }
    @Autowired
    protected M baseMapper;

可以看到,它用到了baseMapper,而baseMapper会自动注入(由Spring的BeanFactory来管理)。

其实这个baseMapper就是我们上面的UserMapper。
在这里插入图片描述
在这里插入图片描述
所以当throwExtrue时,会返回baseMapper.selectOne(queryWrapper)的结果,在之前的博客已经介绍过这个方法,当符合条件构造器的数据有多条时,会抛出异常。
throwExfalse时,会返回SqlHelper.getObject(log, baseMapper.selectList(queryWrapper))的结果,源码如下:

    public static <E> E getObject(Log log, List<E> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            int size = list.size();
            if (size > 1) {
                log.warn(String.format("Warn: execute Method There are  %s results.", size));
            }
            return list.get(0);
        }
        return null;
    }

从源码可知当符合条件构造器的数据有多条时,首先会报一个警告,再返回符合条件的第一条数据(下标为0
所以throwEx就是表示当符合条件构造器的数据有多条时,是否需要抛出异常信息。

来测试一下:

package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import com.kaven.mybatisplus.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void getOne(){
        LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();
        userLambdaQueryWrapper.gt(User::getAge , 20);

        User user = userService.getOne(userLambdaQueryWrapper);
        System.out.println(user);
    }
}

很显然抛出异常了:
在这里插入图片描述
再来测试一下:

package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import com.kaven.mybatisplus.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void getOne(){
        LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();
        userLambdaQueryWrapper.gt(User::getAge , 20);

        User user = userService.getOne(userLambdaQueryWrapper , false);
        System.out.println(user);
    }
}

结果如下:
在这里插入图片描述

和我们分析的一样,首先会发出警告,然后选择第一条符合条件的数据。

再来使用一下saveBatch(),源码如下:

    /**
     * 插入(批量)
     *
     * @param entityList 实体对象集合
     */
    @Transactional(rollbackFor = Exception.class)
    default boolean saveBatch(Collection<T> entityList) {
        return saveBatch(entityList, DEFAULT_BATCH_SIZE);
    }

    /**
     * 插入(批量)
     *
     * @param entityList 实体对象集合
     * @param batchSize  插入批次数量
     */
    boolean saveBatch(Collection<T> entityList, int batchSize);
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
    }

    /**
     * 默认批次提交数量
     */
    int DEFAULT_BATCH_SIZE = 1000;

可以看到这两个方法都加了事务@Transactional(rollbackFor = Exception.class),默认批次提交数量DEFAULT_BATCH_SIZE1000,代码就不深入研究了。

来测试一下:

package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import com.kaven.mybatisplus.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTest {

    @Autowired
    private UserService userService;

    @Transactional
    @Test
    public void saveBatch(){
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 2000; i++) {
            User user = new User();
            user.setUsername("kaven-"+i);
            user.setPassword("itkaven-"+i);
            user.setAge(22);
            userList.add(user);
        }

        long start = System.currentTimeMillis();
        userService.saveBatch(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时: "+(end-start)+"ms");
    }
}

在测试方法上加上事务,会在测试方法完成后,帮我们回滚到原始的数据,避免测试阶段污染数据库中的数据。

结果如下:
在这里插入图片描述
耗时还挺长的,可能是因为服务器的数据库(网络原因),并且还打印了sql信息,以及还需要回滚数据。

再来测试下一次性插入:

package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import com.kaven.mybatisplus.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTest {

    @Autowired
    private UserService userService;

    @Transactional
    @Test
    public void saveBatch(){
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 2000; i++) {
            User user = new User();
            user.setUsername("kaven-"+i);
            user.setPassword("itkaven-"+i);
            user.setAge(22);
            userList.add(user);
        }

        long start = System.currentTimeMillis();
        userService.saveBatch(userList , 2000);
        long end = System.currentTimeMillis();
        System.out.println("耗时: "+(end-start)+"ms");
    }
}

结果如下:
在这里插入图片描述
稍微好一点点。

强调一下,还有些方法比较好用,会返回ChainWrapper<T>这种链式条件构造器,这里就不演示了,下面有源码,自己看一看,还是比较简单的,我在Lambda条件构造器那一篇博客中有使用过这种链式条件构造器。

MyBatis-Plus 之Lambda条件构造器

    /**
     * 以下的方法使用介绍:
     *
     * 一. 名称介绍
     * 1. 方法名带有 query 的为对数据的查询操作, 方法名带有 update 的为对数据的修改操作
     * 2. 方法名带有 lambda 的为内部方法入参 column 支持函数式的
     * 二. 支持介绍
     *
     * 1. 方法名带有 query 的支持以 {@link ChainQuery} 内部的方法名结尾进行数据查询操作
     * 2. 方法名带有 update 的支持以 {@link ChainUpdate} 内部的方法名为结尾进行数据修改操作
     *
     * 三. 使用示例,只用不带 lambda 的方法各展示一个例子,其他类推
     * 1. 根据条件获取一条数据: `query().eq("column", value).one()`
     * 2. 根据条件删除一条数据: `update().eq("column", value).remove()`
     *
     */

    /**
     * 链式查询 普通
     *
     * @return QueryWrapper 的包装类
     */
    default QueryChainWrapper<T> query() {
        return ChainWrappers.queryChain(getBaseMapper());
    }

    /**
     * 链式查询 lambda 式
     * <p>注意:不支持 Kotlin </p>
     *
     * @return LambdaQueryWrapper 的包装类
     */
    default LambdaQueryChainWrapper<T> lambdaQuery() {
        return ChainWrappers.lambdaQueryChain(getBaseMapper());
    }

    /**
     * 链式更改 普通
     *
     * @return UpdateWrapper 的包装类
     */
    default UpdateChainWrapper<T> update() {
        return ChainWrappers.updateChain(getBaseMapper());
    }

    /**
     * 链式更改 lambda 式
     * <p>注意:不支持 Kotlin </p>
     *
     * @return LambdaUpdateWrapper 的包装类
     */
    default LambdaUpdateChainWrapper<T> lambdaUpdate() {
        return ChainWrappers.lambdaUpdateChain(getBaseMapper());
    }

其他方法也是差不多的用法,可以自己去研究一下。

写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!

  • 19
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
### 回答1: Mybatis-Plus是一个基于Mybatis的增强工具,提供了许多实用的功能,如自动生成代码、分页查询、条件构造器、性能分析等。Mybatis-Plus ServiceMybatis-Plus的一个模块,提供了一些常用的Service层接口和实现类,如IServiceServiceImpl等,方便开发者快速构建Service层。 ### 回答2: Mybatis-Plus是一个开源的、能够和Mybatis无缝衔接并扩展出更多实用功能的框架。在实际项目开发中,通常会使用到基于Mybatis-PlusService层,以下是关于Mybatis-Plus Service的一些介绍。 Mybatis-PlusService层是基于Mybatis-Plus框架进行封装的,旨在简化开发者编写Service层代码的流程。使用Mybatis-Plus Service可以有效地减少重复代码的编写,提高开发效率。 在Mybatis-Plus Service中,通常包含了一些常见的CRUD方法,如查询列表、根据ID查询、插入、更新和删除等。我们可以通过继承BaseService或者IService来使用这些方法。同时,Mybatis-Plus Service还提供了一些强大的查询构建器,如LambdaQueryWrapper和QueryWrapper等,可以快速构建复杂的查询条件。 另外,Mybatis-Plus Service还支持事务管理。它提供了一种@Transactional注解来实现声明式事务,我们只需在Service层的方法上添加该注解,即可完成事务的配置。 除了基本的CRUD操作和事务管理外,Mybatis-Plus Service还具有其他扩展的功能,例如分页查询、批量操作、逻辑删除等。这些功能都能够极大地简化开发者的编码工作。 总而言之,Mybatis-Plus Service是一种基于Mybatis-Plus框架的封装,用于简化Service层代码的编写。它提供了一系列的CRUD方法、事务管理以及其他实用功能,可以提高开发效率并减少冗余代码的编写。使用Mybatis-Plus Service,开发者能够更加专注于业务逻辑的实现,提高开发效率和代码质量。 ### 回答3: MyBatis-Plus是一个在MyBatis基础上的增强工具,提供了更加便捷的CRUD操作方式。其中的ServiceMyBatis-Plus提供的一层封装,主要用于处理业务逻辑和数据库操作之间的关系。 MyBatis-PlusService主要有以下几个功能: 1. 提供通用的CRUD方法:Service提供了常见的增删改查方法,如save、remove、update等,可以直接调用这些方法来操作数据库,无需手写SQL语句。 2. 封装条件构造器:Service的方法中可以使用MyBatis-Plus提供的条件构造器来进行查询条件的组装,例如可以使用eq、like、in等方法来构建查询条件。 3. 支持分页查询:Service提供了分页查询的方法,可以方便地进行数据分页查询操作。可以设置每页的数量、当前页码等参数来实现分页效果。 4. 支持事务控制:Service可以通过注解的方式来对方法添加事务控制,保证在业务逻辑中的多个操作要么全部成功,要么全部失败。可以使用@Transactional注解来标记需要进行事务控制的方法。 总的来说,MyBatis-PlusService提供了一种更加便捷的数据库操作方式,简化了开发过程中的数据库操作代码,提高了开发效率。同时,它还具备一些高级功能,如条件构造器、分页查询和事务控制,使得开发者可以更加灵活和方便地进行业务逻辑的处理和数据库操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ITKaven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值