JPA 系列教程4-单向一对多
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
源码地址
如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!
JPA 系列教程4-单向一对多的更多相关文章
- JPA 系列教程5-双向一对多
双向一对多的ddl语句 同单向多对一,单向一对多表的ddl语句一致 Product package com.jege.jpa.one2many; import javax.persistence.En ...
- JPA 系列教程21-JPA2.0-@MapKeyColumn
@MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...
- JPA 系列教程7-双向多对多
双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...
- JPA 系列教程3-单向多对一
JPA中的@ManyToOne 主要属性 - name(必需): 设定"many"方所包含的"one"方所对应的持久化类的属性名 - column(可选): 设 ...
- JPA 系列教程17-继承-独立表-TABLE_PER_CLASS
PerTable策略 每个具体的类一个表的策略 举例 这种映射策略每个类都会映射成一个单独的表,类的所有属性,包括继承的属性都会映射成表的列. 这种映射策略的缺点是:对多态关系的支持有限,当查询涉及到 ...
- JPA 系列教程16-继承-联合子类-JOINED
联合子类策略 这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类. 举例 如果实体类Teacher继承实体类Person,实体类Student也继承自 ...
- JPA 系列教程13-复合主键-@EmbeddedId+@Embeddable
复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id和复合主键-2个@Id+ ...
- JPA 系列教程12-复合主键-2个@Id+@IdClass
复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id一样 Airline p ...
- JPA 系列教程10-双向一对一关联表
双向一对一关联表的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255 ...
随机推荐
- Glusterfs[转]
原文地址:http://support.huawei.com/ecommunity/bbs/10253434.html 1. GlusterFS概述 GlusterFS是Scale-Out存 ...
- java.lang.ClassNotFoundException: com.mysql.jdbc.Driver问题
java.lang.ClassNotFoundException: com.mysql.jdbc.Driverat org.apache.catalina.loader.WebappClassLoad ...
- Java IO 理解流的概念
Java IO 理解流的概念 @author ixenos 在理解流时首先理解以下概念 1.流的来源和去向一般在构造器指出 2.方法中的形参一般是将流输出到某个位置,读取(INPUT)流从流读出数据( ...
- Django中Admin样式定制
Django自带的admin在展示数据是样式有点单一,我们可以自己定义数据的展示样式. 一.自定义数据展示样式 1.后台查询书记列表时,同时列出出版社和出版时间: admin.py文件 from dj ...
- wep密钥的长度
理论上,WEP可以搭配任意长度的密钥,因为RC4并未要求非得使用特定长度的密钥. 不过,大多数产品均支持一种或两种长度的密钥.唯一出现在标准中的密钥长度时64位的WEP种子(seed),其中40位是两 ...
- 如何安全退出已调用多个Activity的Application?
如何退出Activity?如何安全退出已调用多个Activity的Application? 退出Activity直接调用finish()方法 //用户点击back键就是退出一个Activity 退出 ...
- kettle在linux启动spoon.sh报错
org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed] at org.eclipse.swt.SWT.error ...
- HDU 1264 Counting Squares(模拟)
题目链接 Problem Description Your input is a series of rectangles, one per line. Each rectangle is speci ...
- chapter9_3 协同程序实现迭代器
将循环迭代器视为"生产者-消费者"模式的一种特例:迭代器产生的数据供循环体消费. 因此,用协同程序写迭代器就理所当然了.因为协同程序可以一改传统调用者与被调用者之间的关系. 有了这 ...
- Android Lights
Android Lights 很多Android手机上都配有LED灯,手机在充电.新来短信等时候都会有相应的指示灯提示. Android系统之中,一共定义了8个逻辑灯,包含:背光,键盘灯,按键灯,充电 ...