我有一个实体创建的问题。假设我有以下表格
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 = new Bar(1);bar1.setName("小麦");bar1。setFoo(新Foo (1));
与Foo使用integer类型的字段相反:
Bar = new Bar(1);bar2.setName("GlaDOS");
bar2.setFoo (1);我自己更喜欢第二种方法。是否有理由选择第一条路线?我遇到的一个问题是在解组XML时,我组合了实体和JAXB对象,在它们的情况下,Foo对象被设置为一个完全空的Foo对象,而不是一个id为1的Foo对象。
你觉得怎么样?
它叫做对象关系映射:)。如果您觉得JPA的附加特性比更简单的JDBC包装器更有价值,那么还有更多轻量级的替代方案可以将数据库列值填充到对象中。
映射对象所做的第一件事是允许您在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包装器上提供的主要功能之一。
。,如果你在@OneToMany
中用CascadeType.PERSIST
标记条形条列表,那么你可以这样做来制作新的条形条:
beginTransaction();
Foo foo = em.find(Foo.class, 1);
Bar newBar = new Bar();
//set up your Bar
foo.getBarCollection().add(newBar);
commitTransaction();
完成了!
似乎您在询问是否使用Integer Object或int数据类型。如果是这样,我建议使用int数据类型。当Java意识到将数字值放入Integer和Double对象中既麻烦又浪费内存空间时,它们就出现了。一个对象引用一个位置,该位置存储了您放入其中的所有值,从而允许您放入多个变量。数据类型只是存储数据。