2

这是我模型的父母:

abstract public class ApiModel {
    // Problem 1
    public static ExpressionList<Model> find() {
        return null;
    }
    
    public static <T extends Model> T findById(Long id) {
        return null;
    }
}

一个模型 :

public class MyModel extends ApiModel {

    private static Model.Finder<Long,MyModel> find = new Model.Finder(Long.class, MyModel.class);

    public static ExpressionList<MyModel> find() {
        return find.where();
    }
    
    public static MyModel findById(Long id) {
        return find.byId(id);
    }
}

父母的控制器:

public class ApiController<T extends ApiModel> extends Controller {
    public Result list() {
            // Problem 2
        ExpressionList<T> list = T.find();
        return ok(Json.toJson(list.orderBy("name"), 10));
    }
    
    public Result create() {
        return update(null);
    }
    
    public Result details(Long id) {
            // Problem 3
        T model = T.findById(id);
        
        // ...
        return ok(result);
    }
    
    public Result update(Long id) {
            // Problem 4
        Form<T> form = form(T.class).bindFromRequest();

            T model = form.get();

            // Problem 5
            T.save();

        // ...
        return ok(result);
    }
    
    public Result delete(Long id) {
        // ...
        return ok(result);
    }
}

控制器

public class AController extends ApiController<MyModel> {
    public final static AController rest = new AController();
    
    private AController() {}
}

我面临的问题:

  1. 我需要find()返回ExpressionList<T extends Model>,但如果我把它放在这里,我就会出错。
  2. Pb1 使这个错误出现,它说“类型不匹配:无法从 ExpressionList 转换为 ExpressionList”。我想通过修复 1., 2. 也将被修复。
  3. 这很奇怪,它返回“绑定不匹配:ApiModel 类型的泛型方法 findById(Long) 不适用于参数 (Long)。推断的类型 T&Model 不是有界参数的有效替代品”
  4. 我当然不能用.class这个。但是我该怎么办呢?
  5. 由于模型使用注解来拥有@Entity,我不能在这里使用它,它无法识别:/

我认为一切都是相关的。也许我的代码设计不佳?

这就是这种结构的原因。我正在使用 PlayFramework(具有静态控制器),我喜欢继承,因此喜欢通用模型。但为此,我需要实例而不是静态引用,因此public final static AController rest. 但是,我无法访问模型(find& findById)的静态上下文。所以我做了ApiModel。但这也无济于事。

4

3 回答 3

2

ApiModel如果您稍微改写一下,则不需要该课程ApiController

public class ApiController<T extends Model> extends Controller {

    private Model.Finder<Long,T> finder;

    private final Class<T> modelClass;

    public ApiController(Class<T> modelClass) {
        this.modelClass = modelClass;
        finder = new Model.Finder(Long.class, modelClass);
    }

    public Result list() {
        ExpressionList<T> list = finder.where();
        return ok(Json.toJson(list.orderBy("name"), 10));
    }

    public Result details(Long id) {
        T model = finder.findById(id);

        // ...
        return ok(result);
    }

    public Result update(Long id) {
        // Problem 1
        Form<T> form = form(modelClass).bindFromRequest();

            T model = form.get();

            T.save();

        // ...
        return ok(result);
    }

    ...
}

public class AController extends ApiController<MyModel> {
    public final static AController rest = new AController();

    private AController() {
        super(MyModel.class);
    }

}
于 2012-08-11T14:42:45.480 回答
0

我不知道你为什么需要那些静态方法ApiModel

你应该能够ApiController赋予Classfor T

public class ApiController<T extends ApiModel> extends Controller {
    private final Class<T> tClass;
    ApiController(Class<T> tClass) {
        this.tClass = tClass;
    }

public class AController extends ApiController<MyModel> {
    ....
    private AController() {
        super(MyModel.class);
    }
于 2012-08-11T15:21:43.957 回答
0

从我的角度来看,这样做应该是一个坏主意。你可以在play中使用普通的方法,你只需要在路由列表中以a@开头引用该方法。

所以,如果你有这样的控制器:

public class MyController extends Controller {
    public Result index() {
        return TODO;
    }
}

您可以在路由器中这样使用:

GET         /           @controllers.MyController.index()
于 2015-01-06T12:12:13.530 回答