Calcite 将 json 转化为 ResultSet

开始测试:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.calcite.schema.SchemaPlus;

import com.alibaba.fastjson.JSONObject;
import com.yonyou.ice.adapter.JsonSchema;

public class CalciteTest2 {
	public static void main(String[] args) throws Exception {
		long begin = System.currentTimeMillis();
		new CalciteTest2().run();
		long duration = System.currentTimeMillis() - begin;
		System.out.println("total:" + duration);
	}

	public void run() throws ClassNotFoundException, SQLException {
		Class.forName("org.apache.calcite.jdbc.Driver");
		Connection connection = DriverManager.getConnection("jdbc:calcite:");
		CalciteConnection optiqConnection = (CalciteConnection) connection.unwrap(CalciteConnection.class);
		SchemaPlus rootSchema = optiqConnection.getRootSchema();

		String json = "[{\"CUST_ID\":{\"a\":1},\"PROD_ID\":23.56,\"USER_ID\":300,\"USER_NAME\":\"user1\"},"
				+ "{\"USER_ID\":310,\"CUST_ID\":{\"a\":2},\"PROD_ID\":210.45,\"USER_NAME\":\"user2\"},"
				+ "{\"USER_ID\":320,\"CUST_ID\":{\"a\":3},\"PROD_ID\":210.46,\"USER_NAME\":\"user3\"},"
				+ "{\"USER_ID\":330,\"CUST_ID\":{\"a\":4},\"PROD_ID\":210.47,\"USER_NAME\":\"user4\"},"
				+ "{\"USER_ID\":340,\"CUST_ID\":{\"a\":5},\"PROD_ID\":210.48,\"USER_NAME\":\"user5\"},"
				+ "{\"USER_ID\":350,\"CUST_ID\":{\"a\":6},\"PROD_ID\":210.49,\"USER_NAME\":\"user6\"},"
				+ "{\"USER_ID\":360,\"CUST_ID\":{\"a\":7},\"PROD_ID\":210.40,\"USER_NAME\":\"user7\"}]";

		Statement statement = connection.createStatement();
		

		ResultSet resultSet = null;
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 1; i++) {
			rootSchema.add("abc", new JsonSchema("test", json));
			resultSet = statement.executeQuery(
					"select * from \"abc" + "\".\"test\" order by USER_ID desc limit 2 offset 2 ");
		}
		System.out.println("query:" + (System.currentTimeMillis() - begin));

		while (resultSet.next()) {
			JSONObject jo = new JSONObject();
			int n = resultSet.getMetaData().getColumnCount();
			for (int i = 1; i <= n; i++) {
				jo.put(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
			}
			System.out.println(jo.toJSONString());
		}
		resultSet.close();
		statement.close();
		connection.close();
	}
}

// End JdbcExample.java
Adapter  类封装
package com.yonyou.ice.adapter;

import org.apache.calcite.DataContext;
import org.apache.calcite.linq4j.AbstractEnumerable;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Enumerator;
import org.apache.calcite.linq4j.Linq4j;

import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.Types;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.schema.ScannableTable;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Statistic;
import org.apache.calcite.schema.Statistics;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.schema.impl.AbstractTable;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Pair;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Implementation of {@link org.apache.calcite.schema.Schema} that exposes the
 * public fields and methods in a json.
 */
public class JsonSchema extends AbstractSchema {
	private String target;
	private String topic;
	Map<String, Table> table = null;

	/**
	 * Creates a JsonSchema.
	 *
	 * @param target
	 *            Object whose fields will be sub-objects of the schema
	 */
	public JsonSchema(String topic, String target) {
		super();
		this.topic = topic;
		if (!target.startsWith("[")) {
			this.target = '[' + target + ']';
		} else {
			this.target = target;
		}
		final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();

		final Table table = fieldRelation();
		if (table != null) {
			builder.put(topic, table);

			this.table = builder.build();
		}
	}

	@Override
	public String toString() {
		return "JsonSchema(topic=" + topic + ":target=" + target + ")";
	}

	/**
	 * Returns the wrapped object.
	 *
	 * <p>
	 * May not appear to be used, but is used in generated code via
	 * {@link org.apache.calcite.util.BuiltInMethod#REFLECTIVE_SCHEMA_GET_TARGET}
	 * .
	 */
	public String getTarget() {
		return target;
	}

	@Override
	protected Map<String, Table> getTableMap() {
		return table;
	}

	/**
	 * Returns an expression for the object wrapped by this schema (not the
	 * schema itself).
	 */
	Expression getTargetExpression(SchemaPlus parentSchema, String name) {
		return Types.castIfNecessary(target.getClass(),
				Expressions.call(Schemas.unwrap(getExpression(parentSchema, name), JsonSchema.class),
						BuiltInMethod.REFLECTIVE_SCHEMA_GET_TARGET.method));
	}

	private <T> Table fieldRelation() {
		JSONArray jsonarr = JSON.parseArray(target);
		// final Enumerator<Object> enumerator = Linq4j.enumerator(list);
		return new JsonTable(jsonarr);
	}

	private static class JsonTable extends AbstractTable implements ScannableTable {
		private final JSONArray jsonarr;
		// private final Enumerable<Object> enumerable;

		public JsonTable(JSONArray obj) {
			this.jsonarr = obj;
		}

		public RelDataType getRowType(RelDataTypeFactory typeFactory) {
			final List<RelDataType> types = new ArrayList<RelDataType>();
			final List<String> names = new ArrayList<String>();
			JSONObject jsonobj = jsonarr.getJSONObject(0);
			for (String string : jsonobj.keySet()) {
				final RelDataType type;
				type = typeFactory.createJavaType(jsonobj.get(string).getClass());
				names.add(string);
				types.add(type);
			}
			if (names.isEmpty()) {
				names.add("line");
				types.add(typeFactory.createJavaType(String.class));
			}
			return typeFactory.createStructType(Pair.zip(names, types));
		}

		public Statistic getStatistic() {
			return Statistics.UNKNOWN;
		}

		public Enumerable<Object[]> scan(DataContext root) {
			return new AbstractEnumerable<Object[]>() {
				public Enumerator<Object[]> enumerator() {
					return new JsonEnumerator(jsonarr);
				}
			};
		}
	}

	public static class JsonEnumerator implements Enumerator<Object[]> {

		private Enumerator<Object[]> enumerator;

		public JsonEnumerator(JSONArray jsonarr) {
			List<Object[]> objs = new ArrayList<Object[]>();
			for (Object obj : jsonarr) {
				objs.add(((JSONObject) obj).values().toArray());
			}
			enumerator = Linq4j.enumerator(objs);
		}

		public Object[] current() {
			return (Object[]) enumerator.current();
		}

		public boolean moveNext() {
			return enumerator.moveNext();
		}

		public void reset() {
			enumerator.reset();
		}

		public void close() {
			enumerator.close();
		}

	}
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值