All Downloads are FREE. Search and download functionalities are using the official Maven repository.

online.sanen.unabo.sql.pipe.StreamPileline Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
package online.sanen.unabo.sql.pipe;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

import com.mhdt.Print;
import com.mhdt.degist.Validate;
import com.mhdt.toolkit.Reflect;

import online.sanen.unabo.api.Handel;
import online.sanen.unabo.api.exception.QueryException;
import online.sanen.unabo.api.structure.ChannelContext;
import online.sanen.unabo.api.structure.Column;
import online.sanen.unabo.api.structure.StreamConsumer;
import online.sanen.unabo.sql.Assembler;
import online.sanen.unabo.sql.Meta;
import online.sanen.unabo.template.JdbcUtils;
import online.sanen.unabo.template.SqlTemplate;

/**
 * @author LazyToShow 
* Date: 2018年9月11日
* Time: 上午10:56:44 */ public class StreamPileline implements SimplePileline, Handel { private Consumer>> consumer; private Map aliases; private int bufferSize = 10000; private Consumer> rowProcess; private int count; public StreamPileline(int count) { this.count = count; } public StreamPileline(int bufferSize, Consumer>> datas) { this(bufferSize, datas, null, null); } public StreamPileline(int bufferSize, Consumer>> consumer, Consumer> rowProcess, Map aliases) { this.consumer = consumer; this.rowProcess = rowProcess; this.aliases = aliases; if (bufferSize > 0) this.bufferSize = bufferSize; } public StreamPileline(int bufferSize, Function, Object> consumer, StreamConsumer datas, Map aliases) { if (bufferSize > 0) this.bufferSize = bufferSize; this.function_column_process = consumer; this.streamConsumer = datas; this.aliases = aliases; } Function, Object> function_column_process; StreamConsumer streamConsumer; @Override public Object handel(ChannelContext context, Object product) { String sql = context.getSql().toString(); Collection paramers = context.getParamers(); SqlTemplate template = (SqlTemplate) context.getTemplate(); try (Connection connection = template.getDataSource().getConnection()) { // connection.setAutoCommit(false); PreparedStatement ps = connection.prepareStatement(sql); initFetchSize(ps, context.productType()); // Set the parameters int index = 1; for (Iterator iterator = paramers.iterator(); iterator.hasNext(); ) { Object object = (Object) iterator.next(); try { Method method = Reflect.getMethod(ps, "set" + object.getClass().getSimpleName(), int.class, object.getClass()); method.invoke(ps, index++, object); } catch (Exception e) { ps.setString(index++, object.toString()); } } ps.execute(); ResultSet rs = ps.getResultSet(); Assembler.instance().threadLocalPut("meta", new Meta(rs.getMetaData())); // Assembly fields ResultSetMetaData metaData = rs.getMetaData(); List dataFields = new ArrayList<>(); List columns = new ArrayList<>(); for (int i = 0; i < metaData.getColumnCount(); i++) { Column dataField = new Column(); dataField.setName(metaData.getColumnLabel(i + 1)); dataField.setCls(metaData.getColumnClassName(i + 1)); dataField.setType(metaData.getColumnTypeName(i + 1)); dataFields.add(dataField); columns.add(dataField.getName()); } List> list = new LinkedList<>(); Object object = null; if (function_column_process != null) object = function_column_process.apply(dataFields); if (count > 0) { while (rs.next()) { list.add(populate(rs, columns)); if (list.size() == count) break; } return list; } else { while (rs.next()) { Map row = populate(rs, columns); if (rowProcess != null) { rowProcess.accept(row); } list.add(row); // Writes cached data if (list.size() == bufferSize) { consumeDatas(object, list); list = new LinkedList<>(); } } if (list.size() > 0) consumeDatas(object, list); } } catch (QueryException e) { throw e; } catch (Exception e) { throw new QueryException(e); } return null; } private void consumeDatas(Object object, List> list) { if (streamConsumer != null) streamConsumer.accept(object, list); else consumer.accept(list); } private Map populate(ResultSet rs, List columns) { Map map = new LinkedHashMap<>(columns.size()); columns.forEach(column -> { try { String key = (aliases != null && !Validate.isNullOrEmpty(aliases.get(column))) ? aliases.get(column) : column; Object value = JdbcUtils.getResultSetValue(rs, rs.findColumn(column)); map.put(key, value); } catch (SQLException e) { throw new QueryException(e); } }); return map; } }