JDBC有没有办法将结果集内容直接获取到List中。我需要像下面这样的通用内容。
不用说,仅需要 SELECT 查询(因为我的应用程序用于报告目的)
List<Customer> blockedCustomerList = executeQuery(sql, Customer.class);
我写了这样的东西,它工作正常,但这样我无法获取 BLOB 和 CLOB 值。欢迎提出任何建议。
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ResultSetConverter {
/**
* Generates DB column and java Domain class property mapping
*
* @param pInputClassName
* java Domain class, fully qualified name(package+java class)
* @return
* Map<String,ColumnMappingDTO>, mapping of DB column and Java Doamin class property
* @throws Exception
* if pInputClassName is not loaded properly
*/
private static Map<String,ColumnMappingDTO> initColumnMappings(String pInputClassName) throws Exception{
Class mClassObj=null;
Field[] mFieldsArr=null;
Annotation[] mAnnotations =null;
ColumnMappingDTO vColumnMappingDTO=null;
javax.persistence.Column myAnnotation=null;
Map<String,ColumnMappingDTO> outMappingDetails =new HashMap<String, ColumnMappingDTO>();
try{
//try loading Domain Object Class
mClassObj=Class.forName(pInputClassName);
//get fields in class
mFieldsArr=mClassObj.getDeclaredFields();
for(Field vField:mFieldsArr){
mAnnotations=vField.getDeclaredAnnotations();
for(Annotation vAnnotation:mAnnotations){
if(vAnnotation instanceof javax.persistence.Column){
vColumnMappingDTO = new ColumnMappingDTO();
myAnnotation= (javax.persistence.Column) vAnnotation;
vColumnMappingDTO.setPropertyName(vField.getName());
vColumnMappingDTO.setColumnName(myAnnotation.name());
outMappingDetails.put(vColumnMappingDTO.getColumnName(), vColumnMappingDTO);
}
}
}
}catch(ClassNotFoundException e){
System.out.println("caught Exception in initColumnMappings() as "+e);
throw e;
}catch(Exception ex){
System.out.println("caught Exception in initColumnMappings() as "+ex);
throw ex;
}
return outMappingDetails;
}
/**
* Executes sql passed inform of PreparedStatement inPstmt and generated List genere as String pDomainClassName
*
* @param inPstmt
* Sql to be executed inform of PreparedStatement
* @param pDomainClassName
* fully qualified Class name of DTO
* @return
* Object, later to be type casted to List<pDomainClassName>
* @throws Exception
* When Mapping is not missing or done wrong
*
*/
public static Object executeQuery(PreparedStatement inPstmt,String pDomainClassName)throws SQLException,Exception{
ResultSet mRSet=null;
ResultSetMetaData mRsetMt=null;
ColumnValueDTO mColumnValueDTO =null;
List<String> mColumnNamesList =new ArrayList<String>();
List<ColumnValueDTO> mColumnValuesList=null;
List<Object> outResultList =new ArrayList<Object>();
Map<String,ColumnMappingDTO> mMappingDetailsMap =null;
String[] mArrColumnValues=null;
String mColumnName=null;
int mColumnCount=-1;
try{
//generate DB Column and Domain Class property mapping
mMappingDetailsMap=initColumnMappings(pDomainClassName);
//execute sql
mRSet=inPstmt.executeQuery();
if(mRSet!=null){
//get ResultSetMetaData
mRsetMt=mRSet.getMetaData();
if(mRsetMt!=null){
mColumnCount =mRsetMt.getColumnCount();
mArrColumnValues= new String[mColumnCount];
//generate SELECT columns list
for(int i=0;i<mColumnCount;i++){
mColumnName=mRsetMt.getColumnName(i+1);
mColumnNamesList.add(mColumnName);
}
}
while(mRSet.next()){
mColumnValuesList =new ArrayList<ColumnValueDTO>();
for(String columnHeader:mColumnNamesList){
mColumnValueDTO= new ColumnValueDTO();
if(mMappingDetailsMap.get(columnHeader)!=null){
mColumnValueDTO.setPropertyName(mMappingDetailsMap.get(columnHeader).getPropertyName());
mColumnValueDTO.setPropertyValue(mRSet.getString(mMappingDetailsMap.get(columnHeader).getColumnName()));
mColumnValuesList.add(mColumnValueDTO);
}
}
//
Object domainObj=createDomainObject(mColumnValuesList,pDomainClassName);
//Add Object to out List
outResultList.add(domainObj);
}
}
}catch(Exception ex){
System.out.println(" caught in executeQuery() "+ex);
throw ex;
}finally{
//release resources
try {
mRSet.close();
} catch (SQLException e) {
System.out.println(" caught in Exception while closing ResultSet "+e);
throw e;
}
}
return outResultList;
}
private static Object createDomainObject(List<ColumnValueDTO> columnValuesList,String vDoaminClass) throws Exception{
Class domainClassObj=null;
Object domainObj=null;
Field domainDataField =null;
Annotation[] annotations=null;
try{
domainClassObj= Class.forName(vDoaminClass);
domainObj=domainClassObj.newInstance();
for(ColumnValueDTO columnDTO:columnValuesList){
if(columnDTO!=null){
domainDataField = domainClassObj.getDeclaredField(columnDTO.getPropertyName());
domainDataField.setAccessible(true);
annotations = domainDataField.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof javax.persistence.Column){
@SuppressWarnings("unused")
javax.persistence.Column myAnnotation = (javax.persistence.Column) annotation;
}
}
domainDataField.set(domainObj,getValueByType(columnDTO.getPropertyValue(),domainDataField.getGenericType().toString(),domainDataField.getType()));
}
}
}catch(ClassNotFoundException cnfe){
System.out.println(" Caught ClassNotFoundException in createDomainObject() "+cnfe);
throw cnfe;
}catch(IllegalAccessException iae){
System.out.println(" Caught IllegalAccessException in createDomainObject() "+iae);
throw iae;
}catch(InstantiationException ie){
System.out.println(" Caught InstantiationException in createDomainObject() "+ie);
throw ie;
}catch(SecurityException se){
System.out.println(" Caught SecurityException in createDomainObject() "+se);
throw se;
}catch(NoSuchFieldException nfe){
System.out.println(" Caught NoSuchFieldException in createDomainObject() "+nfe);
throw nfe;
}catch(Exception e){
System.out.println(" Caught Exception in createDomainObject() "+e);
throw e;
}
return domainObj;
}
@SuppressWarnings("deprecation")
private static Object getValueByType(String value, String type,Type domainFieldType) throws Exception{
Object retvalue=null;
try{
if(value!=null){
if(domainFieldType.equals(Integer.TYPE)){
retvalue=new Integer(value);
}else if(domainFieldType.equals(Double.TYPE)){
retvalue=new Double(value);
}else if(domainFieldType.equals(Float.TYPE)){
retvalue=new Float(value);
}else if(domainFieldType.equals(Character.TYPE)){
retvalue=new Character(value.charAt(0));
}else if(domainFieldType.equals(Short.TYPE)){
retvalue=new Short(value);
}else if(domainFieldType.equals(Long.TYPE)){
retvalue=new Long(value);
}else if(type.equals(java.sql.Timestamp.class)){
retvalue=java.sql.Timestamp.valueOf(value);
}else if(domainFieldType.equals(java.sql.Date.class)){
retvalue= java.sql.Date.valueOf(value);
}else if(domainFieldType.equals(String.class)){
retvalue=new String(value);
}
}
}catch(Exception ex){
System.out.println(" Caught Exception in getValueByType() "+ex);
throw ex;
}
return retvalue;
}
}
Mappin DTO 类:
public class ColumnMappingDTO {
private String columnName;
private String propertyName;
private String dataType;
/**
* @return the columnName
*/
public String getColumnName() {
return columnName;
}
/**
* @param columnName the columnName to set
*/
public void setColumnName(String columnName) {
this.columnName = columnName;
}
/**
* @return the dataType
*/
public String getDataType() {
return dataType;
}
/**
* @param dataType the dataType to set
*/
public void setDataType(String dataType) {
this.dataType = dataType;
}
/**
* @return the propertyName
*/
public String getPropertyName() {
return propertyName;
}
/**
* @param propertyName the propertyName to set
*/
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public String toString(){
return "Database Column :: "+this.columnName+" Java Property :: "+this.propertyName+" Java Datatype :: "+this.dataType;
}
}
列值类别:
import java.io.Serializable;
public class ColumnValueDTO implements Serializable {
private String propertyName;
private String propertyValue;
private static final long serialVersionUID = -4915109169715618102L;
/**
* @return the propertyName
*/
public String getPropertyName() {
return propertyName;
}
/**
* @param propertyName the propertyName to set
*/
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
/**
* @return the propertyValue
*/
public String getPropertyValue() {
return propertyValue;
}
/**
* @param propertyValue the propertyValue to set
*/
public void setPropertyValue(String propertyValue) {
this.propertyValue = propertyValue;
}
public String toString(){
return "Property :: "+this.propertyName+" Value :: "+this.propertyValue;
}
}
最佳答案
在您的示例中,您有一个方法
public static Object executeQuery(PreparedStatement inPstmt,String pDomainClassName)throws SQLException,Exception{
List<Object> outResultList =new ArrayList<Object>();
// the body of method
return outResultList;
}
方法声明返回对象,但在实现中返回一个List,这是很奇怪的。但为了得到你想要的,你可以使用通用方法。
public static <T> List<T> executeQuery(PreparedStatement inPstmt,Class<T> type) throws Exception{
return (List<T>) executeQuery(inPstmt, type.getName()); //Here you will get a warning.
}
--
编辑:
请注意,在您的代码中几乎没有问题。值解析器非常消耗资源,并且在比较字符串和类型时无法正常工作。当您在使用之前声明对象时,代码的可重读性很困难。
/**
* Generates DB column and java Domain class property mapping
*
* @param pInputClassName
* java Domain class, fully qualified name(package+java class)
* @return
* Map<String,ColumnMappingDTO>, mapping of DB column and Java Doamin class property
* @throws Exception
* if pInputClassName is not loaded properly
*/
private static Map<String, ColumnMappingDTO> initColumnMappings(String pInputClassName) throws Exception {
Map<String, ColumnMappingDTO> outMappingDetails = new HashMap<String, ColumnMappingDTO>();
try {
for (Field vField : getFields(pInputClassName)) {
for (Annotation vAnnotation : vField.getDeclaredAnnotations()) {
if (vAnnotation instanceof Column) {
ColumnMappingDTO vColumnMappingDTO = createColumnMapping(vField, (Column) vAnnotation);
outMappingDetails.put(vColumnMappingDTO.getColumnName(), vColumnMappingDTO);
}
}
}
} catch (Exception ex) {
System.out.println("caught Exception in initColumnMappings() as " + ex);
throw ex;
}
return outMappingDetails;
}
/**
* @param vField
* @param vAnnotation
* @return
*/
private static ColumnMappingDTO createColumnMapping(Field vField, Column vAnnotation) {
ColumnMappingDTO vColumnMappingDTO = new ColumnMappingDTO();
vColumnMappingDTO.setPropertyName(vField.getName());
vColumnMappingDTO.setColumnName(vAnnotation.name());
return vColumnMappingDTO;
}
/**
* @param pInputClassName
* @return
* @throws ClassNotFoundException
*/
private static Field[] getFields(String pInputClassName) throws ClassNotFoundException {
//try loading Domain Object Class
return Class.forName(pInputClassName).getDeclaredFields();
}
/**
* Executes sql passed inform of PreparedStatement inPstmt and generated List genere as String pDomainClassName
*
* @param inPstmt
* Sql to be executed inform of PreparedStatement
* @param pDomainClassName
* fully qualified Class name of DTO
* @return
* Object, later to be type casted to List<pDomainClassName>
* @throws Exception
* When Mapping is not missing or done wrong
*
*/
public static Object executeQuery(PreparedStatement inPstmt, String pDomainClassName) throws SQLException, Exception {
return executeQuery(inPstmt, Class.forName(pDomainClassName));
}
public static <T> List<T> executeQuery(PreparedStatement inPstmt, Class<T> domainClass) throws SQLException, Exception {
List<T> outResultList = new ArrayList<T>();
ResultSet mRSet = null;
try {
// generate DB Column and Domain Class property mapping
Map<String, ColumnMappingDTO> mMappingDetailsMap = initColumnMappings(domainClass.getName());
// execute sql
mRSet = inPstmt.executeQuery();
if (mRSet == null) {
return Collections.EMPTY_LIST;
}
List<String> mColumnNamesList = getColumnNameList(mRSet);
while (mRSet.next()) {
List<ColumnValueDTO> mColumnValuesList = new ArrayList<ColumnValueDTO>();
for (String columnHeader : mColumnNamesList) {
if (mMappingDetailsMap.containsKey(columnHeader)) {
ColumnValueDTO mColumnValueDTO = new ColumnValueDTO();
mColumnValueDTO.setPropertyName(mMappingDetailsMap.get(columnHeader).getPropertyName());
mColumnValueDTO.setPropertyValue(mRSet.getString(mMappingDetailsMap.get(columnHeader).getColumnName()));
mColumnValuesList.add(mColumnValueDTO);
}
}
//
T domainObj = createDomainObject(mColumnValuesList, domainClass);
// Add Object to out List
outResultList.add(domainObj);
}
} catch (Exception ex) {
System.out.println(" caught in executeQuery() " + ex);
throw ex;
} finally {
// release resources
try {
mRSet.close();
} catch (SQLException e) {
System.out.println(" caught in Exception while closing ResultSet " + e);
throw e;
}
}
return outResultList;
}
/**
* @param mColumnNamesList
* @param mRSet
* @return
* @throws SQLException
*/
private static List<String> getColumnNameList(ResultSet mRSet) throws SQLException {
ResultSetMetaData mRsetMt = mRSet.getMetaData();
if(mRsetMt == null){
return Collections.EMPTY_LIST;
}
List<String> mColumnNamesList = new ArrayList<String>();
// generate SELECT columns list
for (int i = 0; i < mRsetMt.getColumnCount(); i++) {
mColumnNamesList.add(mRsetMt.getColumnName(i + 1));
}
return mColumnNamesList;
}
private static Object createDomainObject(List<ColumnValueDTO> columnValuesList, String vDoaminClass) throws Exception {
Class<?> domainClassObj = Class.forName(vDoaminClass);
return createDomainObject(columnValuesList, domainClassObj);
}
private static <T> T createDomainObject(List<ColumnValueDTO> columnValuesList, Class<T> domainClassObj) throws Exception {
T domainObj = null;
try {
domainObj = domainClassObj.newInstance();
for (ColumnValueDTO columnDTO : columnValuesList) {
if (columnDTO == null) {
continue;
}
Field domainDataField = domainClassObj.getDeclaredField(columnDTO.getPropertyName());
domainDataField.setAccessible(true);
Object valueByType = parseValueByType(columnDTO.getPropertyValue(), domainDataField.getType());
domainDataField.set(domainObj, valueByType);
}
} catch (Exception e) {
System.out.println(" Caught " + e.getClass().getSimpleName() + " in createDomainObject() " + e);
throw e;
}
return domainObj;
}
private static Object parseValueByType(String value, Type type) throws Exception{
if(value == null) {
return null;
}
try{
if(Integer.TYPE.equals(type)){
return Integer.parseInt(value);
}
if(Double.TYPE.equals(type)){
return Double.parseDouble(value);
}
if(Float.TYPE.equals(type)){
return Float.parseFloat(value);
}
if(Short.TYPE.equals(type)) {
return Short.parseShort(value);
}
if(Long.TYPE.equals(type)) {
return Long.parseLong(value);
}
if(java.sql.Timestamp.class.equals(type)) {
return java.sql.Timestamp.valueOf(value);
}
if(java.sql.Date.class.equals(type)) {
return java.sql.Date.valueOf(value);
}
if(String.class.equals(type)) {
return value;
}
if(Character.TYPE.equals(type)) {
if(value.length() == 1) {
return value.charAt(0);
}
if(value.length() == 0) {
return '\0';
}
throw new IllegalStateException("");
}
}catch(Exception ex){
System.out.println(" Caught Exception in getValueByType() "+ex);
throw ex;
}
throw new IllegalArgumentException("Could not find the resolver for type " + type);
}
public static class ColumnValueDTO implements Serializable {
private String propertyName;
private String propertyValue;
private static final long serialVersionUID = -4915109169715618102L;
/**
* @return the propertyName
*/
public String getPropertyName() {
return propertyName;
}
/**
* @param propertyName the propertyName to set
*/
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
/**
* @return the propertyValue
*/
public String getPropertyValue() {
return propertyValue;
}
/**
* @param propertyValue the propertyValue to set
*/
public void setPropertyValue(String propertyValue) {
this.propertyValue = propertyValue;
}
public String toString(){
return "Property :: "+this.propertyName+" Value :: "+this.propertyValue;
}
}
public static class ColumnMappingDTO {
private String columnName;
private String propertyName;
private String dataType;
/**
* @return the columnName
*/
public String getColumnName() {
return columnName;
}
/**
* @param columnName the columnName to set
*/
public void setColumnName(String columnName) {
this.columnName = columnName;
}
/**
* @return the dataType
*/
public String getDataType() {
return dataType;
}
/**
* @param dataType the dataType to set
*/
public void setDataType(String dataType) {
this.dataType = dataType;
}
/**
* @return the propertyName
*/
public String getPropertyName() {
return propertyName;
}
/**
* @param propertyName the propertyName to set
*/
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public String toString(){
return "Database Column :: "+this.columnName+" Java Property :: "+this.propertyName+" Java Datatype :: "+this.dataType;
}
}
private static class Column {
/**
* @return
*/
public String name() {
// TODO Auto-generated method stub
return null;
}
}
关于java - java中的结果集转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19782403/