Menu

#27 Add more static factory methods.

sqlbuilder-3.0.1
closed
nobody
None
1
2020-09-04
2020-09-02
No

Hi!

I find myself adding a lot of utility classes with methods like (just examples):

public static NegateExpression negate(final Object obj) {
    return new NegateExpression(obj);
}

public static InCondition in(final Object leftObj, final Object... rightObjs) {
    return new InCondition(leftObj, rightObjs);
}

public static InCondition notIn(final Object leftObj, final Object... rightObjs) {
    return new InCondition(leftObj, rightObjs).setNegate(true);
}

This allows me to write shorter code (by using static method imports).

It would be nice if these methods already exist on some of the classes (they do on some) :)

Discussion

  • James Ahlborn

    James Ahlborn - 2020-09-02

    are there other classes which you think could benefit from static methods? mostly conditions and expressions i presume?

    would it make sense to do something like Hibernate and put these all in one class, like Conditions and Expressions?

     

    Last edit: James Ahlborn 2020-09-02
  • Anonymous

    Anonymous - 2020-09-02

    Hi!

    Any class extending Expression and Condition indeed, some already have static methods (Like FunctionCall).
    No other classes spring to mind really, there's probably some that would benefit, but they haven't come up in my usecases yet :)

    Putting this in 'namespace' classes like Conditions and Expressions is probably a good idea, makes it easier to find all the available 'keywords', and can really shorten the import statements. But it's not a big deal for the usecase, as most ide's are pretty helpfull with finding the right static method, and the actual code will still look identical :)


    Sort of unrelated, currently I'm defining and using my tables and columns as:

    class MyOrders() {
       public final DbTable table;
       public final DbColumn orderId;
    
       public MyOrders(DbSchema schema) {
         table = schema.addTable("my_orders");
         orderId = table.addColumn("orderId");
       }
    }
    

    So that I can then use it as:

    DbSpec spec = new DbSpec();
    DbSchema schema = spec.addDefaultSchema();
    
    MyOrders myOrders = new MyOrders(schema);
    
     String query = new SelectQuery()
      .addColumns(myOrders.orderId)
      .validate().toString();
    

    It's not perfect, but it gives a pretty efficient naming scheme for columns ([table].[column]),
    and when you start having many queries, reusing the 'table' classes (MyOrders) becomes very usefull.
    Open to suggestions on improving it though :)

     
    • James Ahlborn

      James Ahlborn - 2020-09-02

      i actually use the same pattern. additionally, i build the queries using QueryPreparer and stash the prebuilt queries and the related PlaceHolder instances in that class (possibly also using QueryReader). then i add helper methods which take the necessary arguments to build a PreparedStatement and execute the queries. the one point i'd add is that since all of these objects are "effectively immutable" (after construction), you can make these util classes and methods static, no need to instantiate them on each use.

       
  • Anonymous

    Anonymous - 2020-09-02

    I couldn't quite make them static because of the DbSchema, which is passed in in the constructor and needed to create DbTable.
    I guess I could have one DbSchema in a static field in another class, and then use that to create all the static DbTable fields in the other classes :)

     
    • James Ahlborn

      James Ahlborn - 2020-09-02

      yes, i generally build the DbSchema and DbTable objects in the same collection of static class instances.

       
  • Anonymous

    Anonymous - 2020-09-02

    Oh, and I don't use QueryPreparer since I'm in a JPA environment, I can use ':varname' kind of placeholders, and get my result in Tuple instances (I use createNativeQuery).
    Might seem strange to use SQL when there's JPA, but we want to create reports with some flexibility and mapping to objects just isn't a good match (and Hibernate/JPA never does quite what you want) :)

     
    • James Ahlborn

      James Ahlborn - 2020-09-02

      so you are using NamedParamObject? you can still do the same encapsulation, though, you are just working withe hibernate apis instead of jdbc apis (i.e. the named param constants and the logic for building the query and setting the params are static utilities of the wrapping class).

       
      • Anonymous

        Anonymous - 2020-09-03

        I use NamedParamObject indeed :)

         
  • James Ahlborn

    James Ahlborn - 2020-09-04
    • status: open --> closed
    • Group: Unassigned --> sqlbuilder-3.0.1
     
  • James Ahlborn

    James Ahlborn - 2020-09-04

    So i might have gone a little wild, but added Conditions and Expressions classes with a bunch of static methods. makes writing sql expression much more succinct when used as static imports. nice suggestion!

    fixed in trunk will be in 3.01 release.

     
  • Anonymous

    Anonymous - 2020-09-04

    Sweet, glad you like it, and thanks :)

     

Log in to post a comment.