Java 通用存储过程ORMapping的实现 [真正实现篇]

来源:互联网 发布:广告牌抗风计算软件 编辑:程序博客网 时间:2024/04/28 16:56

在[基类实现篇]中,私有变量JxSpObject是真正的实现存储调用的一个类

实现代码:

import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.*;
import java.sql.*;
import com.sun.rowset.*;

final class JxStoredProcedure
{
    
private String[] sqlTypeNames;
    
private int[] sqlTypeVals;
    
protected JxStoredProcedure()throws Exception
    
{
        
this.alAllParams = new ArrayList<JXVar>();
        
this.alOutputParams = new ArrayList<JXVar>();//实际代码中并未使用,测试版本保留此集合
        this.getSqlTypes();
    }

    
    
private void getSqlTypes()throws Exception
    
{
        
//java.sql.Types.VARCHAR ...        
        Field[] flds = Types.class.getFields();
        
        
int idx = 0;        
        sqlTypeVals 
= new int[flds.length];
        sqlTypeNames
= new String[flds.length];
        
for(Field fld : flds)
        
{            
            
this.sqlTypeVals[idx] = Integer.parseInt(fld.get(null).toString());
            
this.sqlTypeNames[idx] = fld.getName();
            idx 
+= 1;
        }

    }

    
    
//从名称[java.sql.Types.INTEGER],得到对应的数据,便于填充参数的类型
    private int getSqlTypeValue(String sqlTypeNAME)throws Exception
    
{
        
int iSqlTypeValue=0;
        
int idx = 0;
        
boolean bFlag = false;
        
for(String str : this.sqlTypeNames)
        
{
            
if(sqlTypeNAME.indexOf(str)>-1)
            
{
                iSqlTypeValue 
= this.sqlTypeVals[idx];
                bFlag 
= true;
                
break;
            }

            idx 
+= 1;
        }

        
        
if(!bFlag)throw new Exception("检查是否参数类型是否正确...");
        
        
return iSqlTypeValue;
    }

    
    
public Object Exectue(Object InstanceClass)throws Exception
    
{
        Object obj 
= null;
        
this.IniSpData(InstanceClass);
        
try
        
{
            obj 
= this.doExecute(InstanceClass);
            
if(this.jxReturn.Flag() == ReturnFlag.IsDataSet || this.jxReturn.Flag() == ReturnFlag.IsDouble)
            
{
                
return chRs;
            }

        }

        
catch(Exception ex)
        
{
            
throw ex;
        }

        
return obj;
    }

    
    
public Object[] ExectueToObject(Object InstanceClass,Class InstanceType)throws Exception
    
{
        Object obj 
= null;
        
this.IniSpData(InstanceClass);
        
try
        
{
            obj 
= this.doExecute(InstanceClass);
            
if(this.jxReturn.Flag() == ReturnFlag.IsDataSet || this.jxReturn.Flag() == ReturnFlag.IsDouble)
            
{
                
return JxConvert.ToObjectArray(InstanceType, chRs);
            }

        }

        
catch(Exception ex)
        
{
            
throw ex;
        }

        
return null;
    }

    
    
private Object getPrivateFieldValue(Object obj, String PrivateFieldName)throws Exception
    
{
        Field fld 
= obj.getClass().getDeclaredField(PrivateFieldName);
        fld.setAccessible(
true);
        Object objVal 
= fld.get(obj);
        fld.setAccessible(
false);
        
        
return objVal;
    }

    
    
private void setReturnFiledValue(Object obj, String PrivateFieldName,Object objResult)throws Exception
    
{
        Field fld 
= obj.getClass().getDeclaredField(PrivateFieldName);
        fld.setAccessible(
true);
        fld.set(obj, objResult);
        fld.setAccessible(
false);
    }

    
    
private String SPName;
    
private JXExectueReturn jxReturn;
    
private ArrayList<JXVar> alAllParams = null;
    
private ArrayList<JXVar> alOutputParams = null;
    
private void IniSpData(Object InstanceClass)throws Exception
    
{
        
//得到整个类上的 JXDatatSet 标注
        JXDatatSet jxDS = InstanceClass.getClass().getAnnotation(JXDatatSet.class);
        
if(jxDS==null)throw new Exception("操作数据库发生错误:你必须使用 @JXDatatSet(...) 来标识类...");
        
if(jxDS.schemaFlag() != SchemaFlag.IsStoredProcedure)throw new Exception("@JXDatatSet标识的类,不是有效的存储过程,请使用 SchemaFlag.IsStoredProcedure 来标识类...");
        
        
//存储过程名称
        SPName = jxDS.SchemaName();
        
        
//得到 .ctor 方法上的返回标注 JXExectueReturn
        Constructor[] ctorAry = InstanceClass.getClass().getDeclaredConstructors();
        
for(Constructor ctor : ctorAry)
        
{
            jxReturn 
= (JXExectueReturn)ctor.getAnnotation(JXExectueReturn.class);
            
if(jxReturn == null)continue;            
        }

        
if(jxReturn == null)throw new Exception("存储的实例类,至少在一个构造器上应用 @JXExectueReturn(...) 注释...");
        
        
        
//得到整个类所有的私有变量的 JXVar 标注
        Field[] flds = InstanceClass.getClass().getDeclaredFields();
        
for(Field fld : flds)
        
{
            JXVar jxVar 
= fld.getAnnotation(JXVar.class);
            
if(jxVar == null)continue;
            
            
this.alAllParams.add(jxVar);
            
if(jxVar.Flag() == VarIOFlag.IsOutput)this.alOutputParams.add(jxVar);
        }


    }

    
    
private CachedRowSetImpl chRs;
    
private int iReturnFlagValue;
    
private Object doExecute(Object InstanceClass)throws Exception
    
{
        Object objValue 
= null;
        
        String strSQL 
= "";
        
for(int i=0;i<this.alAllParams.size();i++)strSQL += (strSQL.length()==0? "?" : ",?";
        
        
if(strSQL.length()==0)strSQL = "call "+ this.SPName +"()";
        
else strSQL = "call "+ this.SPName +"(" + strSQL + ")";
        
        
this.iReturnFlagValue = this.jxReturn.Flag().getValue();
        
switch(this.iReturnFlagValue)
        
{
        
case 0:    //IsDataSet
            strSQL = "{" + strSQL + "}";
            
break;
        
case 1:    //IsValue
            strSQL = "{? = " + strSQL + "}";
            
break;
        
case 2:    //IsNonResult
            strSQL = "{" + strSQL + "}";
            
break;
        
case 3//IsDouble
            strSQL = "{? = " + strSQL + "}";
            
break;
        }
        
        
//System.out.println(strSQL);
        
        Connection conn 
= JxContext.JxCurrentSession.JxConn;//本人实现的数据库上下文环境中得到连接
        conn.setAutoCommit(false);
        CallableStatement callStmt 
= conn.prepareCall(strSQL);
        
        
int iParamIdx = 1;
        
if(iReturnFlagValue != 2 && iReturnFlagValue != 0)
        
{
            callStmt.registerOutParameter(iParamIdx, 
this.getSqlTypeValue(jxReturn.JavaSqlTypes()));
            iParamIdx 
+= 1;
        }

        
        
for(JXVar jxVar : this.alAllParams)
        
{
            
if(jxVar.Flag() == VarIOFlag.IsInput)
            
{
                callStmt.setObject(iParamIdx, 
this.getPrivateFieldValue(InstanceClass,jxVar.PrivateFieldName()));
            }

            
else if(jxVar.Flag() == VarIOFlag.IsOutput)
            
{
                callStmt.registerOutParameter(iParamIdx, 
this.getSqlTypeValue(jxVar.JavaSqlTypes()));
            }

            
else if(jxVar.Flag() == VarIOFlag.IsDouble)
            
{
                callStmt.setObject(iParamIdx, 
this.getPrivateFieldValue(InstanceClass,jxVar.PrivateFieldName()));
                callStmt.registerOutParameter(iParamIdx, 
this.getSqlTypeValue(jxVar.JavaSqlTypes()));
            }

            
            
            iParamIdx 
+= 1;
        }

        
        callStmt.execute();
        
        Object objResult 
= null;
        
if(iReturnFlagValue == 1//IsValue
        {
            iParamIdx 
= 2;
            objResult 
= callStmt.getObject(1);
            setReturnFiledValue(InstanceClass,jxReturn.PrivateFieldName(),objResult);
        }

        
if(iReturnFlagValue == 0 || iReturnFlagValue==3//IsDataSet,IsDouble
        {
            
//具有结果集
            ResultSet rs = callStmt.getResultSet();
            chRs 
= new CachedRowSetImpl();
            chRs.populate(rs);
            rs.close();
            rs 
= null;
            
            
//还具有返回值
            if(iReturnFlagValue==3)
            
{
                iParamIdx 
= 2;
                objResult 
= callStmt.getObject(1);
                setReturnFiledValue(InstanceClass,jxReturn.PrivateFieldName(),objResult);
            }

        }

        
        
//所有的输出参数进行赋值
        for(JXVar jxVar : this.alAllParams)
        
{
            
if(jxVar.Flag() == VarIOFlag.IsOutput || jxVar.Flag() == VarIOFlag.IsDouble)
            
{
                Object objOut 
= callStmt.getObject(iParamIdx);
                
this.setReturnFiledValue(InstanceClass,jxVar.PrivateFieldName(),objOut);
            }

            iParamIdx 
+= 1;
        }


        callStmt.close();
        
return objResult;
    }

}

此类,本人在实现时,实际上专写了一个接口,是通过此接口完成的,但此类现在是完成可以正常工作的

如需转载,请表明出处
anthor:zerodj@163.com/javasuki@hotmail.com

 

原创粉丝点击