JPA注解

 

1、Persistence用来创建entityManagerFactory ,其中最重要的对象entityManager ,EntityManager 是完成持久化操作的核心对象。

 

entityManagerFactory = Persistence.createEntityManagerFactory("jpa-1");
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();

 

2、EntityManager 常用API

 

① find :类似于 hibernate 中 Session 的 get 方法. 立即加载

 

  Customer customer = entityManager.find(Customer.class, 1);

 

② getReference: 类似于 hibernate 中 Session 的 load 方法 懒加载

 

  Customer customer = entityManager.getReference(Customer.class, 1);

 

③ persist :类似于 hibernate 的 save 方法. 使对象由临时状态变为持久化状态. 

 

和 hibernate 的 save 方法的不同之处: 若对象有 id, 则不能执行 insert 操作, 而会抛出异常. 

 

  entityManager.persist(customer);

 

④ remove :类似于 hibernate 中 Session 的 delete 方法. 把对象对应的记录从数据库中移除,但注意: 该方法只能移除 持久化 对象. 而 hibernate 的 delete 方法实际上还可以移除 游离对象.

 

  entityManager.remove(customer);

 

⑤ merge :总的来说: 类似于 hibernate Session 的 saveOrUpdate 方法.

 

  第一种情况:若传入的是一个临时对象,

 

  会创建一个新的对象, 把临时对象的属性复制到新的对象中, 然后对新的对象执行持久化操作.

 

  所以新的对象中有 id, 但以前的临时对象中没有 id. 

 

  第二种情况:若传入的是一个游离对象, 即传入的对象有 OID. 

 

  1. 若在 EntityManager 缓存中没有该对象

 

  2. 若在数据库中也没有对应的记录

 

  3. JPA 会创建一个新的对象, 然后把当前游离对象的属性复制到新创建的对象中

 

  4. 对新创建的对象执行 insert 操作. 

 

  第三种情况:若传入的是一个游离对象, 即传入的对象有 OID. 

 

  1. 若在 EntityManager 缓存中没有该对象

 

  2. 若在数据库中有对应的记录

 

  3. JPA 会查询对应的记录, 然后返回该记录对一个的对象, 再然后会把游离对象的属性复制到查询到的对象中.

 

  4. 对查询到的对象执行 update 操作. 

 

  第四种情况:若传入的是一个游离对象, 即传入的对象有 OID. 

 

  1. 若在 EntityManager 缓存中有对应的对象

 

  2. JPA 会把游离对象的属性复制到查询到EntityManager 缓存中的对象中.

 

  3. EntityManager 缓存中的对象执行 update . 

 

 

 

 参考:尚硅谷_JPA.pptx

 

 

一:单项多对一

  //映射单向 n-1 的关联关系
  //使用 @ManyToOne 来映射多对一的关联关系
  //使用 @JoinColumn 来映射外键.
  //可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略
  @JoinColumn(name="CUSTOMER_ID")
  @ManyToOne(fetch=FetchType.LAZY)
  public Customer getCustomer() {
    return customer;
  }

二:单项一对多

  //映射单向 1-n 的关联关系
  //使用 @OneToMany 来映射 1-n 的关联关系
  //使用 @JoinColumn 来映射外键列的名称
  //可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略
  //可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略.

  @JoinColumn(name="CUSTOMER_ID")
  @OneToMany(fetch=FetchType.LAZY,cascade={CascadeType.REMOVE})
  public Set<Order> getOrders() {
    return orders;
  }

@OneToMany描述一个一对多的关联,该属性应该为集体类型,在数据库中并没有实际字段.
fetch:表示抓取策略,默认为FetchType.LAZY,因为关联的多个对象通常不必从数据库预先读取到内存
cascade:表示级联操作策略,对于OneToMany类型的关联非常重要,通常该实体更新或删除时,其关联的实体也应当被更新删除

三:双向多对一(等同于双向一对多)

一方:

  //可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略
  //可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略. 
  //注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了. 
  @OneToMany(fetch=FetchType.LAZY,cascade={CascadeType.REMOVE},mappedBy="customer")
  public Set<Order> getOrders() {
    return orders;
  }

多方维护:

  @JoinColumn(name="CUSTOMER_ID")
  @ManyToOne(fetch=FetchType.LAZY)
  public Customer getCustomer() {
    return customer;
  }

四:双向一对一

维护方:

 

  //使用 @OneToOne 来映射 1-1 关联关系。
  //若需要在当前数据表中添加外键则需要使用 @JoinColumn 来进行映射. 注意, 1-1 关联关系, 需要添加 unique=true
  @JoinColumn(name="MGR_ID", unique=true)
  @OneToOne(fetch=FetchType.LAZY)
  public Manager getMgr() {
    return mgr;
  }

被维护方:
  //对于不维护关联关系, 没有外键的一方, 使用 @OneToOne 来进行映射, 不建议设置 mappedBy
  @OneToOne(mappedBy="mgr")
  public Department getDept() {
  return dept;
  }

 

五:多对多

维护方:

  //使用 @ManyToMany 注解来映射多对多关联关系
  //使用 @JoinTable 来映射中间表
  //1. name 指向中间表的名字
  //2. joinColumns 映射当前类所在的表在中间表中的外键
  //2.1 name 指定外键列的列名
  //2.2 referencedColumnName 指定外键列关联当前表的哪一列
  //3. inverseJoinColumns 映射关联的类所在中间表的外键
  @JoinTable(name="ITEM_CATEGORY",
  joinColumns={@JoinColumn(name="ITEM_ID", referencedColumnName="ID")},
  inverseJoinColumns={@JoinColumn(name="CATEGORY_ID", referencedColumnName="ID")})
  @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)  
  public Set<Category> getCategories() {
    return categories;
  }

被维护方:

  @ManyToMany(mappedBy="categories")
  public Set<Item> getItems() {
    return items;
  }

 

 备注:

使用JPA的时候,如果A B两个实体间是一对多,多对一的关系,如果不在@OneToMany里加入mappedBy属性(相当于inverse=”true”)会导致自动生成一个多余的中间表。比如:
JPA,在@OneToMany里加入mappedBy属性避免生成中间表。且mappedBy只有在双向关联时,才会使用这个属性。
双向一对一,多对多,一对多(多对一)的时候才会使用。

注解属性mappedBy详解

 首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@manyToMany中,不能够用在@manyToOne中;
第二,这个注解看网上的意思可以简单地理解为:这个注解用在主表的一方,就是被引用的一方;
第三,这个注解是与@JoinColumn这个注解是互斥的,因为@JoinColumn这个注解使用在拥有外键的表的一方,就是从表的一方。
第四,这个注解的属性值是:指向另外一个类中定义的一个属性,这个属性的类型是当前这个类;有点绕,有点晕,是的;就是说它的属性值指向的是:与之关联类中定义的指向本类的一个属性!

mappedBy:表示关系由另一方维护。值为该表在另一张表里面的属性名称。

若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了. 

 

posted on 2017-09-09 16:35  好好学习,天天睡觉  阅读(34)  评论(0)    收藏  举报