侧边栏壁纸
  • 累计撰写 9 篇文章
  • 累计创建 4 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

RuoYi(若依)框架集成MyBatis-Flex

Dckxx
2024-12-02 / 0 评论 / 1 点赞 / 61 阅读 / 39358 字

前言

若依的自带框架中并没有集成任何数据库操作的可持久化的扩展, 这里选择集成了MyBatis-Flex, MyBatis-Flex是一个优雅的 MyBatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库,其内置的 QueryWrapper帮助我们极大的减少了 SQL 编写的工作的同时,减少出错的可能性。

总而言之,MyBatis-Flex 能够极大地提高我们的开发效率和开发体验,让我们有更多的时间专注于自己的事情。

https://mybatis-flex.com

其中涉及到的版本

  • 若依: 3.8.7

  • MyBatis-Flex: 1.8.6

  • pagehelper: 5.3.3

1. 添加依赖

在项目根目录pom中的<dependencies>标签下添加如下依赖:

<dependency>
    <groupId>com.mybatis-flex</groupId>
    <artifactId>mybatis-flex-spring-boot-starter</artifactId>
    <version>${mybatis-flex.version}</version>
</dependency>
<dependency>
    <groupId>com.mybatis-flex</groupId>
    <artifactId>mybatis-flex-processor</artifactId>
    <version>${mybatis-flex.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>${pagehelper.version}</version>
</dependency>

<properties>标签下添加:

<properties>
    <pagehelper.version>5.3.3</pagehelper.version>
    <mybatis-flex.version>1.8.6</mybatis-flex.version>
</properties>

在common包中的pom添加如下依赖:

<dependency>
    <groupId>com.mybatis-flex</groupId>
    <artifactId>mybatis-flex-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.mybatis-flex</groupId>
    <artifactId>mybatis-flex-processor</artifactId>
</dependency>
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

这里要注意把若依框架自带的pagehelper分页的包引用删除掉, 使用上面的, 不然会导致分页失败

2. yml配置

在admin模块, 也就是启动项目的模块配置文件yml中删除mybatis的配置, 添加如下mybatis-flex配置:

# MyBatis配置
mybatis-flex:
  # 搜索指定包别名
  type-aliases-package: com.gz.**.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  configuration:
    # 自动驼峰命名规则(camel case)映射
    mapUnderscoreToCamelCase: true
    # MyBatis 自动映射策略
    # NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
    autoMappingBehavior: FULL
    # MyBatis 自动映射时未知列或未知属性处理策
    # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
    autoMappingUnknownColumnBehavior: NONE
    # 原理的mybatis配置
    cacheEnabled: true
    defaultExecutorType: SIMPLE
    logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl

具体的其他配置可参考MyBatis-Flex官网

3. 修改代码生成器模板

也可以使用MyBatis-Flex官网的代码生成器, 只不过就不能在系统界面中进行操作,而且也不能生成前端页面, 如果需要能在页面配置生成就要通过如下修改, 修改的文件都在generator资源包下vm下面的模板

3.1. 修改controller.java.vm

package ${packageName}.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ${basePackage}.common.annotation.Log;
import ${basePackage}.common.core.controller.BaseController;
import ${basePackage}.common.core.domain.AjaxResult;
import ${basePackage}.common.enums.BusinessType;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import ${basePackage}.common.utils.poi.ExcelUtil;
#if($table.crud || $table.sub)
import ${basePackage}.common.core.page.TableDataInfo;
import com.mybatisflex.core.paginate.Page;
import ${basePackage}.common.core.page.PageDomain;
#end

/**
 * ${functionName}Controller
 *
 * @author ${author}
 * @date ${datetime}
 */
@RestController
@RequestMapping("/${moduleName}/${businessName}")
public class ${ClassName}Controller extends BaseController {
    @Resource
    private I${ClassName}Service ${className}Service;

/**
 * 查询${functionName}列表
 */
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
@GetMapping("/list")
    #if($table.crud || $table.sub)
    public TableDataInfo list(PageDomain pageDomain, ${ClassName} ${className})
    {
        Page<${ClassName}> page = ${className}Service.select${ClassName}Page(pageDomain, ${className});
        return getFlexTable(page);
    }
    #elseif($table.tree)
        public AjaxResult list(${ClassName} ${className})
        {
            List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
            return success(list);
        }
    #end

    /**
     * 导出${functionName}列表
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")
    @Log(title = "${functionName}", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ${ClassName} ${className})
    {
        List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
        ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
        util.exportExcel(response, list, "${functionName}数据");
    }

    /**
     * 获取${functionName}详细信息
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')")
    @GetMapping(value = "/{${pkColumn.javaField}}")
    public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
    {
        return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
    }

    /**
     * 新增${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")
    @Log(title = "${functionName}", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ${ClassName} ${className})
    {
        return toAjax(${className}Service.insert${ClassName}(${className}));
    }

    /**
     * 修改${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")
    @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ${ClassName} ${className})
    {
        return toAjax(${className}Service.update${ClassName}(${className}));
    }

    /**
     * 删除${functionName}
     */
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')")
    @Log(title = "${functionName}", businessType = BusinessType.DELETE)
    @DeleteMapping("/{${pkColumn.javaField}s}")
    public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
    {
        return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));
    }
}

3.2. 修改domain.java.vm

package ${packageName}.domain;

#foreach ($import in $importList)
import ${import};
#end
#if($table.sub)
import com.mybatisflex.annotation.Column;
#end
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import ${basePackage}.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;

#if($table.crud || $table.sub)
import ${basePackage}.common.core.domain.BaseEntity;
#elseif($table.tree)
import ${basePackage}.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
@Data
@EqualsAndHashCode(callSuper = true)
@Table("${tableName}")
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')
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
            #else
    @Excel(name = "${comment}")
            #end
        #end
        #if ($column.columnName == $pkColumn.columnName)
    @Id(keyType= KeyType.Auto)
        #end
    private $column.javaType $column.javaField;

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

#end

}

3.3. 修改mapper.java.vm

package ${packageName}.mapper;

import com.mybatisflex.core.BaseMapper;
import ${packageName}.domain.${ClassName};

/**
 * ${functionName}Mapper接口
 *
 * @author ${author}
 * @date ${datetime}
 */
public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> {
}

3.4. 修改service.java.vm

package ${packageName}.service;

import java.util.List;
    #if($table.crud || $table.sub)
    import com.mybatisflex.core.paginate.Page;
    import ${basePackage}.common.core.page.PageDomain;
    #end
import com.mybatisflex.core.service.IService;
import ${packageName}.domain.${ClassName};

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

    #if($table.crud || $table.sub)
        /**
         * 分页查询${functionName}列表
         *
         * @param pageDomain 分页对象
         * @param ${className} ${functionName}
         * @return 分页对象
         */
        Page<${ClassName}> select${ClassName}Page(PageDomain pageDomain, ${ClassName} ${className});
    #end

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

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

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

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

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

3.5. 修改serviceImpl.java.vm

package ${packageName}.service.impl;

#if($table.crud || $table.sub)
import com.mybatisflex.core.paginate.Page;
#end
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import java.util.List;
import javax.annotation.Resource;
#foreach ($column in $columns)
    #if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
    import ${basePackage}.common.utils.DateUtils;
        #break
    #end
#end
import org.springframework.stereotype.Service;
#if($table.crud || $table.sub)
import ${basePackage}.common.core.page.PageDomain;
import ${basePackage}.common.utils.StringUtils;
#end
import ${packageName}.mapper.${ClassName}Mapper;
#if ($table.sub)
import org.springframework.transaction.annotation.Transactional;
import ${packageName}.domain.${subClassName};
import ${packageName}.mapper.${subClassName}Mapper;
#end
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import java.util.Arrays;
#foreach ($column in $columns)
    #if  ($column.queryType == "BETWEEN")
    import java.util.Map;
        #break
    #end
#end


import static ${packageName}.domain.table.${ClassName}TableDef.${SnakeClassName};
#if ($table.sub)
import static ${packageName}.domain.table.${subClassName}TableDef.${subSnakeClassName};
#end

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

    #if($table.sub)
        @Resource
        private ${subClassName}Mapper ${subclassName}Mapper;
    #end

    /**
     * 查询${functionName}
     *
     * @param ${pkColumn.javaField} ${functionName}主键
     * @return ${functionName}
     */
    @Override
    public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
    {
        ${ClassName} ${className} = ${className}Mapper.selectOneById(${pkColumn.javaField});
        #if($table.sub)
            List<${subClassName}> ${subclassName}List = ${subclassName}Mapper.selectListByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${className}.get${pkColumn.capJavaField}()));
            ${className}.set${subClassName}List(${subclassName}List);
        #end
        return ${className};
    }

    #if($table.crud || $table.sub)
        @Override
        public Page<${ClassName}> select${ClassName}Page(PageDomain pageDomain, ${ClassName} ${className}) {
            QueryWrapper query = buildWrapper(${className});
            if (StringUtils.isNotBlank(pageDomain.getOrderBy())) {
                query.orderBy(pageDomain.getOrderBy());
            }
            Page<${ClassName}> page = page(new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize()), query);
            return page;
        }
    #end

    /**
     * 查询${functionName}列表
     *
     * @param ${className} ${functionName}
     * @return ${functionName}
     */
    @Override
    public List<${ClassName}> select${ClassName}List(${ClassName} ${className})
    {
        QueryWrapper query = buildWrapper(${className});
        return ${className}Mapper.selectListByQuery(query);
    }

    public QueryWrapper buildWrapper(${ClassName} ${className}) {
        #foreach ($column in $columns)
            #if  ($column.queryType == "BETWEEN")
                Map<String, Object> params = ${className}.getParams();
                #break
            #end
        #end
            return query()
        #set($endNum = 0)
        #foreach ($column in $columns)
            #if ($column.query)
                #set($endNum = $endNum + 1)
            #end
        #end
        #set($connection = 'where')
        #set($queryNum = 0)
        #foreach ($column in $columns)
            #if($column.query)
                #set($queryNum = $queryNum + 1)
                #set($queryType = $column.queryType)
                #set($javaType = $column.javaType)
                #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
                #if($queryType == "EQ")
                    #set($queryType = 'eq')
                #elseif($queryType == "NE")
                    #set($queryType = 'gt')
                #elseif($queryType == "GT")
                    #set($queryType = 'gt')
                #elseif($queryType == "GTE")
                    #set($queryType = 'ge')
                #elseif($queryType == "LT")
                    #set($queryType = 'lt')
                #elseif($queryType == "LTE")
                    #set($queryType = 'le')
                #elseif($queryType == "LIKE")
                    #set($queryType = 'like')
                #end
                #if($queryType != "BETWEEN")
                        .${connection}(${SnakeClassName}.${column.columnName.toUpperCase()}.${queryType}(${className}.get${AttrName}()))#if($queryNum == $endNum);#end
                #else
                    .${connection}(${SnakeClassName}.${column.columnName.toUpperCase()}.between(params.get("begin${AttrName}"), params.get("end${AttrName}"))
                        .when(StringUtils.isNotAllBank(params.get("begin${AttrName}"), params.get("end${AttrName}"))))#if($queryNum == $endNum);#end
                #end
                #if($connection == 'where')
                    #set($connection = 'and')
                #end
            #end
        #end
    }

    /**
     * 新增${functionName}
     *
     * @param ${className} ${functionName}
     * @return 结果
     */
        #if($table.sub)
        @Transactional
        #end
    @Override
    public int insert${ClassName}(${ClassName} ${className})
    {
        #foreach ($column in $columns)
            #if($column.javaField == 'createTime')
                ${className}.setCreateTime(DateUtils.getNowDate());
            #end
        #end
        #if($table.sub)
            int rows = ${className}Mapper.insertSelective(${className});
            insert${subClassName}(${className});
            return rows;
        #else
            return ${className}Mapper.insertSelective(${className});
        #end
    }

    /**
     * 修改${functionName}
     *
     * @param ${className} ${functionName}
     * @return 结果
     */
        #if($table.sub)
        @Transactional
        #end
    @Override
    public int update${ClassName}(${ClassName} ${className})
    {
        #foreach ($column in $columns)
            #if($column.javaField == 'updateTime')
                ${className}.setUpdateTime(DateUtils.getNowDate());
            #end
        #end
        #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${className}.get${pkColumn.capJavaField}()));
            insert${subClassName}(${className});
        #end
        return ${className}Mapper.update(${className});
    }

    /**
     * 批量删除${functionName}
     *
     * @param ${pkColumn.javaField}s 需要删除的${functionName}主键
     * @return 结果
     */
        #if($table.sub)
        @Transactional
        #end
    @Override
    public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s)
    {
        #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.in(${pkColumn.javaField}s));
        #end
        return ${className}Mapper.deleteBatchByIds(Arrays.asList(${pkColumn.javaField}s));
    }

    /**
     * 删除${functionName}信息
     *
     * @param ${pkColumn.javaField} ${functionName}主键
     * @return 结果
     */
        #if($table.sub)
        @Transactional
        #end
    @Override
    public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
    {
        #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${pkColumn.javaField}));
        #end
        return ${className}Mapper.deleteById(${pkColumn.javaField});
    }
    #if($table.sub)

        /**
         * 新增${subTable.functionName}信息
         *
         * @param ${className} ${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.isNotEmpty(${subclassName}List))
            {
                for (${subClassName} ${subclassName} : ${subclassName}List)
                {
                    ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
                }
                    ${subclassName}Mapper.insertBatch(${subclassName}List);
            }
        }
    #end
}

3.6. 修改sub-domain.java.vm

package ${packageName}.domain;

    #foreach ($import in $subImportList)
    import ${import};
    #end
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import ${basePackage}.common.annotation.Excel;
import ${basePackage}.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * ${subTable.functionName}对象 ${subTableName}
 *
 * @author ${author}
 * @date ${datetime}
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Table("${subTableName}")
public class ${subClassName} extends BaseEntity {
private static final long serialVersionUID = 1L;

#foreach ($column in $subTable.columns)
    #if(!$table.isSuperColumn($column.javaField))
    /** $column.columnComment */
        #if($column.list)
            #set($parentheseIndex=$column.columnComment.indexOf("("))
            #if($papackage ${packageName}.service.impl;

            #if($table.crud || $table.sub)
            import com.mybatisflex.core.paginate.Page;
            #end
            import com.mybatisflex.core.query.QueryWrapper;
            import com.mybatisflex.spring.service.impl.ServiceImpl;
            import java.util.List;
            #foreach ($column in $columns)
            #if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
            import ${basePackage}.common.utils.DateUtils;
            #break
            #end
            #end
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.stereotype.Service;
            #if($table.crud || $table.sub)
            import ${basePackage}.common.core.page.PageDomain;
            import ${basePackage}.common.utils.StringUtils;
            #end
            import ${packageName}.mapper.${ClassName}Mapper;
            #if ($table.sub)
            import org.springframework.transaction.annotation.Transactional;
            import ${packageName}.domain.${subClassName};
            import ${packageName}.mapper.${subClassName}Mapper;
            #end
            import ${packageName}.domain.${ClassName};
            import ${packageName}.service.I${ClassName}Service;
            import java.util.Arrays;
            #foreach ($column in $columns)
            #if  ($column.queryType == "BETWEEN")
            import java.util.Map;
            #break
            #end
            #end


            import static ${packageName}.domain.table.${ClassName}TableDef.${tableName.toUpperCase()};
            #if ($table.sub)
            import static ${packageName}.domain.table.${subClassName}TableDef.${subTableName.toUpperCase()};
            #end

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

            #if($table.sub)
            @Autowired
            private ${subClassName}Mapper ${subclassName}Mapper;
            #end

            /**
            * 查询${functionName}
            *
            * @param ${pkColumn.javaField} ${functionName}主键
            * @return ${functionName}
            */
            @Override
            public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
            {
                ${ClassName} ${className} = ${className}Mapper.selectOneById(${pkColumn.javaField});
            #if($table.sub)
            List<${subClassName}> ${subclassName}List = ${subclassName}Mapper.selectListByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${className}.get${pkColumn.capJavaField}()));
                ${className}.set${subClassName}List(${subclassName}List);
            #end
            return ${className};
            }

            #if($table.crud || $table.sub)
            @Override
            public Page<${ClassName}> select${ClassName}Page(PageDomain pageDomain, ${ClassName} ${className}) {
            QueryWrapper query = buildWrapper(${className});
            if (StringUtils.isNotBlank(pageDomain.getOrderBy())) {
            query.orderBy(pageDomain.getOrderBy());
            }
            Page<${ClassName}> page = page(new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize()), query);
            return page;
            }
            #end

            /**
            * 查询${functionName}列表
            *
            * @param ${className} ${functionName}
            * @return ${functionName}
            */
            @Override
            public List<${ClassName}> select${ClassName}List(${ClassName} ${className})
            {
            QueryWrapper query = buildWrapper(${className});
            return ${className}Mapper.selectListByQuery(query);
            }

            public QueryWrapper buildWrapper(${ClassName} ${className}) {
            #foreach ($column in $columns)
            #if  ($column.queryType == "BETWEEN")
            Map<String, Object> params = ${className}.getParams();
            #break
            #end
            #end
            return query()
            #set($endNum = 0)
            #foreach ($column in $columns)
            #if ($column.query)
            #set($endNum = $endNum + 1)
            #end
            #end
            #set($connection = 'where')
            #set($queryNum = 0)
            #foreach ($column in $columns)
            #if($column.query)
            #set($queryNum = $queryNum + 1)
            #set($queryType = $column.queryType)
            #set($javaType = $column.javaType)
            #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
            #if($queryType == "EQ")
            #set($queryType = 'eq')
            #elseif($queryType == "NE")
            #set($queryType = 'gt')
            #elseif($queryType == "GT")
            #set($queryType = 'gt')
            #elseif($queryType == "GTE")
            #set($queryType = 'ge')
            #elseif($queryType == "LT")
            #set($queryType = 'lt')
            #elseif($queryType == "LTE")
            #set($queryType = 'le')
            #elseif($queryType == "LIKE")
            #set($queryType = 'like')
            #end
            #if($queryType != "BETWEEN")
            .${connection}(${tableName.toUpperCase()}.${column.columnName.toUpperCase()}.${queryType}(${className}.get${AttrName}()))#if($queryNum == $endNum);#end
            #else
            .${connection}(${tableName.toUpperCase()}.${column.columnName.toUpperCase()}.between(params.get("begin${AttrName}"), params.get("end${AttrName}"))
            .when(StringUtils.isNotAllBank(params.get("begin${AttrName}"), params.get("end${AttrName}"))))#if($queryNum == $endNum);#end
            #end
            #if($connection == 'where')
            #set($connection = 'and')
            #end
            #end
            #end
            }

            /**
            * 新增${functionName}
            *
            * @param ${className} ${functionName}
            * @return 结果
            */
            #if($table.sub)
            @Transactional
            #end
            @Override
            public int insert${ClassName}(${ClassName} ${className})
            {
            #foreach ($column in $columns)
            #if($column.javaField == 'createTime')
                ${className}.setCreateTime(DateUtils.getNowDate());
            #end
            #end
            #if($table.sub)
            int rows = ${className}Mapper.insertSelective(${className});
            insert${subClassName}(${className});
            return rows;
            #else
            return ${className}Mapper.insertSelective(${className});
            #end
            }

            /**
            * 修改${functionName}
            *
            * @param ${className} ${functionName}
            * @return 结果
            */
            #if($table.sub)
            @Transactional
            #end
            @Override
            public int update${ClassName}(${ClassName} ${className})
            {
            #foreach ($column in $columns)
            #if($column.javaField == 'updateTime')
                ${className}.setUpdateTime(DateUtils.getNowDate());
            #end
            #end
            #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${className}.get${pkColumn.capJavaField}()));
            insert${subClassName}(${className});
            #end
            return ${className}Mapper.update(${className});
            }

            /**
            * 批量删除${functionName}
            *
            * @param ${pkColumn.javaField}s 需要删除的${functionName}主键
            * @return 结果
            */
            #if($table.sub)
            @Transactional
            #end
            @Override
            public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s)
            {
            #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.in(${pkColumn.javaField}s));
            #end
            return ${className}Mapper.deleteBatchByIds(Arrays.asList(${pkColumn.javaField}s));
            }

            /**
            * 删除${functionName}信息
            *
            * @param ${pkColumn.javaField} ${functionName}主键
            * @return 结果
            */
            #if($table.sub)
            @Transactional
            #end
            @Override
            public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
            {
            #if($table.sub)
                ${subclassName}Mapper.deleteByCondition(${subTableName.toUpperCase()}.${subTableFkName.toUpperCase()}.eq(${pkColumn.javaField}));
            #end
            return ${className}Mapper.deleteById(${pkColumn.javaField});
            }
            #if($table.sub)

            /**
            * 新增${subTable.functionName}信息
            *
            * @param ${className} ${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.isNotEmpty(${subclassName}List))
            {
            for (${subClassName} ${subclassName} : ${subclassName}List)
            {
                ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
            }
                ${subclassName}Mapper.insertBatch(${subclassName}List);
            }
            }
            #end
            }
            rentheseIndex != -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')
            @JsonFormat(pattern = "yyyy-MM-dd")
            @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
            #else
            @Excel(name = "${comment}")
            #end
        #end
        #if ($column.columnName == $pkColumn.columnName)
        @Id(keyType= KeyType.Auto)
        #end
    private $column.javaType $column.javaField;

    #end
#end

}

4. 修改VelocityUtils

文件位于generator的util包下, 增加如下方法

public static String camelCaseToUpperCaseSnakeCase (String camelCase) {
    if (camelCase.length() == 1) {
        return camelCase.toUpperCase();
    }

    StringBuilder result = new StringBuilder();
    result.append(Character.toLowerCase(camelCase.charAt(0)));

    for (int i = 1; i < camelCase.length(); i++) {
        char currentChar = camelCase.charAt(i);
        if (Character.isUpperCase(currentChar)) {
            result.append('_');
            result.append(Character.toLowerCase(currentChar));
        } else {
            result.append(currentChar);
        }
    }
    return result.toString().toUpperCase();
}

在方法prepareContext中增加

velocityContext.put("SnakeClassName", camelCaseToUpperCaseSnakeCase(genTable.getClassName()));

在方法setSubVelocityContext中增加

context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName));

5. 修改BaseController

增加MyBatis-Flex列表分页相关方法

/**
 * 设置post请求分页数据
 */
protected PageDomain buildPostPage(Object clazz){
    try {
        Method getPageSizeMethod = clazz.getClass().getMethod("getPageSize");
        Method getPageNumMethod = clazz.getClass().getMethod("getPageNum");

        Integer pageSize = (Integer) getPageSizeMethod.invoke(clazz);
        Integer pageNum = (Integer) getPageNumMethod.invoke(clazz);

        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageSize(pageSize);
        pageDomain.setPageNum(pageNum);

        return pageDomain;
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
        return null;
    }
}


/**
 * 响应请求分页数据
 */
protected <T> TableDataInfo getFlexTable(Page<T> page)
{
    TableDataInfo rspData = new TableDataInfo();
    rspData.setCode(HttpStatus.SUCCESS);
    rspData.setMsg("查询成功");
    rspData.setRows(page.getRecords());
    rspData.setTotal(page.getTotalRow());
    return rspData;
}

6. 修改MyBatisConfig

文件在framework包下的config目录

package com.gz.framework.config;

import com.github.pagehelper.PageInterceptor;
import com.mybatisflex.core.FlexGlobalConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * Mybatis支持*匹配扫描包
 *
 * @author ruoyi
 */
@Configuration
public class MyBatisConfig
{
    @Bean
    public PageInterceptor pageInterceptor(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        return pageInterceptor;
    }

    @PostConstruct
    public void setFlexConfig()
    {
        FlexGlobalConfig globalConfig = FlexGlobalConfig.getDefaultConfig();
        // 关闭banner
        globalConfig.setPrintBanner(false);

        //设置数据库正常时的值
        globalConfig.setNormalValueOfLogicDelete("0");
        //设置数据已被删除时的值
        globalConfig.setDeletedValueOfLogicDelete("1");
    }
}

setFlexConfig中的其他配置可以参考MyBatis-Flex官方网站

7. 常见问题

7.1. APT生成问题

在启动项目的时候如果遇到APT生成问题, 可以按照如下操作

MyBatis-Flex官方网站常见问题:

https://mybatis-flex.com/zh/faq.html

7.2. 同类型实体类转换问题

在使用查询的时候, 可能会遇到同类型实体类转换异常问题

这时候需要在admin模块下的resources>META-INF> spring-devtools.properties进行如下配置:

restart.include.json=/com.alibaba.fastjson2.*.jar
restart.include.mapper=/mapper-[\\w-\\.].jar
restart.include.pagehelper=/pagehelper-[\\w-\\.].jar
restart.include.mybatis-flex=/mybatis-flex-[\\w-\\.]+jar

总结

经过如上整改, 即可得到一个若依框架基底, 然后生成的是mybatis-flex相关的代码了, 就不用一个一个去写sql了.

1

评论区