Java 数据源不同于关系数据源和多维数据源之处为:它没有一个物理的数据库存储其字段和数据;但它可以通过Java类将任意一个含有数据的文件或报表通过解析后,在Smartbi中展现分析。 为实现自定义数据结构的查询要求,系统提供接口类 IJavaQueryData 供实现Java查询扩展开发。需实现的接口方法说明如下:
- ICalculateFieldSupport:声明该实现类支持计算字段。
- IOrderSupport:声明该实现类支持排序。
- loadConfigs:从保存的字符串中恢复配置信息。
- saveConfigs:保存配置信息。
- getConfigs:获取Java查询需要的配置信息。
- setConfigValue:设置配置信息。
- init:根据配置信息初始化Java查询对象。
- getParameters:返回参数对象。
- getOutputFields:返回Java查询的输出字段。
- setParameterValue: 设置参数值。
- getRowCount:返回总行数,返回Integer.MAX_VALUE表示未知总行数。
- getGridData:获取指定行的数据。
- close:关闭Java查询对象,关闭必要的资源。
package com.freequery.metadata; import java.util.List; import java.util.Map; import com.freequery.expression.Expression; import com.freequery.querydata.GridData; import com.freequery.report.OrderBy; /** * Java查询实现接口 */ public interface IJavaQueryData { /** * 声明该实现类支持计算字段 */ public interface ICalculateFieldSupport { public void addCalcField(String name, Expression exp); } /** * 声明该实现类支持排序 */ public interface IOrderSupport { public void setOrderBy(List<OrderBy> orderBy); } /** * 从保存的字符串中恢复配置信息 * * @param configStr * 配置字符串 */ public void loadConfigs(String configs); /** * 保存配置信息 * * @return 返回配置字符串 */ public String saveConfigs(); /** * 获取Java查询需要的配置信息 */ public List<JavaQueryConfig> getConfigs(); /** * 设置配置信息 * * @param key * 名称 * @param value * 配置值 */ public void setConfigValue(String key, String value); /** * 设置配置信息 */ public void setConfigValues(Map<String, String> configValues); /** * 根据配置信息初始化Java查询对象 */ public void init(); /** * 返回参数对象 */ public List<JavaQueryParameter> getParameters(); /** * 返回Java查询的输出字段 */ public List<JavaQueryOutputField> getOutputFields(); /** * 设置参数值 */ public void setParameterValue(String id, String value, String displayValue); /** * 返回总行数,返回Integer.MAX_VALUE表示未知总行数 */ public int getRowCount(); /** * 获取指定行的数据 */ public GridData getGridData(int from, int count); /** * 关闭Java查询对象,关闭必要的资源 */ public void close(); }
2、示例说明
以下部分说明如何在项目中进行Java查询的二次开发。
3、操作步骤
- 打开服务器部署文件smartbi.war,解压后将smartbi.war\WEB-INF\lib\目录下的 smartbi-FreeQuery.jar、smartbi-Common.jar 包加入到插件包项目的classpath中去。
撰写Java查询对象类MyJavaQuery.java,实现接口 IJavaQueryData。
package bof.ext.sample9_9; import java.io.*; import java.util.*; import java.util.Map.Entry; import bof.net.sf.json.JSONObject; import bof.util.StringUtil; import bof.util.ValueType; import com.freequery.metadata.*; import com.freequery.querydata.CellData; import com.freequery.querydata.GridData; /** * Java查询示例代码 */ public class MyJavaQuery implements IJavaQueryData { private Map<String, JavaQueryConfig> configs = new LinkedHashMap<String, JavaQueryConfig>(); private BufferedReader reader; private List<JavaQueryOutputField> outputFields; private int currentLine; public MyJavaQuery() { // 增加一个名称为FileName的配置项 addConfig("FileName", "文件名", "给定一个文件名", "test.csv", true); addConfig("Encoding", "编码", "编码方式", "GBK", true); } /** * 获取Java查询需要的配置信息 */ public List<JavaQueryConfig> getConfigs() { return new ArrayList<JavaQueryConfig>(configs.values()); } /** * 添加一个配置项 * * @param name * 名称 * @param alias * 别名 * @param desc * 描述 * @param defaultValue * 默认值 * @param notNull * 是否允许为空 */ private void addConfig(String name, String alias, String desc, String defaultValue, boolean notNull) { JavaQueryConfig p = new JavaQueryConfig(); p.setName(name); p.setAlias(alias); p.setDesc(desc); p.setValue(defaultValue); p.setNotNull(notNull); configs.put(name, p); } /** * 从保存的字符串中恢复配置信息 * * @param configStr * 配置字符串 */ public void loadConfigs(String configStr) { if (StringUtil.isNullOrEmpty(configStr)) return; JSONObject obj = JSONObject.fromString(configStr); configs.get("FileName").setValue(obj.has("FileName") ? obj.getString("FileName") : null); configs.get("Encoding").setValue(obj.has("Encoding") ? obj.getString("Encoding") : null); } /** * 保存配置信息 * * @return 返回配置字符串 */ public String saveConfigs() { JSONObject json = new JSONObject(); for (JavaQueryConfig config : configs.values()) json.put(config.getName(), config.getValue()); return json.toString(); } /** * 设置配置信息 * * @param key * 名称 * @param value * 配置值 */ public void setConfigValue(String key, String value) { configs.get(key).setValue(value); } /** * 设置配置信息 */ public void setConfigValues(Map<String, String> configValues) { for (Entry<String, String> config : configValues.entrySet()) configs.get(config.getKey()).setValue(config.getValue()); } /** * 根据配置信息初始化Java查询对象 */ public void init() { try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(configs.get( "FileName").getValue()), configs.get("Encoding").getValue())); String titleLine = reader.readLine(); String[] fields = titleLine.split(","); outputFields = new ArrayList<JavaQueryOutputField>(); for (String str : fields) { JavaQueryOutputField f = new JavaQueryOutputField(); f.setId(str); f.setName(str); f.setAlias(str); f.setDataType(ValueType.STRING); outputFields.add(f); } currentLine = 0; } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } catch (FileNotFoundException e) { throw new IllegalArgumentException(e); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 关闭Java查询对象,关闭必要的资源 */ public void close() { try { if (reader != null) { reader.close(); reader = null; } } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 返回参数对象 */ public List<JavaQueryParameter> getParameters() { return new ArrayList<JavaQueryParameter>(); } /** * 设置参数值 */ public void setParameterValue(String id, String value, String displayValue) { } /** * 返回Java查询的输出字段 */ public List<JavaQueryOutputField> getOutputFields() { return outputFields; } /** * 获取指定行的数据 */ public GridData getGridData(int from, int count) { try { if (currentLine > from) { reader.close(); reader = new BufferedReader(new InputStreamReader(new FileInputStream(configs.get( "FileName").getValue()), configs.get("Encoding").getValue())); reader.readLine(); currentLine = 0; } while (currentLine < from) { reader.readLine(); currentLine++; } List<List<CellData>> datas = new ArrayList<List<CellData>>(); for (int i = 0; i < count; i++) { String line = reader.readLine(); if (line == null) break; currentLine++; String[] fs = line.split(","); List<CellData> row = new ArrayList<CellData>(); for (int j = 0; j < fs.length; j++) { CellData c = new CellData(); c.setStringValue(fs[j]); row.add(c); } datas.add(row); } GridData d = new GridData(); List<String> headers = new ArrayList<String>(); for (JavaQueryOutputField f : outputFields) headers.add(f.getName()); d.setStringHeaders(headers); d.setData(datas); return d; } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } catch (FileNotFoundException e) { throw new IllegalArgumentException(e); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 返回总行数,返回Integer.MAX_VALUE表示未知总行数 */ public int getRowCount() { return Integer.MAX_VALUE; } }
- 在Smartbi中新建Java查询定义:
- 登录Smartbi,在【定制管理】→【数据管理】的"数据源"节点右键新建Java数据源并保存;
- 在刚才新建的"Java数据源"上右键"新建Java查询对象",在类名中输入正确的Java查询实现类全名(如bof.ext.sample9_9.MyJavaQuery)并检测默认配置;
- 再点击获取参数与结果集并保存;
- "保存"后就可以在"新建Java查询"中使用。
- 登录Smartbi,在【定制管理】→【数据管理】的"数据源"节点右键新建Java数据源并保存;
4、示例代码下载
示例代码下载: Sample9_9.zip