jeudi 19 septembre 2019

How to remove duplication from CallableStatement boiler plate code?

We have many stored procedures and functions that we call on our DB and the setup for each call in our data access layer is really verbose with setting the inputs and registering the output etc... Is there a better solution to maybe generating the CallableStatement dynamically for any stored procedure or function with any types/amounts of parameters and output type?

We have a home brew solution and it is ugly... full of if/else, fors and whiles... very hard to read and maintain. We have also tried to centralize common boilerplate code for like function calls. I.E. All of the ones that take a Long and return a boolean, all use the same centralized method with dynamic Long and stored procedure string.

The code is from memory please don't pay too much attention to syntax, this is a design question more than anything.

//Client usage in Controller class

certAwarded = PackageName.isCertAwardedFor(personIDToCheck);

//In class that mimics the interface of the database packages 
//There would be a method per public function
public static boolean isCertAwardedFor(Long personID){
    return PackageUtils.isMet(personID, "{? = call PACKAGE.is_met(?)}");
}

//In Package scoped Utility class 
//Attempt to centralize all single input param and return of boolean
//type of procedure calls.
static boolean isMet(Long personID, String proc){
    boolean met = false;
    try(AutoCloseableStatement stmt = new AutoCloseableStatement(proc)){
        CallableStatement callableStmt = stmt.createStatement();
        callableStmt.registerOutParameter(1, OracleTypes.VARCHAR2);
        callableStmt.setLong(2, personID);
        callableStmt.execute();
        met = convertYNtoBool(callableStmt.getString(1));
    }catch(SQLException ex){
        Logger.log(ex);
    }
return met;
}


///////////////////////////////////OR///////////////////////////////

//Client usage in Controller class

certAwarded = PackageName.isCertAwardedFor(personIDToCheck, CertPackageEnum);

//In class that mimics the interface of the database packages 
//There would be a method per public function
public static boolean isCertAwardedFor(Long personID, PackageProc procCall){
    return PackageUtils.call(personID, procCall.IS_CERT_AWARDED);
}

//In Package scoped Utility class 
//Attempt to centralize all single input param and return of boolean
//type of procedure calls.
static boolean isMet(Long personID, String proc){
    try(AutoCloseableStatement stmt = new AutoCloseableStatement(proc)){
        CallableStatement callableStmt = stmt.createStatement();
        LOTS OF CONDITIONS TO CHECK AND SET ALL POSSIBLE INPUTS AND OUTPUTS
    }catch(SQLException ex){
        Logger.log(ex);
    }
    return ?????
}

Aucun commentaire:

Enregistrer un commentaire