1.单向一对多
单向一对多用得比较少(性能差),
@OneToMany
必须配置外键id,否则会多生成一张表,形成多对多的关系
,保存代码:
import cn.itsource.jpa.manytoone1.Product;
import cn.itsource.jpa.manytoone1.ProductDir;
import cn.itsource.util.JpaUtils;
import org.junit.Test;
import javax.persistence.EntityManager;
public class Test1 {
@Test
public void testName()throws Exception{
EntityManager entityManager = JpaUtils.getEntityManager();
}
@Test
public void testSave()throws Exception{
EntityManager entityManager = JpaUtils.getEntityManager();
Product p1 = new Product();
p1.setName("Yeezy");
Product p2 = new Product();
p2.setName("乔丹");
ProductDir dir = new ProductDir();
dir.setName("球鞋");
dir.getProduct().add(p1);
dir.getProduct().add(p2);
//开启事务
entityManager.getTransaction().begin();
//先保存一方,再保存多方
entityManager.persist(dir);
entityManager.persist(p1);
entityManager.persist(p2);
entityManager.getTransaction().commit();
entityManager.close();
}
@Test
public void testFind()throws Exception{
EntityManager entityManager = JpaUtils.getEntityManager();
ProductDir productDir = entityManager.find(ProductDir.class, 1L);
if(productDir.getProduct().size()>0){
System.out.println("有东西");
}else {
System.out.println("没有");
}
}
}
不管怎么保存(改变persist代码位置),它都会至少执行5条SQL语句完成保存功能(如下)。而完成同样的功能,我们使用单向多对一可以优化为3条。 因此,我们一般不使用单向一对多(原因:性能太差)
2.集合映射
org.hibernate.collection.internal.PersistentSet 实现了java.util.Set接口
org.hibernate.collection.internal.PersistentBag 实现了java.util.List接口;
声明集合时必须使用接口
2.1集合的使用
List/Set区别?
List是有序 可以重复 Set 无顺序,不能重复
Set 一般使用在多对多 或者 一对多
List 一般组合 一般使用单据上面
3.双向多对一(一对多)
.配置:
@OneToMany(mappedBy = "dir")
private List<Product> products = new ArrayList<>();
尽量让多方来维护的关系,一方放弃管理mappedBy
3.1 级联操作
级联:就是我操作一方数据,就同时可以多方的数据也一并操作;
.映射配置
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "dir")
private Set<Product> products = new HashSet<Product>();
级联删除
配置:
@OneToMany(cascade = CascadeType.REMOVE)
孤儿删除
@OneToMany(cascade = CascadeType.REMOVE,mappedBy = "dir",orphanRemoval = true)
强级联
@OneToMany(cascade = CascadeType.ALL,mappedBy = "dir",orphanRemoval = true)
4.单向多对多
保存代码
@Test
public void testName()throws Exception{
User u1 = new User();
u1.setName("石楚玉");
User u2 = new User();
u2.setName("玉楚石");
Role r1 = new Role();
r1.setName("日本人");
Role r2 = new Role();
r1.setName("玉桑");
//设置关系
u1.getRoles().add(r1);
u2.getRoles().add(r2);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
EntityManager entityManager = JpaUtils.getEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(u1);
entityManager.persist(u2);
entityManager.getTransaction().commit();
}
5.双向多对多
;配置
role:
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
@JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="role_id")},
inverseJoinColumns ={@JoinColumn(name="user_id")} )
private Set<User> users = new HashSet<>();
user:
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
@JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="user_id")},
inverseJoinColumns ={@JoinColumn(name="role_id")} )
private Set<Role> roles = new HashSet<>();
user配置级联保存的代码:
EntityManager entityManager = JpaUtils.getEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(user1);
entityManager.persist(user2);
entityManager.persist(user3);
entityManager.getTransaction().commit();