我有一个关于实体创建的问题。说我有以下表格
create table "foo" (
"id" integer primary key,
"name" varchar
);
create table "bar" (
"id" integer primary key,
"name" varchar,
"fk_foo" integer references foo(id)
);
我想知道哪些对于实体最好,在实体类中使用foo对象作为外键引用,或者在实体中使用整数。
使用Netbeans 6.9我生成了以下实体:
@Entity
@Table(name = "bar")
@NamedQueries({
@NamedQuery(name = "Bar.findAll", query = "SELECT b FROM Bar b"),
@NamedQuery(name = "Bar.findById", query = "SELECT b FROM Bar b WHERE b.id = :id"),
@NamedQuery(name = "Bar.findByName", query = "SELECT b FROM Bar b WHERE b.name = :name")})
public class Bar implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@JoinColumn(name = "fk_foo", referencedColumnName = "id")
@ManyToOne
private Foo foo;
public Bar() {
}
@Entity
@Table(name = "foo")
@NamedQueries({
@NamedQuery(name = "Foo.findAll", query = "SELECT f FROM Foo f"),
@NamedQuery(name = "Foo.findById", query = "SELECT f FROM Foo f WHERE f.id = :id"),
@NamedQuery(name = "Foo.findByName", query = "SELECT f FROM Foo f WHERE f.name = :name")})
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "foo")
private Collection<Bar> barCollection;
public Foo() {
}
现在,当我必须创建一个新的Bar对象时,我还必须创建一个新的Foo对象。所以我创建了以下栏。请记住,我从实体中删除了setter和所有默认构造函数。
Bar bar1 = new Bar(1); bar1.setName( “wheatly”); bar1.setFoo(new Foo(1));
与为Foo使用字段类型的整数相反:
Bar bar2 = new Bar(1); bar2.setName( “GLaDOS的”); bar2.setFoo(1);
我更喜欢自己的第二种方法。是否有理由选择第一条路线更好?我遇到的一个问题是解组XML我已经组合了实体和JAXB对象,在他们的例子中,Foo对象被设置为一个完全为空的Foo对象而不是id为1的Foo对象。
您怎么看?
答案 0 :(得分:2)
嗯,它被称为对象关系映射:)。如果你没有在更简单的JDBC包装器中找到JPA的附加功能的价值,那么有更多轻量级的替代品可以将数据库列值填充到对象中。
映射对象的第一件事就是允许您在JPQL中自然地编写联接。您不能在JPQL中进行任意连接,必须将它们定义为对象映射。
例如,如果您在条形图上的所有内容都是ID的数字值,并且您希望找到具有特定foo的数字,那么您最终会使用select b from Bar b, Foo f where bar.fooId = f.id and f.name = :fooName;
如果你用正常的对象引用方式映射它,你可以编写
select b from Bar b where b.foo.name = :fooName;
根据您正在使用的数据库以及是否/如何重写查询,第一个查询中的笛卡尔积可能是坏消息。
其次,如果不映射对象,则不能使用传递持久性。您将重新使用EntityManager显式地导致每个单独的插入和更新,就像它只是一个JDBC包装器一样。通过传递持久性(CASCADE设置)将所有显式持久化/合并插入/更新抽象到ORM层是JPA提供的主要内容之一,而不是简单的JDBC包装器。
例如,如果您在CascadeType.PERSIST
中标记了@OneToMany
栏的列表,那么您可以通过这样做来制作新栏:
beginTransaction();
Foo foo = em.find(Foo.class, 1);
Bar newBar = new Bar();
//set up your Bar
foo.getBarCollection().add(newBar);
commitTransaction();
完成!
答案 1 :(得分:0)
似乎您在询问是否使用Integer Object或int数据类型。如果是这样,我会推荐int数据类型。当他们意识到将数值放入Integer和Double对象既麻烦又浪费内存空间时,Java想出了它们。对象是指存储您放入其中的所有值的位置,因此允许您放入多个变量。数据类型只存储数据。