JPA学习笔记
Posted 普通网友
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA学习笔记相关的知识,希望对你有一定的参考价值。
映射关联关系
Order.java
package com.atguigu.jpa.helloworld;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Table(name="JPA_ORDERS")
@Entity
public class Order
private Integer id;
private String orderName;
private Customer customer;
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="ORDER_NAME")
public String getOrderName()
return orderName;
public void setOrderName(String orderName)
this.orderName = orderName;
//映射单向 n-1 的关联关系
//使用 @ManyToOne 来映射多对一的关联关系
//使用 @JoinColumn 来映射外键.
//可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略
@JoinColumn(name="CUSTOMER_ID")
@ManyToOne(fetch=FetchType.LAZY)
public Customer getCustomer()
return customer;
public void setCustomer(Customer customer)
this.customer = customer;
Customer.java
package com.atguigu.jpa.helloworld;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@NamedQuery(name="testNamedQuery", query="FROM Customer c WHERE c.id = ?")
@Cacheable(true)
@Table(name="JPA_CUTOMERS")
@Entity
public class Customer
private Integer id;
private String lastName;
private String email;
private int age;
private Date createdTime;
private Date birth;
public Customer()
// TODO Auto-generated constructor stub
public Customer(String lastName, int age)
super();
this.lastName = lastName;
this.age = age;
private Set<Order> orders = new HashSet<>();
// @TableGenerator(name="ID_GENERATOR",
// table="jpa_id_generators",
// pkColumnName="PK_NAME",
// pkColumnValue="CUSTOMER_ID",
// valueColumnName="PK_VALUE",
// allocationSize=100)
// @GeneratedValue(strategy=GenerationType.TABLE,generator="ID_GENERATOR")
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="LAST_NAME",length=50,nullable=false)
public String getLastName()
return lastName;
public void setLastName(String lastName)
this.lastName = lastName;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
public int getAge()
return age;
public void setAge(int age)
this.age = age;
@Temporal(TemporalType.TIMESTAMP)
public Date getCreatedTime()
return createdTime;
public void setCreatedTime(Date createdTime)
this.createdTime = createdTime;
@Temporal(TemporalType.DATE)
public Date getBirth()
return birth;
public void setBirth(Date birth)
this.birth = birth;
//映射单向 1-n 的关联关系
//使用 @OneToMany 来映射 1-n 的关联关系
//使用 @JoinColumn 来映射外键列的名称
//可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略
//可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略.
//注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了.
// @JoinColumn(name="CUSTOMER_ID")
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.REMOVE,mappedBy="customer")
public Set<Order> getOrders()
return orders;
public void setOrders(Set<Order> orders)
this.orders = orders;
//工具方法. 不需要映射为数据表的一列.
@Transient
public String getInfo()
return "lastName: " + lastName + ", email: " + email;
@Override
public String toString()
return "Customer [id=" + id + ", lastName=" + lastName + ", email="
+ email + ", age=" + age + ", createdTime=" + createdTime
+ ", birth=" + birth + "]";
Department.java
package com.atguigu.jpa.helloworld;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Table(name="JPA_DEPARTMENTS")
@Entity
public class Department
private Integer id;
private String deptName;
private Manager mgr;
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="DEPT_NAME")
public String getDeptName()
return deptName;
public void setDeptName(String deptName)
this.deptName = deptName;
//使用 @OneToOne 来映射 1-1 关联关系。
//若需要在当前数据表中添加主键则需要使用 @JoinColumn 来进行映射. 注意, 1-1 关联关系, 所以需要添加 unique=true
@JoinColumn(name="MGR_ID", unique=true)
@OneToOne(fetch=FetchType.LAZY)
public Manager getMgr()
return mgr;
public void setMgr(Manager mgr)
this.mgr = mgr;
Manager.java
package com.atguigu.jpa.helloworld;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Table(name="JPA_MANAGERS")
@Entity
public class Manager
private Integer id;
private String mgrName;
private Department dept;
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="MGR_NAME")
public String getMgrName()
return mgrName;
public void setMgrName(String mgrName)
this.mgrName = mgrName;
//对于不维护关联关系, 没有外键的一方, 使用 @OneToOne 来进行映射, 建议设置 mappedBy=true
@OneToOne(mappedBy="mgr")
public Department getDept()
return dept;
public void setDept(Department dept)
this.dept = dept;
Item.java
package com.atguigu.jpa.helloworld;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Table(name="JPA_ITEMS")
@Entity
public class Item
private Integer id;
private String itemName;
private Set<Category> categories = new HashSet<>();
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="ITEM_NAME")
public String getItemName()
return itemName;
public void setItemName(String itemName)
this.itemName = itemName;
//使用 @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
public Set<Category> getCategories()
return categories;
public void setCategories(Set<Category> categories)
this.categories = categories;
Category.java
package com.atguigu.jpa.helloworld;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Table(name="JPA_CATEGORIES")
@Entity
public class Category
private Integer id;
private String categoryName;
private Set<Item> items = new HashSet<>();
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
@Column(name="CATEGORY_NAME")
public String getCategoryName()
return categoryName;
public void setCategoryName(String categoryName)
this.categoryName = categoryName;
@ManyToMany(mappedBy="categories")
public Set<Item> getItems()
return items;
public void setItems(Set<Item> items)
this.items = items;
JPATest.java
//对于关联的集合对象, 默认使用懒加载的策略.
//使用维护关联关系的一方获取, 还是使用不维护关联关系的一方获取, SQL 语句相同.
@Test
public void testManyToManyFind()
// Item item = entityManager.find(Item.class, 5);
// System.out.println(item.getItemName());
//
// System.out.println(item.getCategories().size());
Category category = entityManager.find(Category.class, 3);
System.out.println(category.getCategoryName());
System.out.println(category.getItems().size());
//多对所的保存
@Test
public void testManyToManyPersist()
Item i1 = new Item();
i1.setItemName("i-1");
Item i2 = new Item();
i2.setItemName("i-2");
Category c1 = new Category();
c1.setCategoryName("C-1");
Category c2 = new Category();
c2.setCategoryName("C-2");
//设置关联关系
i1.getCategories().add(c1);
i1.getCategories().add(c2);
i2.getCategories().add(c1);
i2.getCategories().add(c2);
c1.getItems().add(i1);
c1.getItems().add(i2);
c2.getItems().add(i1);
c2.getItems().add(i2);
//执行保存
entityManager.persist(i1);
entityManager.persist(i2);
entityManager.persist(c1);
entityManager.persist(c2);
//1. 默认情况下, 若获取不维护关联关系的一方, 则也会通过左外连接获取其关联的对象.
//可以通过 @OneToOne 的 fetch 属性来修改加载策略. 但依然会再发送 SQL 语句来初始化其关联的对象
//这说明在不维护关联关系的一方, 不建议修改 fetch 属性.
@Test
public void testOneToOneFind2()
Manager mgr = entityManager.find(Manager.class, 1);
System.out.println(mgr.getMgrName());
System.out.println(mgr.getDept().getClass().getName());
//1.默认情况下, 若获取维护关联关系的一方, 则会通过左外连接获取其关联的对象.
//但可以通过 @OntToOne 的 fetch 属性来修改加载策略.
@Test
public void testOneToOneFind()
Department dept = entityManager.find(Department.class, 1);
System.out.println(dept.getDeptName());
System.out.println(dept.getMgr().getClass().getName());
//双向 1-1 的关联关系, 建议先保存不维护关联关系的一方, 即没有外键的一方, 这样不会多出 UPDATE 语句.
@Test
public void testOneToOnePersistence()
Manager mgr = new Manager();
mgr.setMgrName("M-BB");
Department dept = new Department();
dept.setDeptName("D-BB");
//设置关联关系
mgr.setDept(dept);
dept.setMgr(mgr);
//执行保存操作
entityManager.persist(mgr);
entityManager.persist(dept);
@Test
public void testUpdate()
Customer customer = entityManager.find(Customer.class, 10);
customer.getOrders().iterator().next().setOrderName("O-XXX-10");
//默认情况下, 若删除 1 的一端, 则会先把关联的 n 的一端的外键置空, 然后进行删除.
//可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略.
@Test
public void testOneToManyRemove()
Customer customer = entityManager.find(Customer.class, 8);
entityManager.remove(customer);
//默认对关联的多的一方使用懒加载的加载策略.
//可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略
@Test
public void testOneToManyFind()
Customer customer = entityManager.find(Customer.class, 9);
System.out.println(customer.getLastName());
System.out.println(customer.getOrders().size());
//若是双向 1-n 的关联关系, 执行保存时
//若先保存 n 的一端, 再保存 1 的一端, 默认情况下, 会多出 n 条 UPDATE 语句.
//若先保存 1 的一端, 则会多出 n 条 UPDATE 语句
//在进行双向 1-n 关联关系时, 建议使用 n 的一方来维护关联关系, 而 1 的一方不维护关联系, 这样会有效的减少 SQL 语句.
//注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了.
//单向 1-n 关联关系执行保存时, 一定会多出 UPDATE 语句.
//因为 n 的一端在插入时不会同时插入外键列.
@Test
public void testOneToManyPersist()
Customer customer = new Customer();
customer.setAge(18);
customer.setBirth(new Date());
customer.setCreatedTime(new Date());
customer.setEmail("mm@163.com");
customer.setLastName("MM");
Order order1 = new Order();
order1.setOrderName("O-MM-1");
Order order2 = new Order();
order2.setOrderName("O-MM-2");
//建立关联关系
customer.getOrders().add(order1);
customer.getOrders().add(order2);
order1.setCustomer(customer);
order2.setCustomer(customer);
//执行保存操作
entityManager.persist(customer);
entityManager.persist(order1);
entityManager.persist(order2);
@Test
public void testManyToOneUpdate()
Order order = entityManager.find(Order.class, 2);
order.getCustomer().setLastName("FFF");
//不能直接删除 1 的一端, 因为有外键约束.
@Test
public void testManyToOneRemove()
// Order order = entityManager.find(Order.class, 1);
// entityManager.remove(order);
Customer customer = entityManager.find(Customer.class, 7);
entityManager.remove(customer);
//默认情况下, 使用左外连接的方式来获取 n 的一端的对象和其关联的 1 的一端的对象.
//可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略
@Test
public void testManyToOneFind()
Order order = entityManager.find(Order.class, 1);
System.out.println(order.getOrderName());
System.out.println(order.getCustomer().getLastName());
/**
* 保存多对一时, 建议先保存 1 的一端, 后保存 n 的一端, 这样不会多出额外的 UPDATE 语句.
*/
@Test
public void testManyToOnePersist()
Customer customer = new Customer();
customer.setAge(18);
customer.setBirth(new Date());
customer.setCreatedTime(new Date());
customer.setEmail("gg@163.com");
customer.setLastName("GG");
Order order1 = new Order();
order1.setOrderName("G-GG-1");
Order order2 = new Order();
order2.setOrderName("G-GG-2");
//设置关联关系
order1.setCustomer(customer);
order2.setCustomer(customer);
//执行保存操作
entityManager.persist(order1);
entityManager.persist(order2);
entityManager.persist(customer);
以上是关于JPA学习笔记的主要内容,如果未能解决你的问题,请参考以下文章