package com.taobao.yugong.translator;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import com.taobao.yugong.common.YuGongConstants;
import com.taobao.yugong.common.audit.RecordDumper;
import com.taobao.yugong.common.db.meta.ColumnMeta;
import com.taobao.yugong.common.db.meta.ColumnValue;
import com.taobao.yugong.common.model.record.Record;
import com.taobao.yugong.common.utils.thread.ExecutorTemplate;
/**
* 根据bill_out_id关联查询bill_out表获取数据
*
* @author agapple 2014-5-13 下午1:13:18
*/
public class MidBillOutDetailDataTranslator extends BackTableDataTranslator implements DataTranslator {
private static final Logger ignoreLogger = LoggerFactory.getLogger("ignore");
private int splitSize = 50;
@Override
public List<Record> translator(final DataSource sourceDs, final DataSource targetDs, final List<Record> records,
final ExecutorTemplate template) {
if (template != null) {
final List<Record> result = Collections.synchronizedList(new ArrayList<Record>());
final String spiltKey = MDC.get(YuGongConstants.MDC_TABLE_SHIT_KEY);
if (records.size() > splitSize) {
try {
int index = 0;// 记录下处理成功的记录下标
int size = records.size();
// 全量复制时,无顺序要求,数据可以随意切割,直接按照splitSize切分后提交到多线程中进行处理
for (; index < size;) {
int end = (index + splitSize > size) ? size : (index + splitSize);
final List<Record> subList = records.subList(index, end);
template.submit(new Runnable() {
public void run() {
MDC.put(YuGongConstants.MDC_TABLE_SHIT_KEY, spiltKey);
result.addAll(doTranslator(sourceDs, subList));
}
});
index = end;// 移动到下一批次
}
// 等待所有结果返回
template.waitForResult();
} finally {
template.clear();
}
} else {
result.addAll(doTranslator(sourceDs, records));
}
return result;
} else {
return super.translator(sourceDs, targetDs, records, template);
}
}
public List<Record> doTranslator(DataSource sourceDs, List<Record> records) {
// 构建in sql
int size = records.size();
StringBuilder builder = new StringBuilder("select BILL_OUT_ID,REF_USER_ID,TO_REF_USER_ID,BILL_TYPE FROM BILL_OUT WHERE BILL_OUT_ID in");
builder.append("(");
for (int i = 0; i < size; i++) {
builder.append('?');
if (i < size - 1) {
builder.append(',');
}
}
builder.append(')');
Object args[] = new Object[size];
int i = 0;
for (Record record : records) {
ColumnValue idColum = record.getColumnByName("BILL_OUT_ID");
args[i++] = idColum.getValue();
}
JdbcTemplate jdbcTemplate = new JdbcTemplate(sourceDs);
List datas = jdbcTemplate.query(builder.toString(), args, new ColumnMapRowMapper());
Map<String, Map<String, Object>> joinDatas = new HashMap<String, Map<String, Object>>();
for (Object data : datas) {
Map map = (Map) data;
Object number = map.get("BILL_OUT_ID");
joinDatas.put(number.toString(), map);
}
List<Record> result = new ArrayList<Record>();
i = 0;
for (Record record : records) {
record.setTableName("MID_BILL_OUT_DETAIL_TEST");
Map map = joinDatas.get(args[i++].toString());
if (map == null) {
ignoreLogger.info("{}", RecordDumper.dumpRecord(record));
} else {
ColumnMeta refEntId = new ColumnMeta("REF_ENT_ID", Types.VARCHAR);
ColumnValue refEntIdColumn = new ColumnValue(refEntId, map.get("REF_USER_ID"));
record.addPrimaryKey(refEntIdColumn);
ColumnMeta toRefUserId = new ColumnMeta("TO_REF_USER_ID", Types.VARCHAR);
ColumnValue toRefUserIdColumn = new ColumnValue(toRefUserId, map.get("TO_REF_USER_ID"));
record.addColumn(toRefUserIdColumn);
ColumnMeta billType = new ColumnMeta("BILL_TYPE", Types.DECIMAL);
ColumnValue billTypeColumn = new ColumnValue(billType, map.get("BILL_TYPE"));
record.addColumn(billTypeColumn);
result.add(record);
}
}
return result;
}
@Override
public boolean translator(DataSource sourceDs, Record record) {
return true;
}
}