package com.ctrip.platform.dal.dao.sqlbuilder;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import com.ctrip.platform.dal.dao.DalResultSetExtractor;
import com.ctrip.platform.dal.dao.DalRowCallback;
import com.ctrip.platform.dal.dao.DalRowMapper;
import com.ctrip.platform.dal.dao.ResultMerger;
import com.ctrip.platform.dal.dao.StatementParameters;
import com.ctrip.platform.dal.dao.helper.DalListMerger;
import com.ctrip.platform.dal.dao.helper.DalRowCallbackExtractor;
import com.ctrip.platform.dal.dao.helper.DalRowMapperExtractor;
import com.ctrip.platform.dal.dao.helper.EntityManager;
import com.ctrip.platform.dal.dao.helper.MultipleResultMerger;
public class MultipleSqlBuilder implements SqlBuilder {
private List<QueryUnit> queryUnits = new ArrayList<>();
private MultipleResultMerger mergers = new MultipleResultMerger();
/**
* This extractor instance maybe used in more than one thread. Make sure it is thread safe.
* To be thread safe is easy, just not keep any changeable state inside the object.
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, DalResultSetExtractor<T> extractor, ResultMerger<T> merger) {
queryUnits.add(new QueryUnit(sql,parameters, extractor));
mergers.add(merger);
return this;
}
/**
* This mapper instance maybe used in more than one thread. Make sure it is thread safe.
* To be thread safe is easy, just not keep any changeable state inside the object.
* The default JPA parser is thread safe.
* @return
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, DalRowMapper<T> mapper) {
DalListMerger<T> defaultMerger = new DalListMerger<>();
return addQuery(sql, parameters, new DalRowMapperExtractor<T>(mapper), defaultMerger);
}
/**
* This mapper instance maybe used in more than one thread. Make sure it is thread safe.
* To be thread safe is easy, just not keep any changeable state inside the object.
* The default JPA parser is thread safe.
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, DalRowMapper<T> mapper, ResultMerger<List<T>> merger) {
return addQuery(sql, parameters, new DalRowMapperExtractor<T>(mapper), merger);
}
/**
* This mapper instance maybe used in more than one thread. Make sure it is thread safe.
* To be thread safe is easy, just not keep any changeable state inside the object.
* The default JPA parser is thread safe.
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, DalRowMapper<T> mapper, Comparator<T> sorter) {
ResultMerger<List<T>> defaultMerger = new DalListMerger<>(sorter);
return addQuery(sql, parameters, new DalRowMapperExtractor<T>(mapper), defaultMerger);
}
/**
* Query list of objects against type clazz with default list merger
* The class can be normal Object that can be get from result set or the class of annotated DAL POJO.
* The DalDefaultJpaMapper will be used as row mapper for later case.
* @param sql
* @param clazz
* @return
* @throws SQLException
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, Class<T> clazz) throws SQLException {
return addQuery(sql, parameters, clazz, new DalListMerger<T>());
}
/**
* Query list of objects against type clazz with given list merger
* The class can be normal Object that can be get from result set or the class of annotated DAL POJO.
* @param sql
* @param clazz
* @param merger
* @return
* @throws SQLException
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, Class<T> clazz, ResultMerger<List<T>> merger) throws SQLException {
return addQuery(sql, parameters, new DalRowMapperExtractor<T>(EntityManager.getMapper(clazz)), merger);
}
/**
* Query list of objects against type clazz with default list merger sort with given comparator.
* The class can be normal Object that can be get from result set or the class of annotated DAL POJO.
* @param sql
* @param clazz
* @param sorter
* @return
* @throws SQLException
*/
public <T> MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, Class<T> clazz, Comparator<T> sorter) throws SQLException {
return addQuery(sql, parameters, clazz, new DalListMerger<T>(sorter));
}
/**
* Work with callback. There will be null return value.
* @param sql
* @param callback
* @return
*/
public MultipleSqlBuilder addQuery(String sql, StatementParameters parameters, DalRowCallback callback) {
DalListMerger<Object> defaultMerger = new DalListMerger<>();
return addQuery(sql, parameters, new DalRowCallbackExtractor(callback), defaultMerger);
}
public List<DalResultSetExtractor<?>> getExtractors() {
List<DalResultSetExtractor<?>> extractors = new ArrayList<>();
for(QueryUnit unit: queryUnits)
extractors.add(unit.extractor);
return extractors;
}
public ResultMerger<List<?>> getMergers() {
return mergers;
}
@Override
public String build() {
StringBuilder sb = new StringBuilder();
List<DalResultSetExtractor<?>> extractors = new ArrayList<>();
for(QueryUnit unit: queryUnits) {
sb.append(unit.sql);
if(!unit.sql.endsWith(";"))
sb.append(';');
}
return sb.toString();
}
@Override
public StatementParameters buildParameters() {
StatementParameters parameters = new StatementParameters();
for(QueryUnit unit: queryUnits) {
parameters.addAll(unit.parameters);
}
return parameters;
}
private class QueryUnit {
String sql;
StatementParameters parameters;
DalResultSetExtractor<?> extractor;
<T> QueryUnit(String sql, StatementParameters parameters, DalResultSetExtractor<T> extractor) {
this.sql = sql.trim();
this.parameters = parameters;
this.extractor = extractor;
}
}
}