二、RuoYi项目集成Mybatis Plus与扩展

为了减少基础SQL的代码量,并使得后续项目开发时减少SQL代码的编写量,故引入mybatis-plus,在原来的Mybatis的基础进行扩展和增强,并且修改代码生成模块的代码模板。

集成Mybatis Plus

  1. ruoyi-common的pom文件中引入依赖

    <!-- ruoyi-springboot2 / mybatis-plus 配置 -->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.5.2</version>
    </dependency>
    

    也可以将版本号和依赖统一放到项目的总pom文件管理,再引入依赖

     <properties>
       ... ...
       <mybatisplus.veriosn>3.5.2</mybatisplus.veriosn>
       ... ...
    </properties>
    
    <dependencyManagement>
      <dependencies>
          ...  ...
        <!-- mybatis plus -->
        <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-boot-starter</artifactId>
          <version>${mybatisplus.veriosn}</version>
        </dependency>
      </dependencies>
    </dependencyManagement>
    
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    
  2. ruoyi-adminapplication.yml文件中添加配置,其中增加了如下功能:

    • 主键修改为雪花算法自动生成,在数据库创建新表时不需要设置自增
    • 增加逻辑删除,对于需要逻辑删除的表增加delFlag字段
# MyBatis Plus配置
mybatis-plus:
  # 不支持多包, 如有需要可在注解配置 或 提升扫包等级
  # 例如 com.**.**.mapper
  mapperPackage: com.ruoyi.**.mapper
  # 搜索指定包别名
  typeAliasesPackage: com.ruoyi.**.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 加载全局的配置文件
#  configLocation: classpath:mybatis/mybatis-config.xml
  configuration:
    # 开启下划线转驼峰(默认值其实就是true,显式配置更稳妥)
    map-underscore-to-camel-case: true
    # 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
    # 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
    logImpl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 是否打印 Logo banner
      banner: false
      # 主键类型
      # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
      # 如需改为自增 需要将数据库表全部设置为自增
      id-type: assign_id
      logic-delete-field: delFlag # 全局逻辑删除的实体字段名
      logic-delete-value: 2 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. ruoyi-framework中添加配置类MybatisPlusConfig
package com.ruoyi.framework.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Mybatis Plus 配置
 *
 * @author ruoyi
 */
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@EnableConfigurationProperties(MybatisPlusProperties.class)
public class MybatisPlusConfig
{
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor()
    {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(paginationInnerInterceptor());
        // 乐观锁插件
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
        // 阻断插件
        interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
        return interceptor;
    }

    /**
     * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
     */
    public PaginationInnerInterceptor paginationInnerInterceptor()
    {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // 设置数据库类型为mysql
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        return paginationInnerInterceptor;
    }

    /**
     * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor()
    {
        return new OptimisticLockerInnerInterceptor();
    }

    /**
     * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
     */
    public BlockAttackInnerInterceptor blockAttackInnerInterceptor()
    {
        return new BlockAttackInnerInterceptor();
    }
}

编写后端业务代码

后端的基础业务代码包括实体类domain、数据操作映射类mapper、业务逻辑类service、接口类controller。以下以考试试卷数据库表ExamPaper为例依次编写相关代码。

实体类domain
  1. 在RuoYi项目中,所有实体类都要编写gettersetter方法,代码量较大,引入lombok来减少代码量;
 <!-- pom.xml -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  1. 在实体类中,与前端交互时,Date类型字段需要JSON格式的转化;由于前段js的数据类型受限,Long类型的数据过长时以字符串形式转换为JSON。因此,需要统一JSON格式的转换逻辑。

​ 先修改ruoyi-adminapplication.yml文件的jackson配置

# Spring配置
spring:
	... ...
  jackson:
    # 日期格式化
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8  # 添加时区设置
    serialization:
      # 格式化输出
      indent_output: false
      # 忽略无法转换的对象
      fail_on_empty_beans: false
    deserialization:
      # 允许对象忽略json中不存在的属性
      fail_on_unknown_properties: false
 ... ...

​ 在ruoyi-framework中添加配置类JacksonConfig

package com.ruoyi.framework.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

@Configuration
public class JacksonConfig {

    // JavaScript 安全整数范围常量
    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
    private static final long MIN_SAFE_INTEGER = -9007199254740991L;

    /**
     * 配置Jackson消息转换器(核心函数)
     * 注入Jackson2ObjectMapperBuilder以集成yml配置
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
        // 使用Spring Boot自动配置的builder创建ObjectMapper(会读取yml配置)
        ObjectMapper objectMapper = builder.build();
        // 在此基础上添加自定义配置
        configureObjectMapper(objectMapper);
        // 创建转换器
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 配置自定义序列化器
        converter.setObjectMapper(objectMapper);
        return converter;
    }

    /**
     * 配置ObjectMapper的核心函数:注册自定义序列化器
     */
    private void configureObjectMapper(ObjectMapper objectMapper) {
        // 创建自定义模块
        SimpleModule module = new SimpleModule();
        // 注册Long类型的智能序列化器
        module.addSerializer(Long.class, createSmartLongSerializer());
        module.addSerializer(long.class, createSmartLongSerializer());
        // 将模块注册到ObjectMapper
        objectMapper.registerModule(module);
    }

    /**
     * 创建智能Long类型序列化器的函数
     */
    private JsonSerializer<Long> createSmartLongSerializer() {
        return new JsonSerializer<Long>() {
            @Override
            public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                if (value == null) {
                    gen.writeNull();
                    return;
                }
                // 超出安全范围则序列化为字符串
                if (value < MIN_SAFE_INTEGER || value > MAX_SAFE_INTEGER) {
                    gen.writeString(value.toString());
                } else {
                    gen.writeNumber(value);
                }
            }
        };
    }
}
  1. 修改所有实体类都要继承的基类BaseEntity@JsonIgnore注解表示该字段不会被JSON序列化,@TableField(exist = false)注解表示该字段不会出现在SQL中;
package com.ruoyi.common.core.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

/**
 * Entity基类
 * 
 * @author ruoyi
 */
@Data
public class BaseEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 搜索值 */
    @JsonIgnore
    @TableField(exist = false)
    private String searchValue;

    /** 创建者 */
    private String createBy;

    /** 创建时间 */
    private Date createTime;

    /** 更新者 */
    private String updateBy;

    /** 更新时间 */
    private Date updateTime;

    /** 备注 */
    private String remark;

    /** 请求参数 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @TableField(exist = false)
    private Map<String, Object> params;

    public Map<String, Object> getParams()
    {
        if (params == null)
        {
            params = new HashMap<>();
        }
        return params;
    }
}
  1. 编写实体类ExamPaper,包括试卷标题、岗位、状态、考试时间等属性。
package com.ruoyi.exam.domain;

import com.baomidou.mybatisplus.annotation.TableId;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * 考试试卷对象 exam_paper
 */
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class ExamPaper extends BaseEntity
{
    /** 试卷id */
    @TableId("paper_id")
    private Long paperId;

    /** 试卷标题 */
    @Excel(name = "试卷标题")
    private String paperTitle;

    /** 试卷考试时间 */
    @Excel(name = "试卷考试时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date paperExamTime;

    /** 试卷考试岗位 */
    @Excel(name = "试卷考试岗位")
    private String paperExamJob;

    /** 试卷状态(草稿、完成、完成并考完) */
    @Excel(name = "试卷状态")
    private String paperStatus;

    /** 删除标志(0代表存在 2代表删除) */
    private String delFlag;
  
}
数据操作映射类mapper

ExamPaperMapper

package com.ruoyi.exam.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.exam.domain.ExamPaper;

/**
 * 考试试卷Mapper接口
 */
public interface ExamPaperMapper extends BaseMapper<ExamPaper>
{
}
业务逻辑类service

IExamPaperService

package com.ruoyi.exam.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.exam.domain.ExamPaper;
import java.util.List;

/**
 * 考试试卷Service接口
 */
public interface IExamPaperService extends IService<ExamPaper>
{
    /**
     * 查询考试试卷
     * 
     * @param paperId 考试试卷主键
     * @return 考试试卷
     */
    ExamPaper selectExamPaperByPaperId(Long paperId);

    /**
     * 查询考试试卷列表
     * 
     * @param examPaper 考试试卷
     * @return 考试试卷集合
     */
    List<ExamPaper> selectExamPaperList(ExamPaper examPaper);

    /**
     * 新增考试试卷
     * 
     * @param examPaper 考试试卷
     * @return 结果
     */
    int insertExamPaper(ExamPaper examPaper);

    /**
     * 修改考试试卷
     * 
     * @param examPaper 考试试卷
     * @return 结果
     */
    int updateExamPaper(ExamPaper examPaper);

    /**
     * 批量删除考试试卷
     * 
     * @param paperIds 需要删除的考试试卷主键集合
     * @return 结果
     */
    int deleteExamPaperByPaperIds(Long[] paperIds);

    /**
     * 删除考试试卷信息
     * 
     * @param paperId 考试试卷主键
     * @return 结果
     */
    int deleteExamPaperByPaperId(Long paperId);

}

ExamPaperServiceImpl

package com.ruoyi.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.exam.domain.*;
import com.ruoyi.exam.mapper.*;
import com.ruoyi.exam.service.IExamPaperService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;

/**
 * 考试试卷Service业务层处理
 */
@Service
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper> implements IExamPaperService
{
   
    private LambdaQueryWrapper<ExamPaper> createQueryWrapper(ExamPaper examPaper) {

        LambdaQueryWrapper<ExamPaper> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Objects.nonNull(examPaper.getPaperId()),ExamPaper::getPaperId, examPaper.getPaperId());
        queryWrapper.like(Objects.nonNull(examPaper.getPaperTitle()),ExamPaper::getPaperTitle, examPaper.getPaperTitle());
        queryWrapper.like(Objects.nonNull(examPaper.getPaperExamJob()),ExamPaper::getPaperExamJob, examPaper.getPaperExamJob());
        queryWrapper.eq(Objects.nonNull(examPaper.getPaperStatus()),ExamPaper::getPaperStatus, examPaper.getPaperStatus());
        // 获取查询??的时间间隔
        Map<String, Object> params = examPaper.getParams();
        Object beginTime = params.get("beginTime");
        Object endTime = params.get("endTime");
        if (Objects.nonNull(beginTime) && Objects.nonNull(endTime)) {
            Date begin = DateUtils.parseDate(beginTime);
            Date end = DateUtils.parseDate(endTime);
            queryWrapper.between(ExamPaper::getPaperExamTime, begin, end);
        }
        queryWrapper.orderBy(
                Objects.nonNull(examPaper.getOrderByColumn()),
                StringUtils.equals(examPaper.getIsAsc(),"asc"),
                ExamPaper::getCreateTime
        );
        return queryWrapper;
    }

    /**
     * 查询考试试卷
     */
    @Override
    public ExamPaper selectExamPaperByPaperId(Long paperId)
    {
        return baseMapper.selectById(paperId);
    }

    /**
     * 查询考试试卷列表
     */
    @Override
    public List<ExamPaper> selectExamPaperList(ExamPaper examPaper)
    {
        LambdaQueryWrapper<ExamPaper> queryWrapper = createQueryWrapper(examPaper);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 新增考试试卷
     */
    @Override
    public int insertExamPaper(ExamPaper examPaper)
    {
        examPaper.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insert(examPaper);
    }

    /**
     * 修改考试试卷
     */
    @Override
    public int updateExamPaper(ExamPaper examPaper)
    {
        examPaper.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(examPaper);
    }

    /**
     * 批量删除考试试卷
     */
    @Override
    public int deleteExamPaperByPaperIds(Long[] paperIds)
    {
        return baseMapper.deleteBatchIds(Arrays.asList(paperIds));
    }

    /**
     * 删除考试试卷信息
     */
    @Override
    public int deleteExamPaperByPaperId(Long paperId)
    {
        return baseMapper.deleteById(paperId);
    }
}
接口类controller

ExamPaperController(基本不需要修改)

package com.ruoyi.exam.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.exam.domain.ExamPaper;
import com.ruoyi.exam.service.IExamPaperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 考试试卷Controller
 */
@RestController
@RequestMapping("/exam/paper")
public class ExamPaperController extends BaseController
{
    @Autowired
    private IExamPaperService examPaperService;

    /**
     * 查询考试试卷列表
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:list')")
    @GetMapping("/list")
    public TableDataInfo list(ExamPaper examPaper)
    {
        startPage();
        List<ExamPaper> list = examPaperService.selectExamPaperList(examPaper);
        return getDataTable(list);
    }

    /**
     * 导出考试试卷列表
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:export')")
    @Log(title = "考试试卷", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ExamPaper examPaper)
    {
        List<ExamPaper> list = examPaperService.selectExamPaperList(examPaper);
        ExcelUtil<ExamPaper> util = new ExcelUtil<ExamPaper>(ExamPaper.class);
        util.exportExcel(response, list, "考试试卷数据");
    }

    /**
     * 获取考试试卷详细信息
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:query')")
    @GetMapping(value = "/{paperId}")
    public AjaxResult getInfo(@PathVariable("paperId") Long paperId)
    {
        return success(examPaperService.selectExamPaperByPaperId(paperId));
    }

    /**
     * 新增考试试卷
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:add')")
    @Log(title = "考试试卷", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ExamPaper examPaper)
    {
        examPaper.setCreateBy(getUsername());
        return toAjax(examPaperService.insertExamPaper(examPaper));
    }

    /**
     * 修改考试试卷
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:edit')")
    @Log(title = "考试试卷", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ExamPaper examPaper)
    {
        examPaper.setUpdateBy(getUsername());
        return toAjax(examPaperService.updateExamPaper(examPaper));
    }

    /**
     * 删除考试试卷
     */
    @PreAuthorize("@ss.hasPermi('exam:paper:remove')")
    @Log(title = "考试试卷", businessType = BusinessType.DELETE)
	@DeleteMapping("/{paperIds}")
    public AjaxResult remove(@PathVariable Long[] paperIds)
    {
        return toAjax(examPaperService.deleteExamPaperByPaperIds(paperIds));
    }

}

通过代码生成器生成sql和前端代码后,就可以测试了。

修改生成代码模板

代码生成模块是基于velocity第三方库实现,由于集成了Mybatis Plus,原来的业务相关的代码生成模版就不适用了,因此只需要修改ruoyi-generator/src/main/resources/vm下的相关模板即可。

domain.java.vm
package ${packageName}.domain;

#foreach ($import in $importList)
import ${import};
#end
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import com.ruoyi.common.annotation.Excel;
#if($table.crud || $table.sub)
import com.ruoyi.common.core.domain.BaseEntity;
#elseif($table.tree)
import com.ruoyi.common.core.domain.TreeEntity;
#end

/**
 * ${functionName}对象 ${tableName}
 * 
 * @author ${author}
 * @date ${datetime}
 */
#if($table.crud || $table.sub)
#set($Entity="BaseEntity")
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class ${ClassName} extends ${Entity}
{
    private static final long serialVersionUID = 1L;

#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
    /** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($parentheseIndex != -1)
    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
    @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
#else
    @Excel(name = "${comment}")
#end
#end
    #if($column.javaField.endsWith("Id"))
    @TableId("${column.javaField.replaceAll('([A-Z])', '_$1').toLowerCase()}")
    #end
    private $column.javaType $column.javaField;

#end
#end
#if($table.sub)
    /** $table.subTable.functionName信息 */
    private List<${subClassName}> ${subclassName}List;

#end
}
mapper.java.vm
package ${packageName}.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${packageName}.domain.${ClassName};
#if($table.sub)
import ${packageName}.domain.${subClassName};
#end

/**
 * ${functionName}Mapper接口
 * 
 * @author ${author}
 * @date ${datetime}
 */
public interface ${ClassName}Mapper extends BaseMapper<ExamPaper>
{
}
service.java.vm
package ${packageName}.service;

import com.baomidou.mybatisplus.extension.service.IService;
import ${packageName}.domain.${ClassName};
import java.util.List;

/**
 * ${functionName}Service接口
 * 
 * @author ${author}
 * @date ${datetime}
 */
public interface I${ClassName}Service extends IService<${ClassName}>
{
    /**
     * 查询${functionName}
     * 
     * @param ${pkColumn.javaField} ${functionName}主键
     * @return ${functionName}
     */
     ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});

    /**
     * 查询${functionName}列表
     * 
     * @param ${className} ${functionName}
     * @return ${functionName}集合
     */
    List<${ClassName}> select${ClassName}List(${ClassName} ${className});

    /**
     * 新增${functionName}
     * 
     * @param ${className} ${functionName}
     * @return 结果
     */
    int insert${ClassName}(${ClassName} ${className});

    /**
     * 修改${functionName}
     * 
     * @param ${className} ${functionName}
     * @return 结果
     */
    int update${ClassName}(${ClassName} ${className});

    /**
     * 批量删除${functionName}
     * 
     * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合
     * @return 结果
     */
    int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);

    /**
     * 删除${functionName}信息
     * 
     * @param ${pkColumn.javaField} ${functionName}主键
     * @return 结果
     */
    int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
}

serviceImpl.java.vm
package ${packageName}.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.springframework.stereotype.Service;
#if($table.sub)
import java.util.ArrayList;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import ${packageName}.domain.${subClassName};
#end
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${packageName}.mapper.${ClassName}Mapper;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;

/**
 * ${functionName}Service业务层处理
 * 
 * @author ${author}
 * @date ${datetime}
 */
@Service
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service
{

    private LambdaQueryWrapper<${ClassName}> createQueryWrapper(${ClassName} ${className}) {
        LambdaQueryWrapper<ExamSection> queryWrapper = Wrappers.lambdaQuery();
        // your query code
        return queryWrapper;
    }

    /**
     * 查询${functionName}
     */
    @Override
    public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
    {
        return baseMapper.selectById(${pkColumn.javaField});
    }

    /**
     * 查询${functionName}列表
     */
    @Override
    public List<${ClassName}> select${ClassName}List(${ClassName} ${className})
    {
        LambdaQueryWrapper<${ClassName}> queryWrapper = createQueryWrapper(${className});
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 新增${functionName}
     */
#if($table.sub)
    @Transactional
#end
    @Override
    public int insert${ClassName}(${ClassName} ${className})
    {
#if($table.sub)
        int rows = ${className}Mapper.insert${ClassName}(${className});
        insert${subClassName}(${className});
        return rows;
#else
        return baseMapper.insert(${className});
#end
    }

    /**
     * 修改${functionName}
     */
#if($table.sub)
    @Transactional
#end
    @Override
    public int update${ClassName}(${ClassName} ${className})
    {
#if($table.sub)
        ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}());
        insert${subClassName}(${className});
#end
        return baseMapper.updateById(${className});
    }

    /**
     * 批量删除${functionName}
     */
#if($table.sub)
    @Transactional
#end
    @Override
    public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s)
    {
#if($table.sub)
        ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s);
#end
        return baseMapper.deleteBatchIds(Arrays.asList(${pkColumn.javaField}s));
    }

    /**
     * 删除${functionName}信息
     */
#if($table.sub)
    @Transactional
#end
    @Override
    public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
    {
#if($table.sub)
        ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField});
#end
        return baseMapper.deleteById(${pkColumn.javaField});
    }
#if($table.sub)

    /**
     * 新增${subTable.functionName}信息
     */
    public void insert${subClassName}(${ClassName} ${className})
    {
        List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List();
        ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}();
        if (StringUtils.isNotNull(${subclassName}List))
        {
            List<${subClassName}> list = new ArrayList<${subClassName}>();
            for (${subClassName} ${subclassName} : ${subclassName}List)
            {
                ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
                list.add(${subclassName});
            }
            if (list.size() > 0)
            {
                ${className}Mapper.batch${subClassName}(list);
            }
        }
    }
#end
}
mapper.xml.vm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${packageName}.mapper.${ClassName}Mapper">
    
    <resultMap type="${ClassName}" id="${ClassName}Result">
#foreach ($column in $columns)
        <result property="${column.javaField}"    column="${column.columnName}"    />
#end
    </resultMap>
#if($table.sub)

    <resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result">
        <collection property="${subclassName}List" ofType="${subClassName}" column="${pkColumn.columnName}" select="select${subClassName}List" />
    </resultMap>

    <resultMap type="${subClassName}" id="${subClassName}Result">
#foreach ($column in $subTable.columns)
        <result property="${column.javaField}"    column="${column.columnName}"    />
#end
    </resultMap>
#end

    <sql id="select${ClassName}Vo">
        select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName}
    </sql>
</mapper>

参考代码和网站连接:

RuoYi-Vue3 前端
RuoYi-Vue-Boot-2.x 后端
RuoYi-Vue的金仓数据库版本
RuoYi-Vue的多租户后台管理系统
集成mybatis-plus实现mybatis增强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值