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

org.tinygroup.tinyscript.database.function.WriteDBFunction Maven / Gradle / Ivy

package org.tinygroup.tinyscript.database.function;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.tinygroup.tinyscript.ScriptContext;
import org.tinygroup.tinyscript.ScriptException;
import org.tinygroup.tinyscript.ScriptSegment;
import org.tinygroup.tinyscript.dataset.AbstractDataSet;
import org.tinygroup.tinyscript.dataset.DataSet;
import org.tinygroup.tinyscript.dataset.Field;
import org.tinygroup.tinyscript.function.AbstractScriptFunction;
import org.tinygroup.tinyscript.interpret.ResourceBundleUtil;
import org.tinygroup.tinyscript.interpret.ScriptContextUtil;
import org.tinygroup.tinyscript.interpret.ScriptUtil;

/**
 * 序表通过sql写入数据库
 * 
 * @author yancheng11334
 *
 */
public class WriteDBFunction extends AbstractScriptFunction {

	private static final int MAX_RECORDS = 200;

	public String getNames() {
		return "writeDB";
	}

	public String getBindingTypes() {
		return DataSet.class.getName();
	}

	public Object execute(ScriptSegment segment, ScriptContext context, Object... parameters) throws ScriptException {
		try {
			if (parameters == null || parameters.length == 0) {
				throw new ScriptException(ResourceBundleUtil.getDefaultMessage("function.parameter.empty", getNames()));
			} else if (checkParameters(parameters, 2)) {
				AbstractDataSet ds = (AbstractDataSet) parameters[0];
				String table = (String) parameters[1];
				return insertDataSet(ds, table, null, context);
			} else if (checkParameters(parameters, 3)) {
				AbstractDataSet ds = (AbstractDataSet) parameters[0];
				String table = (String) parameters[1];
				DataSource dataSource = (DataSource) parameters[2];
				return insertDataSet(ds, table, dataSource, context);
			} else {
				throw new ScriptException(ResourceBundleUtil.getDefaultMessage("function.parameter.error", getNames()));
			}
		} catch (ScriptException e) {
			throw e;
		} catch (Exception e) {
			throw new ScriptException(ResourceBundleUtil.getDefaultMessage("function.run.error", getNames()), e);
		}
	}

	/**
	 * 批量插入序表数据
	 * 
	 * @param ds
	 * @param table
	 * @param dataSource
	 * @return
	 * @throws ScriptException
	 */
	private Object insertDataSet(AbstractDataSet ds, String table, DataSource dataSource, ScriptContext context)
			throws Exception {
		DataSource newDataSource = dataSource == null
				? (DataSource) ScriptUtil.getVariableValue(context, ScriptContextUtil.getCustomBeanName(context))
				: dataSource;
		Connection conn = null;
		PreparedStatement ps = null;
		String insertSql = null;
		try {
			conn = newDataSource.getConnection();
			ResultSetMetaData rsmd = getTableMetaData(table, conn);
			Map maps = createMap(ds, rsmd);
			insertSql = createSQL(ds, table);

			conn.setAutoCommit(false);
			ps = conn.prepareStatement(insertSql);

			int count = 0;
			int[] result = new int[ds.getRows()];
			int i = 0, j = 0;
			try {
				for (i = 0; i < ds.getRows(); i++) {
					for (j = 0; j < ds.getColumns(); j++) {
						int targetSqlType = rsmd.getColumnType(maps.get(j));
						ps.setObject(j + 1, ds.getData(ds.getShowIndex(i), ds.getShowIndex(j)), targetSqlType);
					}
					count++;
					ps.addBatch();
					if (count % MAX_RECORDS == 0) {
						int[] temp = ps.executeBatch(); // 批量提交
						System.arraycopy(temp, 0, result, count - MAX_RECORDS, MAX_RECORDS); // 合并结果
					}
				}
				// 提交剩余记录
				int[] temp = ps.executeBatch();
				System.arraycopy(temp, 0, result, result.length - temp.length, temp.length); // 合并结果
				conn.commit();
			} catch (Exception e) {
				throw new ScriptException(ResourceBundleUtil.getResourceMessage("database",
						"database.sql.position.error", getNames(), insertSql, ds.getShowIndex(i), ds.getShowIndex(j)),
						e);
			}

			return result;

		} catch (ScriptException e) {
			throw e;
		} catch (Exception e) {
			throw new ScriptException(
					ResourceBundleUtil.getResourceMessage("database", "database.sql.error", getNames(), insertSql), e);
		} finally {
			if (ps != null) {
				ps.close();
			}
			if (conn != null) {
				conn.close();
			}
		}
	}

	private Map createMap(DataSet ds, ResultSetMetaData rsmd) throws Exception {
		Map maps = new HashMap(); // 定义物理表的字段名和列的映射关系
		Map result = new HashMap(); // 定义字段列和物理表列的映射关系
		for (int i = 1; i <= rsmd.getColumnCount(); i++) {
			maps.put(rsmd.getColumnName(i).toUpperCase(), i); // 转大写存储
		}
		List fields = ds.getFields();
		for (int i = 0; i < fields.size(); i++) {
			Field f = fields.get(i);
			String name = f.getName().toUpperCase();
			if (!maps.containsKey(name)) {
				throw new ScriptException(
						ResourceBundleUtil.getResourceMessage("database", "database.field.noexists", f.getName()));
			}
			result.put(i, maps.get(name));
		}
		return result;
	}

	private String createSQL(DataSet ds, String table) throws Exception {
		List fields = ds.getFields();
		StringBuilder sb = new StringBuilder();
		StringBuilder values = new StringBuilder();
		values.append(" values(");
		sb.append("insert into ").append(table);
		sb.append(" (");
		for (int i = 0; i < fields.size(); i++) {
			Field f = fields.get(i);
			if (i == fields.size() - 1) {
				sb.append(f.getName());
				values.append("?");
			} else {
				sb.append(f.getName()).append(",");
				values.append("?,");
			}
		}
		sb.append(")");
		values.append(")");
		sb.append(values);
		return sb.toString();
	}

	/**
	 * 获取表结构信息
	 * 
	 * @param table
	 * @param conn
	 * @return
	 * @throws Exception
	 */
	private ResultSetMetaData getTableMetaData(String table, Connection conn) throws Exception {
		String sql = "select * from " + table + " where 1=0; "; // 不查数据
		Statement sc = null;
		ResultSet rs = null;
		try {
			sc = conn.createStatement();
		    rs = sc.executeQuery(sql);
			return rs.getMetaData();
		} finally {
			if (rs !=null ){
				rs.close();
			}
			if (sc != null) {
				sc.close();
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy