package com.ctrip.platform.dal.dao.helper;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import com.ctrip.platform.dal.dao.DalRowMapper;
/**
*
* If Use this parser, the JPA Entity should flow the rules
* 1.The entity must contain non-parameters constructor.
* 2.Each field of the entity must declare the SqlType annotation.
*/
public class DalDefaultJpaParser<T> extends AbstractDalParser<T> implements SupportPartialResultMapping<T> {
private Map<String, Field> fieldsMap;
private Class<T> clazz;
private Field identity;
private boolean autoIncrement;
private DalDefaultJpaMapper<T> rowMapper;
public DalDefaultJpaParser(Class<T> clazz) throws SQLException {
EntityManager manager = EntityManager.getEntityManager(clazz);
this.dataBaseName = manager.getDatabaseName();
this.tableName = manager.getTableName();
this.columns = manager.getColumnNames();
this.primaryKeyColumns = manager.getPrimaryKeyNames();
this.columnTypes = manager.getColumnTypes();
this.clazz = clazz;
this.autoIncrement = manager.isAutoIncrement();
this.fieldsMap = manager.getFieldMap();
Field[] identities = manager.getIdentity();
this.identity = identities != null && identities.length == 1 ? identities[0] : null;
this.rowMapper = new DalDefaultJpaMapper<T>(clazz);
this.sensitiveColumnNames = manager.getSensitiveColumnNames();
this.versionColumn = manager.getVersionColumn();
this.updatableColumnNames = manager.getUpdatableColumnNames();
this.insertableColumnNames = manager.getInsertableColumnNames();
}
/**
* To allow config DB name
* @param clazz
* @param dataBaseName
* @throws SQLException
*/
public DalDefaultJpaParser(Class<T> clazz, String dataBaseName) throws SQLException {
this(clazz);
this.dataBaseName = dataBaseName;
}
/**
* To allow config DB and table name
* @param clazz
* @param dataBaseName
* @param tableName
* @throws SQLException
*/
public DalDefaultJpaParser(Class<T> clazz, String dataBaseName, String tableName) throws SQLException {
this(clazz);
this.dataBaseName = dataBaseName;
this.tableName = tableName;
}
@Override
public T map(ResultSet rs, int rowNum) throws SQLException {
return rowMapper.map(rs, rowNum);
}
@Override
public boolean isAutoIncrement() {
return this.autoIncrement;
}
@Override
public Number getIdentityValue(T pojo) {
if (pojo.getClass().equals(this.clazz) && identity != null) {
try {
Object val = identity.get(pojo);
if (val instanceof Number)
return (Number) val;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
return null;
}
@Override
public Map<String, ?> getPrimaryKeys(T pojo) {
return getFields(getPrimaryKeyNames(), pojo);
}
@Override
public Map<String, ?> getFields(T pojo) {
return getFields(getColumnNames(), pojo);
}
private Map<String, ?> getFields(String[] columnNames, T pojo) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
for (String columnName: columnNames) {
try {
map.put(columnName, fieldsMap.get(columnName).get(pojo));
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
return map;
}
@Override
public DalRowMapper<T> mapWith(String[] selectedColumns, boolean ignorMissingFields)
throws SQLException {
return rowMapper.mapWith(selectedColumns, ignorMissingFields);
}
}