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 属性了.
浙公网安备 33010602011771号