需求場景:
若依框架的30張數(shù)據(jù)表 和 業(yè)務(wù)使用的數(shù)據(jù)表,同數(shù)據(jù)源,但分開的兩個庫,原生若依只支持主庫的代碼生成,故自己修改添加代碼來實(shí)現(xiàn)
若依多數(shù)據(jù)源的使用
效果展示
前端
修改頁面ruoyi-ui\src\views\tool\gen\importTable.vue
el-form 中新增 el-form-item
<el-form-item label="數(shù)據(jù)源">
<el-select v-model="queryParams.dataSource" placeholder="選擇數(shù)據(jù)源">
<el-option v-for="item in dataSources"
:label="item.desc"
:value="item.dataBaseCode"></el-option>
</el-select>
</el-form-item>
添加 data
// 查詢參數(shù)
data() {
return {
………………
………………
queryParams: {
pageNum: 1,
pageSize: 10,
dataSource: '',
tableName: undefined,
tableComment: undefined
},
//數(shù)據(jù)源列表
dataSources:[{dataBaseCode:'',desc:''}],
};
},
添加方法
// 顯示彈框
show() {
this.getTableSource();
this.getList();
this.visible = true;
},
//查詢數(shù)據(jù)源
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 添加方法
// 查詢數(shù)據(jù)源列表
export function tableSourceList(){
return request({
url: '/tool/gen/tableSourceList',
method: 'get',
})
}
后端
一:修改枚舉類
修改 數(shù)據(jù)源類型 枚舉類 ——> com.ruoyi.common.enums.DataSourceType
package com.ruoyi.common.enums;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 數(shù)據(jù)源
*
* @author ruoyi
*/
//使枚舉類返回前端是完整的對象,否則是只會有name屬性的String數(shù)組
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum DataSourceType {
/**
* 主庫
*/
MASTER("MASTER","若依框架數(shù)據(jù)庫"),
/**
* 從庫
*/
SLAVE("SLAVE","業(yè)務(wù)數(shù)據(jù)庫");
private String dataBaseCode;
private String desc;
//……省略get set 構(gòu)造函數(shù)……
}
二:添加接口
添加數(shù)據(jù)源列表獲取的接口 ——> com.ruoyi.generator.controller.GenController
/**
* 數(shù)據(jù)源列表
* @return
*/
@PreAuthorize("@ss.hasPermi('tool:gen:list')")
@GetMapping("/tableSourceList")
public AjaxResult tableSourceList(){
return AjaxResult.success(DataSourceType.values());
}
三:添加字段、屬性
在 genTable 表中添加字段 form_data_source
新增字段后,對應(yīng)的xml 中 resultMap、各種select以及insert、update方法,記得加上字段
查詢條件 添加數(shù)據(jù)源的屬性 ——> com.ruoyi.generator.domain.GenTable
public class GenTable extends BaseEntity
{
private static final long serialVersionUID = 1L;
………………
@NotBlank(message = "請選擇數(shù)據(jù)源")
private String tableSource;
/** 來自的數(shù)據(jù)源名 */
private String formDataSource;
………………
}
四:實(shí)現(xiàn)方法
修改查詢庫表 列表的方法 ——> com.wenhu.generator.service.selectDbTableList()
4.1:
在genTableMapper 新增 方法
/**
* 查詢已經(jīng)導(dǎo)入了的表名集合
*/
public List<String> selectExcludeGenTable();
對應(yīng)的 mapper xml中 GenTableMapper.xml
<select id="selectExcludeGenTable" resultType="java.lang.String">
select table_name from gen_table
</select>
4.2:
找到 GenTableMapper 的 selectDbTableList 方法
新增參數(shù) List excludeTables
/**
* 查詢據(jù)庫列表
*
* @param genTable 業(yè)務(wù)信息
* @return 數(shù)據(jù)庫表集合
*/
public List<GenTable> selectDbTableList(@Param("genTable") GenTable genTable, @Param("excludeTables") List<String> excludeTables);
修改sql語句 table_name not in 后面的參數(shù)使用 以及多參別稱的引用
<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') >= date_format(#{genTable.params.beginTime},'%y%m%d')
</if>
<if test="genTable.params.endTime != null and genTable.params.endTime != ''"><!-- 結(jié)束時間檢索 -->
AND date_format(create_time,'%y%m%d') <= date_format(#{genTable.params.endTime},'%y%m%d')
</if>
order by create_time desc
</select>
4.3:
/**
* 查詢據(jù)庫列表
*
* @param genTable 業(yè)務(wù)信息
* @return 數(shù)據(jù)庫表集合
*/
@Override
public List<GenTable> selectDbTableList(GenTable genTable) {
List<String> excludeGenTable = genTableMapper.selectExcludeGenTable();
//確保值不為空
if (StringUtils.isNotEmpty(genTable.getDataSource())) {
//找出對應(yīng)的枚舉
DataSourceType sourceType = DataSourceType.valueOf(genTable.getDataSource());
//手動切換數(shù)據(jù)源
DynamicDataSourceContextHolder.setDataSourceType(sourceType.name());
}
List<GenTable> genTables = genTableMapper.selectDbTableList(genTable,excludeGenTable);
//清空數(shù)據(jù)源變量
DynamicDataSourceContextHolder.clearDataSourceType();
return genTables;
}
五:修改導(dǎo)入表接口
因?yàn)闆]有引入 atomikos 分布式事務(wù)插件(若依官網(wǎng)提供的方法僅不分離版),所以在增刪改類業(yè)務(wù)需要開啟事務(wù)的方法中,Spring開啟事務(wù)后會維護(hù)一個ConnectionHolder,保證在整個事務(wù)下,都是用同一個數(shù)據(jù)庫連接
不想引入的簡單方式,對方法的邏輯順序進(jìn)行改造
controller:
/**
* 導(dǎo)入表結(jié)構(gòu)(保存)
*/
@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);
// 切換數(shù)據(jù)源并查詢表信息
// 確保值不為空
if(StringUtils.isNotEmpty(dataSource)){
//找出對應(yīng)的枚舉
DataSourceType sourceType = DataSourceType.valueOf(dataSource);
//手動切換數(shù)據(jù)源
DynamicDataSourceContextHolder.setDataSourceType(sourceType.name());
}else{
throw new ServiceException("指定了無效數(shù)據(jù)源");
}
//先把需要的表結(jié)構(gòu)數(shù)據(jù)、字段數(shù)據(jù)整理好
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
//導(dǎo)入到若依框架數(shù)據(jù)庫
DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
genTableService.importGenTable(tableList,dataSource);
//清空數(shù)據(jù)源變量
DynamicDataSourceContextHolder.clearDataSourceType();
return success();
}
service:
/**
* 查詢據(jù)庫列表
*
* @param tableNames 表名稱組
* @return 數(shù)據(jù)庫表集合
*/
@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;
}
/**
* 導(dǎo)入表結(jié)構(gòu)
*
* @param tableList 導(dǎo)入表列表
*/
@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("導(dǎo)入失敗:" + e.getMessage());
}
}
六:修改同步表接口
controller:
/**
* 同步數(shù)據(jù)庫
*/
@PreAuthorize("@ss.hasPermi('tool:gen:edit')")
@Log(title = "代碼生成", businessType = BusinessType.UPDATE)
@GetMapping("/synchDb/{tableName}")
public AjaxResult synchDb(@PathVariable("tableName") String tableName) {
//目標(biāo)表的最新數(shù)據(jù)
List<GenTableColumn> dbTableColumns = genTableService.getDbTableColumns(tableName);
genTableService.synchDb(tableName,dbTableColumns);
return success();
}
service:
新增方法
/**
* 獲取數(shù)據(jù)庫中指定表的當(dāng)前字段數(shù)據(jù)
* @param tableName
* @return
*/
@Override
public List<GenTableColumn> getDbTableColumns(String tableName){
GenTable genTable = genTableMapper.selectGenTableByName(tableName);
if(genTable==null){
throw new ServiceException("表結(jié)構(gòu)已被刪除,請重新導(dǎo)入");
}
if(StringUtils.isNotEmpty(genTable.getFormDataSource())) {
DynamicDataSourceContextHolder.setDataSourceType(genTable.getFormDataSource());
}
//最新的目標(biāo)表的字段
List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
DynamicDataSourceContextHolder.clearDataSourceType();
return genTableColumns;
}
修改原方法
synchDb方法中,只是將原來的臨時變量 dbTableColumns 在方法內(nèi)獲取的邏輯改為了用上面的方法單獨(dú)獲取
由controller調(diào)用傳參進(jìn)來
避免了事務(wù)中無法切換數(shù)據(jù)源的問題文章來源:http://www.zghlxwxcb.cn/news/detail-759345.html
/**
* 同步數(shù)據(jù)庫
*
* @param tableName 表名稱
*/
@Override
@Transactional
public void synchDb(String tableName,List<GenTableColumn> dbTableColumns) {
//找出已導(dǎo)入的當(dāng)前表
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("同步數(shù)據(jù)失敗,原表結(jié)構(gòu)不存在");
}
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()) {
// 如果是列表,繼續(xù)保留查詢方式/字典類型選項(xiàng)
column.setDictType(prevColumn.getDictType());
column.setQueryType(prevColumn.getQueryType());
}
if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
&& (column.isInsert() || column.isEdit())
&& ((column.isUsableColumn()) || (!column.isSuperColumn()))) {
// 如果是(新增/修改&非主鍵/非忽略及父屬性),繼續(xù)保留必填/顯示類型選項(xiàng)
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);
}
}
至此滿足了動態(tài)生成不同數(shù)據(jù)源的代碼的需求
出現(xiàn)了什么問題,歡迎查缺補(bǔ)漏,提出bug文章來源地址http://www.zghlxwxcb.cn/news/detail-759345.html
到了這里,關(guān)于RuoYi-Vue-generator 代碼生成模塊 動態(tài) 多數(shù)據(jù)源切換 前端+后臺的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!