我可以使用Builder模式配置myBatis来创建类的实例吗?

Jam*_*mes 8 java builder-pattern mybatis static-factory

我有一个(Java)类,有许多实例字段(其中许多是可选的).我希望所有字段(因此类)都是不可变的.所以,我想使用Builder Pattern来构造类的实例.

我可以使用Builder模式配置myBatis来创建类的实例吗?我知道我可以让myBatis返回一张地图并使用该地图在我的代码中构建实例.但是,我正在寻找一种方法来配置这种映射(或使用一些约定),类似于如何通过使用Java Bean和构造函数来创建实例.

编辑(包括一个例子)

这是一个例子:

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.
}
}
Run Code Online (Sandbox Code Playgroud)

然后,我有一个mapper:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

最后,我有mapper界面:

package com.example.persistence.CarFactsMapper;

public interface CarFactsMapper{

List<CarFacts> selectCarFacts();

}
Run Code Online (Sandbox Code Playgroud)

我还希望能够通过myBatis使用静态工厂方法创建实例.例如:

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);
}
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我怎样才能让myBatis调用newInstance(String,String)?

小智 -2

您不需要使用构建器或静态工厂方法。是的,如果您想保持不变性,这些模式肯定会有所帮助,因为可能会发生突变,我们应该说“在实例之间”,例如,因为构建器在调用 build() (以创建新的不可变实例)之前正在发生突变。

不过,不变性与给定实例的构造方式无关。它并不能帮助我们为可变的类编写构建器和静态工厂方法。在施工时,所有对象尚未发生突变,因此真正重要的是接下来会发生什么(在建筑商和工厂离开之后)。

您需要做的就是关注类本身,并认为这个类是不可变的就可以了。常规的 myBatis 映射应该没问题 - 节省您编写构建器的时间。

那么 - 你的类是不可变的吗?是的,因为你的所有字段都是最终的,并且要么是原始类型,要么是 String(在 Java 中是不可变的!)。如果您有其他非原始字段,那么您希望它们是最终的(从技术上讲,您不需要编写最终的,但建议这样做,只要该字段从未真正重新分配)并且您希望他们的类一直向下遵循这些规则的递归。

我希望这会有所帮助,我想表达的一点是,构建器模式和工厂方法对于管理构造很有帮助,但它们不会免费为您提供不变性,并且您始终需要编写构造函数。