Ebean和Play!不使用.select()过滤列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ebean和Play!不使用.select()过滤列相关的知识,希望对你有一定的参考价值。

我正试图在Ebean中使用Play! Framework获取模型的一部分,但我遇到了一些问题而且我没有找到任何解决方案。

我有这些模型:

User

@Entity
@Table(name = "users")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User extends Model{
    @Id
    private int id;
    @NotNull
    @Column(name = "first_name", nullable = false)
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @NotNull
    @Column(nullable = false)
    private String username;
    @NotNull
    @Column(nullable = false)
    private String email;
    private String gender;
    private String locale;
    private Date birthday;
    private String bio;
    @NotNull
    @Column(nullable = false)
    private boolean active;
    private String avatar;
    @Column(name = "created_at",nullable = false)
    private Date createdAt;

    @OneToMany
    private List<UserToken> userTokens;

    // Getters and Setters omitted for brevity
}

UserToken

@Entity
@Table(name = "user_tokens")
public class UserToken extends Model {
    @Id
    private int id;
    @Column(name = "user_id")
    private int userId;
    private String token;
    @Column(name = "created_at")
    @CreatedTimestamp
    private Date createdAt;

    @ManyToOne
    private User user;

    // Getters and Setters omitted for brevity
}

然后,我有一个控制器UserController

public class UserController extends Controller{
    public static Result list(){
        User user = Ebean.find(User.class).select("firstName").where().idEq(1).findUnique();
        return Results.ok(Json.toJson(user));
    }
}

我预计,当使用.select()时,它会过滤字段并加载一个部分对象,但它会完全加载它。在日志中,还有更多问题,我不知道为什么会发生这种问题。

Statements logs

它正在进行3次查询。首先是我想要的那个。然后它使一个人获取整个模型,另一个人找到UserTokens。我不知道为什么它会执行最后两个查询,我只想要执行第一个查询。

解决方案编辑

在已经接受了@biesior建议我必须建立Json的事实之后,我发现(在nowhere之外)解决方案!

public static Result list() throws JsonProcessingException {
    User user = Ebean.find(User.class).select("firstName").where().idEq(1).findUnique();
    JsonContext jc = Ebean.createJsonContext();
    return Results.ok(jc.toJsonString(user));
}

在使用.select()之后,我只渲染在JsonContext中选择的想要的字段。

答案

这很简单,当你使用select("...")它总是得到id字段(无法避免 - 它是映射所需)+所需字段,但如果以后你试图访问第一个select("...")中没有的字段 - Ebean重复查询并映射整个对象。

换句话说,您正在访问第一个查询中不可用的字段,分析您的控制器和/或模板,查找所有字段并将其添加到您的选择中(即使它们已在评论中注释了常见的html注释)视图!)

另一答案

在最新版本的Play Framework(2.6)中,正确的方法是:

   public Result list() {
        JsonContext json = ebeanServer.json();

        List<MyClass> orders= ebeanServer.find(MyClass.class).select("id,property1,property2").findList();

        return ok(json.toJson(orders));
    }

以上是关于Ebean和Play!不使用.select()过滤列的主要内容,如果未能解决你的问题,请参考以下文章

更新如何与 Ebean 和 Play 框架一起使用

Play Ebean 从 2.4 升级到 2.5 后不生成 Id

Lob 使用 play 框架和 Ebean 和 H2 返回 null

Java Play 中的配置 - ebean 和 postgresql

如何通过 java 为 Play!2.1.1 配置 ebean 服务器

数据库“默认”需要进化!尝试使用 play framework 2.7.0 和 Ebean 连接到 MySQL 时