RuoYi-Vue-generator 代码生成模块 动态 多数据源切换 前端+后台

这篇具有很好参考价值的文章主要介绍了RuoYi-Vue-generator 代码生成模块 动态 多数据源切换 前端+后台。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求场景:

若依框架的30张数据表 和 业务使用的数据表,同数据源,但分开的两个库,原生若依只支持主库的代码生成,故自己修改添加代码来实现

若依多数据源的使用

效果展示

若依多数据源切换,vue.js,javascript,spring boot,database,java
若依多数据源切换,vue.js,javascript,spring boot,database,java

前端

修改页面ruoyi-ui\src\views\tool\gen\importTable.vue
el-form 中新增 el-form-item

	<el-form-item label="数据源">
        <el-select v-model="queryParams.dataSource" placeholder="选择数据源">
          <el-option v-for="item in dataSources"
                     :label="item.desc"
                     :value="item.dataBaseCode"></el-option>
        </el-select>
      </el-form-item>

添加 data

// 查询参数
 data() {
    return {
    	………………
    	………………
	      queryParams: {
	        pageNum: 1,
	        pageSize: 10,
	        dataSource: '',
	        tableName: undefined,
	        tableComment: undefined
	      },
	      //数据源列表
	      dataSources:[{dataBaseCode:'',desc:''}],
      };
  },

添加方法

	// 显示弹框
    show() {
      this.getTableSource();
      this.getList();
      this.visible = true;
    },
	//查询数据源
    getTableSource(){
      tableSourceList().then(res=>{
        if(res.code===200){
          this.dataSources=res.data;
          if(this.queryParams.dataSource===''){
            this.queryParams.dataSource=this.dataSources[0].dataBaseCode
          }
        }
      })
    },

ruoyi-ui\src\api\tool\gen.js 添加方法

// 查询数据源列表
export function tableSourceList(){
  return request({
    url: '/tool/gen/tableSourceList',
    method: 'get',
  })
}

后端

一:修改枚举类

修改 数据源类型 枚举类 ——> com.ruoyi.common.enums.DataSourceType

package com.ruoyi.common.enums;

import com.fasterxml.jackson.annotation.JsonFormat;

/**
 * 数据源
 * 
 * @author ruoyi
 */
//使枚举类返回前端是完整的对象,否则是只会有name属性的String数组
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum DataSourceType {
    /**
     * 主库
     */
    MASTER("MASTER","若依框架数据库"),

    /**
     * 从库
     */
    SLAVE("SLAVE","业务数据库");

    private String dataBaseCode;

    private String desc;
    
    //……省略get set 构造函数……
}

二:添加接口

添加数据源列表获取的接口 ——> com.ruoyi.generator.controller.GenController

/**
     * 数据源列表
     * @return
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:list')")
    @GetMapping("/tableSourceList")
    public AjaxResult tableSourceList(){
        return AjaxResult.success(DataSourceType.values());
    }

三:添加字段、属性

在 genTable 表中添加字段 form_data_source
新增字段后,对应的xml 中 resultMap、各种select以及insert、update方法,记得加上字段

查询条件 添加数据源的属性 ——> com.ruoyi.generator.domain.GenTable

public class GenTable extends BaseEntity
{
    private static final long serialVersionUID = 1L;

	………………
	
    @NotBlank(message = "请选择数据源")
    private String tableSource;

	/** 来自的数据源名 */
    private String formDataSource;

	………………
}

四:实现方法

修改查询库表 列表的方法 ——> com.wenhu.generator.service.selectDbTableList()

4.1:

在genTableMapper 新增 方法

 /**
 * 查询已经导入了的表名集合
 */
 public List<String> selectExcludeGenTable();

对应的 mapper xml中 GenTableMapper.xml

	<select id="selectExcludeGenTable" resultType="java.lang.String">
		select table_name from gen_table
	</select>
4.2:

找到 GenTableMapper 的 selectDbTableList 方法
新增参数 List excludeTables

/**
     * 查询据库列表
     *
     * @param genTable 业务信息
     * @return 数据库表集合
     */
    public List<GenTable> selectDbTableList(@Param("genTable") GenTable genTable, @Param("excludeTables") List<String> excludeTables);

修改sql语句 table_name not in 后面的参数使用 以及多参别称的引用

<select id="selectDbTableList" parameterType="com.ruoyi.generator.domain.GenTable" resultMap="GenTableResult">
		select table_name, table_comment, create_time, update_time from information_schema.tables
		where table_schema = (select database())
		AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'
		AND table_name NOT IN
		<foreach collection="excludeTables" item="tName" open="(" close=")" separator=",">
			#{tName}
		</foreach>
		<if test="genTable.tableName != null and genTable.tableName != ''">
			AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%'))
		</if>
		<if test="genTable.tableComment != null and genTable.tableComment != ''">
			AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%'))
		</if>
		<if test="genTable.params.beginTime != null and genTable.params.beginTime != ''"><!-- 开始时间检索 -->
			AND date_format(create_time,'%y%m%d') &gt;= date_format(#{genTable.params.beginTime},'%y%m%d')
		</if>
		<if test="genTable.params.endTime != null and genTable.params.endTime != ''"><!-- 结束时间检索 -->
			AND date_format(create_time,'%y%m%d') &lt;= date_format(#{genTable.params.endTime},'%y%m%d')
		</if>
        order by create_time desc
	</select>
4.3:
	/**
     * 查询据库列表
     * 
     * @param genTable 业务信息
     * @return 数据库表集合
     */
    @Override
    public List<GenTable> selectDbTableList(GenTable genTable) {
        List<String> excludeGenTable = genTableMapper.selectExcludeGenTable();
        //确保值不为空
        if (StringUtils.isNotEmpty(genTable.getDataSource())) {
            //找出对应的枚举
            DataSourceType sourceType = DataSourceType.valueOf(genTable.getDataSource());
            //手动切换数据源
            DynamicDataSourceContextHolder.setDataSourceType(sourceType.name());
        }
        List<GenTable> genTables = genTableMapper.selectDbTableList(genTable,excludeGenTable);
        //清空数据源变量
        DynamicDataSourceContextHolder.clearDataSourceType();
        return genTables;
    }

五:修改导入表接口

因为没有引入 atomikos 分布式事务插件(若依官网提供的方法仅不分离版),所以在增删改类业务需要开启事务的方法中,Spring开启事务后会维护一个ConnectionHolder,保证在整个事务下,都是用同一个数据库连接
不想引入的简单方式,对方法的逻辑顺序进行改造

controller:
	/**
     * 导入表结构(保存)
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:import')")
    @Log(title = "代码生成", businessType = BusinessType.IMPORT)
    @PostMapping("/importTable")
    public AjaxResult importTableSave(String tables,
                                      String dataSource)
    {
        String[] tableNames = Convert.toStrArray(tables);
        // 切换数据源并查询表信息
        // 确保值不为空
        if(StringUtils.isNotEmpty(dataSource)){
            //找出对应的枚举
            DataSourceType sourceType = DataSourceType.valueOf(dataSource);
            //手动切换数据源
            DynamicDataSourceContextHolder.setDataSourceType(sourceType.name());
        }else{
            throw new ServiceException("指定了无效数据源");
        }
        //先把需要的表结构数据、字段数据整理好
        List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
        //导入到若依框架数据库
        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
        genTableService.importGenTable(tableList,dataSource);
        //清空数据源变量
        DynamicDataSourceContextHolder.clearDataSourceType();
        return success();
    }
service:
/**
     * 查询据库列表
     *
     * @param tableNames 表名称组
     * @return 数据库表集合
     */
    @Override
    public List<GenTable> selectDbTableListByNames(String[] tableNames) {
        List<GenTable> genTables = genTableMapper.selectDbTableListByNames(tableNames);
        String operName = SecurityUtils.getUsername();
        for (int i = 0; i < genTables.size(); i++) {
            String tableName = genTables.get(i).getTableName();
            GenUtils.initTable(genTables.get(i), operName);
            List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
            genTables.get(i).setColumns(genTableColumns);
        }
        return genTables;
    }
/**
     * 导入表结构
     *
     * @param tableList 导入表列表
     */
    @Override
    @Transactional
    public void importGenTable(List<GenTable> tableList,
                               String dataSource) {
        try {
            for (GenTable table : tableList) {
            	table.setFormDataSource(dataSource);
                int row = genTableMapper.insertGenTable(table);
                if (row > 0) {
                    for (GenTableColumn column : table.getColumns()) {
                        GenUtils.initColumnField(column, table);
                        genTableColumnMapper.insertGenTableColumn(column);
                    }
                }
            }
        } catch (Exception e) {
            throw new ServiceException("导入失败:" + e.getMessage());
        }
    }

六:修改同步表接口

controller:
	/**
     * 同步数据库
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:edit')")
    @Log(title = "代码生成", businessType = BusinessType.UPDATE)
    @GetMapping("/synchDb/{tableName}")
    public AjaxResult synchDb(@PathVariable("tableName") String tableName) {
        //目标表的最新数据
        List<GenTableColumn> dbTableColumns = genTableService.getDbTableColumns(tableName);
        genTableService.synchDb(tableName,dbTableColumns);
        return success();
    }
service:

新增方法

	/**
     * 获取数据库中指定表的当前字段数据
     * @param tableName
     * @return
     */
    @Override
    public List<GenTableColumn> getDbTableColumns(String tableName){
        GenTable genTable = genTableMapper.selectGenTableByName(tableName);
        if(genTable==null){
            throw new ServiceException("表结构已被删除,请重新导入");
        }
        if(StringUtils.isNotEmpty(genTable.getFormDataSource())) {
            DynamicDataSourceContextHolder.setDataSourceType(genTable.getFormDataSource());
        }
        //最新的目标表的字段
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
        DynamicDataSourceContextHolder.clearDataSourceType();
        return genTableColumns;
    }

修改原方法
synchDb方法中,只是将原来的临时变量 dbTableColumns 在方法内获取的逻辑改为了用上面的方法单独获取
由controller调用传参进来
避免了事务中无法切换数据源的问题

	/**
     * 同步数据库
     *
     * @param tableName 表名称
     */
    @Override
    @Transactional
    public void synchDb(String tableName,List<GenTableColumn> dbTableColumns) {
        //找出已导入的当前表
        GenTable table = genTableMapper.selectGenTableByName(tableName);
        //表的字段
        List<GenTableColumn> tableColumns = table.getColumns();
        Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
        
        if (StringUtils.isEmpty(dbTableColumns)) {
            throw new ServiceException("同步数据失败,原表结构不存在");
        }
        List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());

        dbTableColumns.forEach(column -> {
            GenUtils.initColumnField(column, table);
            if (tableColumnMap.containsKey(column.getColumnName())) {
                GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
                column.setColumnId(prevColumn.getColumnId());
                if (column.isList()) {
                    // 如果是列表,继续保留查询方式/字典类型选项
                    column.setDictType(prevColumn.getDictType());
                    column.setQueryType(prevColumn.getQueryType());
                }
                if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
                        && (column.isInsert() || column.isEdit())
                        && ((column.isUsableColumn()) || (!column.isSuperColumn()))) {
                    // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项
                    column.setIsRequired(prevColumn.getIsRequired());
                    column.setHtmlType(prevColumn.getHtmlType());
                }
                genTableColumnMapper.updateGenTableColumn(column);
            } else {
                genTableColumnMapper.insertGenTableColumn(column);
            }
        });

        List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(delColumns)) {
            genTableColumnMapper.deleteGenTableColumns(delColumns);
        }
    }

至此满足了动态生成不同数据源的代码的需求
出现了什么问题,欢迎查缺补漏,提出bug文章来源地址https://www.toymoban.com/news/detail-759345.html

到了这里,关于RuoYi-Vue-generator 代码生成模块 动态 多数据源切换 前端+后台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 若依ruoyi——手把手教你制作自己的管理系统【三、代码生成】

    增删改查导一( ̄︶ ̄*)) 按钮换个色一((* ̄3 ̄)╭ ********* 专栏略长 ==== 爆肝万字 ==== 细节狂魔 ==== 请准备好一键三连 ********* 修改后的页面: 干干净净贼舒服一Ψ( ̄∀ ̄)Ψ——Ψ( ̄∀ ̄)Ψ一 接下来我们要达到的效果如下(自定义菜单 里面有列表数据回显+增删改查) 一、修改

    2023年04月25日
    浏览(35)
  • mybatis-generator代码生成器的使用与配置

    官网的MyBatis Generator使用介绍,请点击下面的链接: 链接 MyBatis Generator 生成的文件包含三类: (1)Model实体文件,一个数据库表对应生成一个 Model 实体; (2)Mapper接口文件,数据数操作方法都在此接口中定义; (3)Mapper XML配置文件 在pom.xml文件添加如下依赖: 代码如下

    2024年02月14日
    浏览(29)
  • 5.6 Mybatis代码生成器Mybatis Generator (MBG)实战详解

    本文我们主要实战Mybatis官方的代码生成器:Mybatis Generator(MBG),掌握它以后,可以简化大部分手写代码,我们只需要写复杂逻辑代码! 通过前几篇,我们掌握了在SpringBoot下Mybatis的基本用法,操作步骤回顾一下: 创建与MySQL表对应的Java PO对象,字段一一对应; 创建Mapper接口,

    2024年02月05日
    浏览(31)
  • mybatis-plus-generator-ui 可视化代码生成器!

    它提供交互式的Web UI用于生成兼容mybatis-plus框架的相关功能代码,包括Entity,Mapper,Mapper.xml,Service,Controller等。 可以自定义模板以及各类输出参数,也可通过SQL查询语句直接生成代码。 git地址 :https://github.com/davidfantasy/mybatis-plus-generator-ui 1、引入依赖 2、新建程序入口,以main函

    2024年02月08日
    浏览(48)
  • springboot的代码生成器mybatis-plus-generator-ui

    GeberatorUIServer 在springboot的test中运行 这段代码是一个用于生成 MyBatis-Plus 代码的工具类,进行解释: 这是一个名为 GeberatorUIServer 的类。 这是程序的入口方法,即 main 方法。 这段代码创建了一个 GeneratorConfig 对象,并使用链式调用的方式设置了一系列参数: jdbcUrl :数据库连

    2024年02月10日
    浏览(33)
  • 自动化生成代码:MyBatis 的 Generator与MyBatis-Plus 的 AutoGenerator

    自动化生成代码是现在一种非常常见的技术,它可以大大提高开发效率,减少重复劳动。而在 Java 开发中,MyBatis 是一个非常流行的 ORM 框架,而其中的 Generator 和 MyBatis-Plus 中的 AutoGenerator 是两个非常好用的自动化代码生成工具,下面我们来分别介绍一下它们的使用。 MyBati

    2024年02月03日
    浏览(35)
  • 【AI人工智能】用于代码生成的大型语言模型 Large Language Models for Code Generation

      目录 Large Language Models for Code Generation – Part 1用于代码生成的大型语言模型——第 1 部分 Introduction

    2024年02月08日
    浏览(51)
  • MyBatis-Plus 可视化代码生成器mybatis-plus-generator-ui

    在基于Mybatis的开发模式中,很多开发者还会选择Mybatis-Plus来辅助功能开发,以此提高开发的效率。虽然Mybatis也有代码生成的工具,但Mybatis-Plus由于在Mybatis基础上做了一些调整,因此,常规的生成工具生成的代码还有一些不太符合预期。而且对于多数据库的支持不是很好。

    2024年02月04日
    浏览(35)
  • Java:mybatis-plus-generator-ui 基于Mybatis-Plus的代码自助生成器

    引用官方文档上的简介: 提供交互式的Web UI用于生成兼容mybatis-plus框架的相关功能代码,包括Entity,Mapper,Mapper.xml,Service,Controller等 ,可以自定义模板以及各类输出参数,也可通过SQL查询语句直接生成代码。 文档 github: https://github.com/davidfantasy/mybatis-plus-generator-ui gitee: https://g

    2024年02月10日
    浏览(40)
  • SpringBoot 集成MyBatis-Plus-Generator(最新版3.5.2版本)自动生成代码(附带集成MyBatis-Plus)

    快速入门 代码生成器配置(新) spring boot 2.3.12.RELEASE mybatis 3.5.2 mybatis plus 3.5.2 mybatis plus generator 3.5.2 mysql 8.0.17 velocity 2.3 hutool 5.8.15 druid 1.2.8 lombok 自带 示例程序选择的技术目前各项技术的稳定版本。 相信大家厌烦重复的造轮子过程,编写与数据库表对应的实体类,接着再进

    2024年02月21日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包