Builder Pattern and Static Factory Methods

106 views
Skip to first unread message

James

unread,
Mar 28, 2013, 2:31:15 PM3/28/13
to mybati...@googlegroups.com

I have a (Java) class with many instance fields (many of which are optional). I would like all fields (i.e. class) to be immutable. So, I would like to use the Builder Pattern for constructing instances of the class.

Can I configure myBatis to create an instance of a class using the Builder Pattern? I know that I could have myBatis return a map and use that map to build the instance in my code. However, I'm looking for a way to configure this mapping (or use some convention) similar to how I can create instance via use of Java Beans and constructors.

Also, is it possible to configure myBatis to create a instance of a class using a static factory method?

Jose María Zaragoza

unread,
Mar 29, 2013, 5:23:38 PM3/29/13
to mybati...@googlegroups.com


2013/3/28 James <johnson...@gmail.com>

I have a (Java) class with many instance fields (many of which are optional). I would like all fields (i.e. class) to be immutable. So, I would like to use the Builder Pattern for constructing instances of the class.

Can I configure myBatis to create an instance of a class using the Builder Pattern? I know that I could have myBatis return a map and use that map to build the instance in my code. However, I'm looking for a way to configure this mapping (or use some convention) similar to how I can create instance via use of Java Beans and constructors.

Also, is it possible to configure myBatis to create a instance of a class using a static factory method 


Hello

I don't understand your problem .
What do you want to use that class for ? Is it a returnClass ? is it a service class ?


Regards

Gin-Ting Chen

unread,
Mar 29, 2013, 8:24:27 PM3/29/13
to mybati...@googlegroups.com, mybati...@googlegroups.com
If you just want Mybatis to use your builder as the model then yes. If you want Mybatis to then call build, then no.
If you have a dao or service (as some people seem repulsed by daos ;)) layer in front of your Mybatis services then it's simple to call the build yourself
--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mybatis-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

James

unread,
Apr 2, 2013, 2:12:29 PM4/2/13
to mybati...@googlegroups.com
The class is in the model. My first question is in regards to using the builder pattern (on a model class) with myBatis. Here's an example:

package com.example.model;

// domain model class with builder
public final class CarFacts {

private final double price;
private final double numDoors;
private final String make;
private final String model;
private final String previousOwner;
private final String description;

public static class Builder {
// required params
private final double price;
private final String make;
private final String model;

// optional params
private final String previousOwner;
private final String description;
private final double numDoors;

public Builder(double price, String make, String model) {
this.price = price;
this.make = make;
this.model = model;
}

public Builder previousOwner(String previousOwner) {
this.previousOwner = previousOwner;
return this;
}
// other methods for optional param

public CarFacts build() {
return new CarFacts(this);
}
}

private CarFacts(Builder builder) {
this.price = builder.price;
//etc.
}
}

Then, I have a mapper as:

 
<!-- this doesn't work but I think h3adache suggest that I could have the resultType
be com.example.model.CarFacts.Builder and use the Builder constructor. But I'm not sure how
I would call the methods (such previousOwner(String)) to populate optional params -->

<mapper namespace="com.example.persistence.CarFactsMapper">
  <select id="selectCarFacts" resultType="com.example.model.CarFacts">
    select *
    from CarFacts
  </select>
    
</mapper>

Finally, I have the mapper interface:

package com.example.persistence.CarFactsMapper;

public interface CarFactsMapper{

List<CarFacts> selectCarFacts();

}

The second question is in regards to using a model class that create instances using a static factory method. For example:

public final class Person {

private final String lastName;
private final String firstName;

private Person(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}

public Person newInstance(String lastName, String firstName) {
return new Person(lastName, firstName);
}
}

Specifically, how can I have myBatis call newInstance(String, String)?

Jeff Butler

unread,
Apr 3, 2013, 9:51:50 AM4/3/13
to mybati...@googlegroups.com
MyBatis will not call these methods.  If you want to use this pattern, your best bet is to just return a Map of columns from the database and build the objects yourself in some layer of your application.  MyBatis can build immutable objects through constructor arguments or direct access to private fields.

Jeff Butler


--

James

unread,
Apr 3, 2013, 7:12:19 PM4/3/13
to mybati...@googlegroups.com
Hi Jeff,

Thanks for your response. I see how I can build immutable objects through constructor arguments. However, I'm not clear how immutable objects should be built via direct access to private fields. I have these fields as final and thus they must be initialized to compile. That being said, it appears that myBatis can get direct access (as you stated) and overwrite initialized final fields. For example, the price variable is initialized as follows

public final class CarFacts {

private final double price = 0.0;
.
.
.
// no explicitly defined constructor

}

and it (price) will get a new value assigned by myBatis. Is this the approach you had in mind for direct access to private final fields?

Thanks,

James

Jeff Butler

unread,
Apr 4, 2013, 9:38:17 AM4/4/13
to mybati...@googlegroups.com
Yes - that is what I meant.  MyBatis will overwrite final fields if allowed by the JRE.

Jeff Butler
Reply all
Reply to author
Forward
0 new messages