前提:需要两张约定的表,这是dataway需要的
这里基于【mysql】数据库演示,所以在 dataway的依赖 jar 包中选择 “META-INF/hasor-framework/mysql” 目录下的两张表粘贴到自己的数据库下 
CREATE TABLE `interface_info` (
`api_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`api_method` varchar(12) NOT NULL COMMENT 'HttpMethod:GET、PUT、POST',
`api_path` varchar(512) NOT NULL COMMENT '拦截路径',
`api_status` int(2) NOT NULL COMMENT '状态:0草稿,1发布,2有变更,3禁用',
`api_comment` varchar(255) NULL COMMENT '注释',
`api_type` varchar(24) NOT NULL COMMENT '脚本类型:SQL、DataQL',
`api_script` mediumtext NOT NULL COMMENT '查询脚本:xxxxxxx',
`api_schema` mediumtext NULL COMMENT '接口的请求/响应数据结构',
`api_sample` mediumtext NULL COMMENT '请求/响应/请求头样本数据',
`api_create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`api_gmt_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`api_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='Dataway 中的API';
CREATE TABLE `interface_release` (
`pub_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Publish ID',
`pub_api_id` int(11) NOT NULL COMMENT '所属API ID',
`pub_method` varchar(12) NOT NULL COMMENT 'HttpMethod:GET、PUT、POST',
`pub_path` varchar(512) NOT NULL COMMENT '拦截路径',
`pub_status` int(2) NOT NULL COMMENT '状态:0有效,1无效(可能被下线)',
`pub_type` varchar(24) NOT NULL COMMENT '脚本类型:SQL、DataQL',
`pub_script` mediumtext NOT NULL COMMENT '查询脚本:xxxxxxx',
`pub_script_ori` mediumtext NOT NULL COMMENT '原始查询脚本,仅当类型为SQL时不同',
`pub_schema` mediumtext NULL COMMENT '接口的请求/响应数据结构',
`pub_sample` mediumtext NULL COMMENT '请求/响应/请求头样本数据',
`pub_release_time`datetime DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间(下线不更新)',
PRIMARY KEY (`pub_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='Dataway API 发布历史。';
create index idx_interface_release on interface_release (pub_api_id);
这里有两种方式,第一种是基于主数据源(跟系统所使用同一个数据库),第二种是独立数据源(跟系统使用不同的数据库,比如系统使用的主数据库,dataway使用从数据库)。 第一种方式可以去【这里】查看。这里演示第二种方式,基于ruoyi-vue项目。
第一步:新增一个maven模块 ruoyi-hasor

第二步:给这个ruoyi-hasor引入jar
<dependency>
<groupId>net.hasor</groupId>
<artifactId>hasor-dataway</artifactId>
<version>${hasor.version}</version>
</dependency>
<dependency>
<groupId>net.hasor</groupId>
<artifactId>hasor-spring</artifactId>
<version>${hasor.version}</version>
</dependency>
<dependency>
<groupId>net.hasor</groupId>
<artifactId>hasor-dataql-fx</artifactId>
<version>${hasor.version}</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
如果 不是用若依框架(没有ruoyi-common模块),那就再把下面的jar引入进去即可:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
第三步:ruoyi-hasor模块新建三个文件夹,并分别新建以下java文件
chain:存放关于dataway日志打印、兼容设置等java文件 config:存放关于dataway组件注册相关java文件 core:存放关于dataway上下文、数据源配置相关java文件 
FxSqlCheckChain:
package com.ruoyi.chain;
import com.ruoyi.common.utils.StringUtils;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FxSqlCheckChain implements FxSqlCheckChainSpi {
private static final Logger log = LoggerFactory.getLogger(FxSqlCheckChain.class);
public static FxSqlCheckChain getInstance() {
return new FxSqlCheckChain();
}
@Override
public int doCheck(FxSqlInfo fxSqlInfo) throws Throwable {
String sourceName = fxSqlInfo.getSourceName();
if (StringUtils.isNotEmpty(sourceName)) {
log.info("【dataway】dataSource ==>:{}", sourceName);
}
log.info("【dataway】sql ==>:{}", fxSqlInfo.getQueryString().trim());
log.info("【dataway】params ==>: {}", fxSqlInfo.getQueryParams());
return FxSqlCheckChainSpi.NEXT;
}
}
PreExecuteChain
package com.ruoyi.chain;
import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.utils.future.BasicFuture;
import org.apache.commons.collections4.MapUtils;
import java.util.HashMap;
import java.util.Map;
public class PreExecuteChain implements PreExecuteChainSpi {
public static PreExecuteChain getInstance() {
return new PreExecuteChain();
}
@Override
public void preExecute(ApiInfo apiInfo, BasicFuture<Object> basicFuture) {
Map<String, Object> parameter = apiInfo.getParameterMap();
parameter.putAll(MapUtils.emptyIfNull(loginUserAuthParams()));
}
private Map<String, Object> loginUserAuthParams () {
Map<String, Object> authParams = new HashMap<>();
return authParams;
}
}
ReturnProcessChain
package com.ruoyi.chain;
import com.ruoyi.common.core.domain.AjaxResult;
import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.ResultProcessChainSpi;
public class ReturnProcessChain implements ResultProcessChainSpi {
public static ReturnProcessChain getInstance() {
return new ReturnProcessChain();
}
@Override
public Object callAfter(boolean formPre, ApiInfo apiInfo, Object result) {
if (apiInfo.isPerform() || apiInfo.getParameterMap().containsKey("SELF_CALL")) {
return result;
}
apiInfo.getOptionMap().put("resultStructure", false);
return AjaxResult.success(result);
}
@Override
public Object callError(boolean formPre, ApiInfo apiInfo, Throwable e) {
if (apiInfo.isPerform()) {
return ResultProcessChainSpi.super.callError(formPre, apiInfo, e);
}
apiInfo.getOptionMap().put("resultStructure", false);
return AjaxResult.error( "系统繁忙");
}
}
HasorConfig
package com.ruoyi.config;
import com.ruoyi.core.HasorContextHandle;
import net.hasor.dataway.DatawayService;
import net.hasor.spring.boot.EnableHasor;
import net.hasor.spring.boot.EnableHasorWeb;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@EnableHasor()
@EnableHasorWeb()
@Configuration
public class HasorConfig {
@Bean
public DatawayService datawayService() {
return HasorContextHandle.getInstance(DatawayService.class);
}
}
HasorContextHandle
package com.ruoyi.core;
import net.hasor.core.AppContext;
public class HasorContextHandle {
private static AppContext appContext;
public static void setAppContext(AppContext appContext) {
HasorContextHandle.appContext = appContext;
}
public static AppContext getAppContext() {
return appContext;
}
public static <T> T getInstance(Class<T> clazz) {
return appContext.getInstance(clazz);
}
}
HasorModule
注意 @Value(“${spring.datasource.druid.slave.url}”)等这里面的路径就是后文中从库的信息,需要改成你自己的
package com.ruoyi.core;
import com.alibaba.druid.pool.DruidDataSource;
import com.ruoyi.chain.FxSqlCheckChain;
import com.ruoyi.chain.PreExecuteChain;
import com.ruoyi.chain.ReturnProcessChain;
import net.hasor.core.ApiBinder;
import net.hasor.core.AppContext;
import net.hasor.core.DimModule;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.dataway.spi.ResultProcessChainSpi;
import net.hasor.db.JdbcModule;
import net.hasor.db.Level;
import net.hasor.spring.SpringModule;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@DimModule
@Component
public class HasorModule implements SpringModule {
@Value("${spring.datasource.druid.slave.url}")
private String url;
@Value("${spring.datasource.druid.slave.username}")
private String username;
@Value("${spring.datasource.druid.slave.password}")
private String password;
@Override
public void loadModule(ApiBinder apiBinder) throws Throwable {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestWhileIdle(true);
dataSource.setTimeBetweenEvictionRunsMillis(60000);
dataSource.setMaxActive(20);
dataSource.setInitialSize(5);
apiBinder.installModule(new JdbcModule(Level.Full, dataSource));
apiBinder.bindSpiListener(FxSqlCheckChainSpi.class, FxSqlCheckChain.getInstance());
apiBinder.bindSpiListener(PreExecuteChainSpi.class, PreExecuteChain.getInstance());
apiBinder.bindSpiListener(ResultProcessChainSpi.class, ReturnProcessChain.getInstance());
}
@Override
public void onStart(AppContext appContext) {
HasorContextHandle.setAppContext(appContext);
}
}
第四步:在启动模块配置文件中添加dataway配置和从库路径
我的启动模块是ruoyi-admin,所以在ruoyi-admin模块下application.yml 或者 application.properties配置文件中添加
HASOR_DATAQL_DATAWAY: true
HASOR_DATAQL_DATAWAY_ADMIN: true
HASOR_DATAQL_DATAWAY_API_URL: /api/
HASOR_DATAQL_DATAWAY_UI_URL: /api/interface-ui/

slave:
enabled: true
url: jdbc:mysql:
username: root
password: root

第五步:在启动模块下的pom文件中引入刚才新建的ruoyi-hasor模块
引入之后就能正常启动加载了 我这里的启动模块是ruoyi-admin,所以如果不一样,需要改成你自己的
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-hasor</artifactId>
</dependency>

第六步:开放dataway的ui可视化界面的路径权限
前提是上述第四步的界面开关必须打开 就是这两个: HASOR_DATAQL_DATAWAY: true HASOR_DATAQL_DATAWAY_ADMIN: true 这一步比较重要!!!
上面第四步中配置的路径:"/api/interface-ui/"需要在权限配置中放开,否则访问不到。我这里使用的若依框架中是在SecurityConfig这个文件中设置路由权限的,你们需要改成你们自己的 
第七步:运行项目
项目路径+datawayui路径,例如: http://127.0.0.1:9090/api/interface-ui/#/
运行结果
 账号密码应该默认的 admin / admin
|