您的位置:首页 > 其它

JPA 菜鸟教程 4 单向一对多

2016-12-10 23:56 483 查看

GitHub

JPA中的@OneToMany

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
String mappedBy() default "";
boolean orphanRemoval() default false;
}


主要属性

- # targetEntity属性表示默认关联的实体类型,默认为当前标注的实体类;

因为一对多的实体集合时保存在集合类中,因此必须指明集合类中保存的具体类型:

1)指定集合泛型的具体类型;如:Set getProducts() {…

2)指定targetEntity属性类型;如:@OneToMany(targetEntity=Product.class,casade={CascadeTypeType.ALL})

- # cascade属性表示与此实体一对一关联的实体的联级样式类型。联级样式上当对实体进行操作时的策略。

说明:在定义关系时经常会涉及是否定义Cascade(级联处理)属性,担心造成负面影响.

·不定义,则对关系表不会产生任何影响

·CascadeType.PERSIST (级联新建)

·CascadeType.REMOVE (级联删除)

·CascadeType.REFRESH (级联刷新)

·CascadeType.MERGE (级联更新)中选择一个或多个。

·还有一个选择是使用CascadeType.ALL ,表示选择全部四项

- # fetch属性是该实体的加载方式,有两种:LAZY和EAGER。默认为惰性加载,一般也建议使用惰性加载。

- # mappedBy属性用于双向关联实体时使用。

- # orphanRemoval属性用于双向关联实体时使用。

单向一对多(@OneToMany)关联是比较少用的(一般用双向一对多代替)。一个商品类型对应多个商品,通过商品类型可以获得该商品类型的多个商品的信息,商品类型和商品就是一对多的关系。

单向一对多表的ddl语句

同单向多对一表的ddl语句一致

Product

package com.jege.jpa.one2many;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
* @author JE哥
* @email 1272434821@qq.com
* @description:单向
*/
@Entity
@Table(name = "t_product")
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;

public Product() {

}

public Product(String name) {
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

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

@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + "]";
}

}


ProductType

package com.jege.jpa.one2many;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
* @author JE哥
* @email 1272434821@qq.com
* @description:单向:一个产品类型下面有多个产品
*/
@Entity
@Table(name = "t_product_type")
public class ProductType {
@Id
@GeneratedValue
private Long id;
private String name;
// 一对多:集合Set
@OneToMany
@JoinColumn(name = "type_id")
private Set<Product> products = new HashSet<Product>();

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

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

public Set<Product> getProducts() {
return products;
}

public void setProducts(Set<Product> products) {
this.products = products;
}

@Override
public String toString() {
return "ProductType [id=" + id + ", name=" + name + "]";
}

}


One2ManyTest

package com.jege.jpa.one2many;

import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
* @author JE哥
* @email 1272434821@qq.com
* @description:单向一对多Test
*/
public class One2ManyTest {
private static EntityManagerFactory entityManagerFactory = null;
private EntityManager entityManager = null;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");
}

// 一次性保存1一个商品类型,保存这个商品类型下面的2个产品商品
// 不过无论怎样调整保存一方商品类型,还是保存多方商品的顺序,都会出现多余的update语句,从而影响性能
@Before
public void persist() throws Exception {
entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();

ProductType type = new ProductType();
type.setName("商品类型类型1");

Product product1 = new Product("商品1");
Product product2 = new Product("商品2");

// 只能从一方建立到多方的关系
type.getProducts().add(product1);
type.getProducts().add(product2);// 临时状态

entityManager.persist(type);// 持久化状态 1 类型1
entityManager.persist(product1);// 持久化状态,只保存了name属性,type_id没有保存:1 商品1 null
entityManager.persist(product2);// 持久化状态,只保存了name属性,type_id没有保存:2 商品2 null

// type.getProducts(商品1的id=1,商品2的id=2)出现脏数据
// 脏数据在当前事务范围内出现,2条更新语句
}

@Test
public void find() throws Exception {
System.out.println("---------------------");
// 不能通过一方获取多方集合是否为null,来判断是否一方是否有多方的数据,只能通过一方获取多方集合.size()来判断
ProductType type = entityManager.find(ProductType.class, 1L);
System.out.println(type);
Set<Product> products = type.getProducts();
if (products.size() > 0) {
System.out.println("当前商品类型下面是有商品的");
} else {
System.out.println("当前商品类型下面是没有商品的");
}
}

@After
public void tearDown() throws Exception {
entityManager.getTransaction().commit();
if (entityManager != null && entityManager.isOpen())
entityManager.close();
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
if (entityManagerFactory != null && entityManagerFactory.isOpen())
entityManagerFactory.close();
}

}


其他关联项目

JPA 菜鸟教程 3 单向多对一

http://blog.csdn.net/je_ge/article/details/53493897

源码地址

https://github.com/je-ge/jpa

如果觉得我的文章或者代码对您有帮助,可以请我喝杯咖啡。

您的支持将鼓励我继续创作!谢谢!



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: