1 单向的一对多

1.1 配置

多方配置
 @Entity@Table(name=“t_product”)
 public class Product {
 @Id
 @GeneratedValue
 private Long id;
 private String name;
 }
 1方配置
 @Entity
 @Table(name=“t_productDir”)
 public class ProductDir {
 @Id
 @GeneratedValue
 private Long id;
 private String name;
 //泛型必须添加进去
 @OneToMany
 @JoinColumn(name=“dir_id”)
 private Set products = new HashSet<>();
 }1.2 保存
无论怎么保存,都在额外发送sql ,所有一般不用单向一对多
1.3 查询
lazy加载
使用 Set集合 HashSet 打印出来 PersistentSet
 PersistentSet 它是Set的实现类 和 HashSet一样 ,PersistentSet 和 HashSet都是
 Set的实现类,是兄弟关系 --在定义实体的集合的时候,不要定义HashSet
 //PersistentBag 也是 List的实现类,和ArrayList一样,ArrayList和PersistentBag都是
 List的实现 ,是兄弟关系 --在定义实体的集合的时候,不要定义ArrayList总结:在定义实体类的时候时候,如果使用到集合,就使用集合接口的方式
1.4集合的使用
现在在定义集合的时候,什么情况下使用List ,什么情况下使用Set?
List/Set区别?
 List是有序 可以重复 Set 无顺序,不能重复
Set 一般使用在多对多 或者 一对多
List 一般组合 一般使用单据上面
1.5 集合排序 orderby
配置
@OneToMany
 @JoinColumn(name = “dir_id”)
 @OrderBy(“price DESC”) //根据price的降序排列
 private List products = new ArrayList(); = new HashSet();2 双向的一对多 或者 多对一
配置:尽量让多方来维护的关系,一方放弃管理mappedBy
 @OneToMany(mappedBy = “dir”)
 private List products = new ArrayList<>();2.1级联操作保存
级联:就是我操作一方数据,就同时可以多方的数据也一并操作
persist(dir);
级联分为:级联保存 级联删除
@OneToMany(cascade = CascadeType.PRESIST)
2.2 级联删除
@OneToMany(cascade = CascadeType.REMOVE)2.3 孤儿删除(掌握)
让一方解除关系 ,才能从1方删除多方
@OneToMany(cascade = CascadeType.REMOVE,mappedBy = “dir”,orphanRemoval = true)
2.4 强级联 --后面项目里使用 组合关系(单据)
@OneToMany(cascade = CascadeType.ALL,mappedBy = “dir”,orphanRemoval = true)
3 单向多对多
3.1单向多对多配置
多对多
User
@Entity
 @Table(name=“t_user”)
 public class User {
 @Id
 @GeneratedValue
 private Long id;
 private String name;
 @ManyToMany
 @JoinTable(name=“t_user_role”,joinColumns={@JoinColumn(name=“user_id”)},
 inverseJoinColumns ={@JoinColumn(name=“role_id”)} )
 private Set roles = new HashSet<>();
 }Role
@Entity
 @Table(name=“t_role”)
 public class Role {
 @Id @GeneratedValue
 private Long id;
 private String name;
 }3.2 单向对多对保存数据
保存代码
//3个用户 2个角色
 User user1 = new User();
 user1.setName(“渣渣辉”);
 User user2 = new User();
 user2.setName(“光头强”);
 User user3 = new User();
 user3.setName(“王天霸”);
 Role role1 = new Role();
 role1.setName(“演员”);
 Role role2 = new Role();
 role2.setName(“导演”);
 //设置关系
 user1.getRoles().add(role1);
 user2.getRoles().add(role1);
 user3.getRoles().add(role1);
 user1.getRoles().add(role2);
 user2.getRoles().add(role2);
 //保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 entityManager.getTransaction().begin();
 entityManager.persist(user1);
 entityManager.persist(user2);
 entityManager.persist(user3);
 entityManager.persist(role1);
 entityManager.persist(role2);
 entityManager.getTransaction().commit();查询:如果要使用lazy加载 自己配置lazy就可以
4 双向多对多
4.1配置
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 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 roles = new HashSet<>();4.2操作
(1)级联保存:
user配置级联保存
EntityManager entityManager = JpaUtils.getEntityManager();
 entityManager.getTransaction().begin();
 entityManager.persist(user1);
 entityManager.persist(user2);
 entityManager.persist(user3);
 entityManager.getTransaction().commit();(2)删除1 先删除中间表,再删除user1
//保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 User user = entityManager.find(User.class, 1L);
 entityManager.getTransaction().begin();
 entityManager.remove(user);
 entityManager.getTransaction().commit();(3)删除2 删除user1的所有包含角色(role1,role2),不能删除user1(只删除中间表)
//保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 User user = entityManager.find(User.class, 1L);
 entityManager.getTransaction().begin();
 user.getRoles().clear();
 entityManager.getTransaction().commit();(4)删除user1的一个角色,不能删除user1(只删除中间表)
//保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 User user1 = entityManager.find(User.class, 1L);
 Role role1 = entityManager.find(Role.class, 1L);
 entityManager.getTransaction().begin();
 user1.getRoles().remove(role1);
 entityManager.getTransaction().commit();(5)删除 用户3的角色1 添加用户3的角色2
@Test
 public void testDelete4()throws Exception{
 //保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 User user3 = entityManager.find(User.class, 3L);
 Role role1 = entityManager.find(Role.class, 1L);
 Role role2 = entityManager.find(Role.class, 2L);
 entityManager.getTransaction().begin();
 user3.getRoles().remove(role1);
 user3.getRoles().add(role2);
 entityManager.getTransaction().commit();
 }(5)级联删除
配置
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
 @JoinTable(name=“t_user_role”,joinColumns={@JoinColumn(name=“user_id”)},
 inverseJoinColumns ={@JoinColumn(name=“role_id”)} )代码: 把user3 删除 相关的角色删除 在中间表相关的数据删除
@Test
 public void testDelete5()throws Exception{
 //保存数据
 EntityManager entityManager = JpaUtils.getEntityManager();
 User user3 = entityManager.find(User.class, 3L);
 entityManager.getTransaction().begin();
 entityManager.remove(user3);
 entityManager.getTransaction().commit();}

5 一对一 (了解)

一对一 可以看成 一对多 或者 多对一的特殊情况

一对一场景:

QQ 和 QQZone

配置了解 后面不用 一般使用多对1来代替一对一

重点配置:

(1)建议使用单向 多 对一 不要使用单向一对多

(2)如果要使用1对多,尽量使用双向配置,让1方放弃管理

(3) 多对多 如果想相互获取数据 配置双向,如果单向操作 就配置单向

(4) 使用 多对一 来代替一对一 ,如果实在使用一对一 使用唯一外键的方式