JPA学习笔记(二)

来源:互联网 发布:去日本带mac好吗 编辑:程序博客网 时间:2024/05/17 06:20

映射关联关系

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")@Entitypublic class Order {private Integer id;private String orderName;private Customer customer;@GeneratedValue@Idpublic 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")@Entitypublic 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)@Idpublic 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;}//工具方法. 不需要映射为数据表的一列. @Transientpublic String getInfo(){return "lastName: " + lastName + ", email: " + email;}@Overridepublic 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")@Entitypublic class Department {private Integer id;private String deptName;private Manager mgr;@GeneratedValue@Idpublic 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")@Entitypublic class Manager {private Integer id;private String mgrName;private Department dept;@GeneratedValue@Idpublic 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")@Entitypublic class Item {private Integer id;private String itemName;private Set<Category> categories = new HashSet<>();@GeneratedValue@Idpublic 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")})@ManyToManypublic 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")@Entitypublic class Category {private Integer id;private String categoryName;private Set<Item> items = new HashSet<>();@GeneratedValue@Idpublic 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 语句相同. @Testpublic 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());}//多对所的保存@Testpublic 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 属性. @Testpublic void testOneToOneFind2(){Manager mgr = entityManager.find(Manager.class, 1);System.out.println(mgr.getMgrName());System.out.println(mgr.getDept().getClass().getName());}//1.默认情况下, 若获取维护关联关系的一方, 则会通过左外连接获取其关联的对象. //但可以通过 @OntToOne 的 fetch 属性来修改加载策略.@Testpublic void testOneToOneFind(){Department dept = entityManager.find(Department.class, 1);System.out.println(dept.getDeptName());System.out.println(dept.getMgr().getClass().getName());}//双向 1-1 的关联关系, 建议先保存不维护关联关系的一方, 即没有外键的一方, 这样不会多出 UPDATE 语句.@Testpublic 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);}@Testpublic void testUpdate(){Customer customer = entityManager.find(Customer.class, 10);customer.getOrders().iterator().next().setOrderName("O-XXX-10");}//默认情况下, 若删除 1 的一端, 则会先把关联的 n 的一端的外键置空, 然后进行删除. //可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略. @Testpublic void testOneToManyRemove(){Customer customer = entityManager.find(Customer.class, 8);entityManager.remove(customer);}//默认对关联的多的一方使用懒加载的加载策略. //可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略@Testpublic 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 的一端在插入时不会同时插入外键列. @Testpublic 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);}@Testpublic void testManyToOneUpdate(){Order order = entityManager.find(Order.class, 2);order.getCustomer().setLastName("FFF");}//不能直接删除 1 的一端, 因为有外键约束. @Testpublic 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 属性来修改默认的关联属性的加载策略@Testpublic void testManyToOneFind(){Order order = entityManager.find(Order.class, 1);System.out.println(order.getOrderName());System.out.println(order.getCustomer().getLastName());}/** * 保存多对一时, 建议先保存 1 的一端, 后保存 n 的一端, 这样不会多出额外的 UPDATE 语句. */@Testpublic 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);}


0 0
原创粉丝点击