您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在模型类中使用javafx.beans属性

在模型类中使用javafx.beans属性

我将在这里提出不同意见。

正如我评论jewelsea的答案一样,只要您使用“属性访问”而不是“字段访问”,就可以在JPA中使用基于JavaFX属性的Bean。我链接到那里的博客文章对此进行了更详细的介绍,但是基本思想是任何注释都应该在get...()方法上,而不是在字段上。据我所知,这确实阻止了将任何只读JavaFX属性模式与JPA结合使用,但是我从来没有真正感觉到JPA在只读属性(即get方法和无set方法)中表现良好。

与我对jewelsea答案的评论相反,并受益于几个星期的工作(并且被安排为我面临使用JavaFX属性在JavaFX客户端上复制多个实体类的位置),我认为缺乏JavaFX属性的序列化可以解决。关键的观察结果是,您实际上只需要序列化属性的包装状态(而不是任何侦听器)。您可以通过实现java.io.ExternalizableExternalizable是的子接口Serializable,要求您填写readExternal(...)writeExternal(...)方法。可以实现这些方法以仅外部化属性包装的状态,而不是属性本身。这意味着,如果您的实体先序列化然后反序列化,您将得到一个新的属性实例,并且将不会保留任何侦听器(即,侦听器实际上变为transient),但是据我所知,这就是所需要的在任何合理的用例中。

我尝试用这种方式定义的bean,并且一切似乎都很好地工作。另外,我进行了一个小实验,使用杰克逊映射器在JSON表示形式之间进行转换,从而在客户端和静态Web服务之间传输它们。由于映射器仅依靠使用get和set方法,因此可以正常工作。

需要注意两点。与任何序列化一样,拥有无参数的构造函数也很重要。当然,由JavaFX属性包装的所有值本身必须可序列化- 再次,这与任何可序列化bean的规则相同。

关于JavaFX属性通过副作用起作用的观点已被很好地理解,并且在将这些属性(在某种程度上考虑到单线程模型的设计)移至潜在的多线程服务器时,需要格外小心。一个好的经验法则可能是,如果您使用此策略,则仅应在客户端注册侦听器(请记住,这些侦听器是暂时的,无论是通过序列化还是通过JSON表示,都可以传输回服务器)。当然,这表明在服务器端使用它们可能是一个糟糕的设计。在拥有“所有人的万事万物”的单个实体(JavaFX客户端的可观察属性,可序列化以实现持久性和/或远程访问,

最后,如果您确实使用了JPA批注,则这些批注具有运行时保留,这意味着(我认为)您的JavaFX客户端将需要在类路径上使用javax.persistence规范。

这是一个“四季皆宜的人”实体的示例:

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.time.MonthDay;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * Entity implementation class for Entity: Person
 *
 */
@Entity

public class Person implements Externalizable {


    private static final long serialVersionUID = 1L;

    public Person() {

    }

    public Person(String name, MonthDay birthday) {
        setName(name);
        setBirthday(birthday);
    }

    private final IntegerProperty id = new SimpleIntegerProperty(this, "id");

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public int getId() {
        return id.get();
    }

    public void setId(int id) {
        this.id.set(id);
    }

    public IntegerProperty idproperty() {
        return id ;
    }

    private final StringProperty name = new SimpleStringProperty(this, "name");

    // redundant, but here to indicate that annotations must be on the property accessors:
    @Column(name="name")
    public final String getName() {
        return name.get();
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    public StringProperty nameproperty() {
        return name ;
    }

    private final ObjectProperty<MonthDay> birthday = new SimpleObjectProperty<>();

    public final MonthDay getBirthday() {
        return birthday.get();
    }

    public final void setBirthday(MonthDay birthday) {
        this.birthday.set(birthday);
    }

    public ObjectProperty<MonthDay> birthdayproperty() {
        return birthday ;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(getId());
        out.writeObject(getName());
        out.writeObject(getBirthday());
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        setId(in.readInt());
        setName((String) in.readObject());
        setBirthday((MonthDay) in.readObject());
    }

}
java 2022/1/1 18:17:08 有588人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶