Order(多)–>Customer(一)
Order里有一个Customer的成员
/** *@JoinColumn:来映射外键 *@ManyToOne:映射多对一的关系 */ @JoinColumn(name="customer_id") @ManyToOne(fetch=FetchType.LAZY)//使用懒加载 public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; }把EntityManagerFactory,EntityManager,EntityTransaction的创建和销毁分别放在@before和@after中执行
private String persistenceUnitName = "jpa-1"; private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName); private EntityManager manager = entityManagerFactory.createEntityManager(); private EntityTransaction transaction ; @Before public void before(){ //1.创建EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName); //2.创建EntityManager manager = entityManagerFactory.createEntityManager(); //3.开启事务管理 transaction = manager.getTransaction(); transaction.begin(); } @After public void after(){ transaction.commit(); //6. 关闭factory entityManagerFactory.close(); //7. 关闭manager manager.close(); }输出SQL语句:
Hibernate: insert into JPA_CUSTOMER (age, birth, createTime, email, last_name) values (?, ?, ?, ?, ?) Hibernate: insert into jpa_order (customer_id, o_name) values (?, ?) Hibernate: insert into jpa_order (customer_id, o_name) values (?, ?)此时MySQL数据库中会创建两张表:
jpa_customer mysql> select * from jpa_customer; +----+------+-------+---------------------+-----------+-----------+ | id | age | birth | createTime | email | last_name | +----+------+-------+---------------------+-----------+-----------+ | 1 | NULL | NULL | 2017-03-12 19:11:47 | GG@qq.cpm | GG | +----+------+-------+---------------------+-----------+-----------+ 1 row in set jpa_order mysql> select * from jpa_order; +----+--------+-------------+ | id | o_name | customer_id | +----+--------+-------------+ | 1 | O-AA | 1 | +----+--------+-------------+ | 2 | O-BB | 1 | +----+--------+-------------+ 1 row in set输出SQL语句:
Hibernate: select order0_.id as id1_6_0_, order0_.customer_id as customer3_6_0_, order0_.o_name as o_name2_6_0_ from jpa_order order0_ where order0_.id=? O-AA Hibernate: select customer0_.id as id1_0_0_, customer0_.age as age2_0_0_, customer0_.birth as birth3_0_0_, customer0_.createTime as createTi4_0_0_, customer0_.email as email5_0_0_, customer0_.last_name as last_nam6_0_0_ from JPA_CUSTOMER customer0_ where customer0_.id=? GG数据库:
mysql> select * from jpa_order; +----+--------+-------------+ | id | o_name | customer_id | +----+--------+-------------+ | 2 | O-BB | 1 | +----+--------+-------------+ 1 row in set输出:
Hibernate: select order0_.id as id1_6_0_, order0_.customer_id as customer3_6_0_, order0_.o_name as o_name2_6_0_ from jpa_order order0_ where order0_.id=? Hibernate: select customer0_.id as id1_0_0_, customer0_.age as age2_0_0_, customer0_.birth as birth3_0_0_, customer0_.createTime as createTi4_0_0_, customer0_.email as email5_0_0_, customer0_.last_name as last_nam6_0_0_ from JPA_CUSTOMER customer0_ where customer0_.id=? Hibernate: update JPA_CUSTOMER set age=?, birth=?, createTime=?, email=?, last_name=? where id=? mysql> select * from jpa_customer; +----+------+-------+---------------------+-----------+-----------+ | id | age | birth | createTime | email | last_name | +----+------+-------+---------------------+-----------+-----------+ | 1 | NULL | NULL | 2017-03-12 19:11:47 | GG@qq.cpm | GGG | +----+------+-------+---------------------+-----------+-----------+ 1 row in set为什么这两个能放在一块呢? 因为一对多和多对一在单向的时候是相对的例如表A和表B,当A作为1时,B为n时,在A的角度就是单向一对多(1–>n),反过来就是单向多对一(n–>1)
所以直接看双向多对一 此时Order作为多的多方(n),Customer作为一方(1) 还是以上面两个为表格为例子
多方:
//使用 @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; }一方:
// /** // *@JoinColumn:来映射外键 // *@ManyToOne:映射多对一的关系 // */ @JoinColumn(name="customer_id") @ManyToOne(fetch=FetchType.LAZY)//使用懒加载 public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; }输出SQL语句:
Hibernate: insert into JPA_CUSTOMER (age, birth, createTime, email, last_name) values (?, ?, ?, ?, ?) Hibernate: insert into jpa_order (customer_id, o_name) values (?, ?) Hibernate: insert into jpa_order (customer_id, o_name) values (?, ?)数据库:
mysql> select * from jpa_customer; +----+-----+-------+---------------------+-------------+-----------+ | id | age | birth | createTime | email | last_name | +----+-----+-------+---------------------+-------------+-----------+ | 1 | 25 | NULL | 2017-03-12 20:04:15 | GGG@123.com | GGG | +----+-----+-------+---------------------+-------------+-----------+ 1 row in set mysql> select * from jpa_order; +----+--------+-------------+ | id | o_name | customer_id | +----+--------+-------------+ | 1 | O-AA | 1 | | 2 | O-BB | 1 | +----+--------+-------------+ 2 rows in set输出: 因为是fetch=FetchType.LAZY设置的懒加载,所
Hibernate: select customer0_.id as id1_0_0_, customer0_.age as age2_0_0_, customer0_.birth as birth3_0_0_, customer0_.createTime as createTi4_0_0_, customer0_.email as email5_0_0_, customer0_.last_name as last_nam6_0_0_ from JPA_CUSTOMER customer0_ where customer0_.id=? GGG Hibernate: select orders0_.customer_id as customer3_0_1_, orders0_.id as id1_6_1_, orders0_.id as id1_6_0_, orders0_.customer_id as customer3_6_0_, orders0_.o_name as o_name2_6_0_ from jpa_order orders0_ where orders0_.customer_id=? Order [id=2, name=O-BB, customer=Customer [id=1, lastName=GGG, email=GGG@123.com, age=25, createTime=2017-03-12 20:04:15.0, birth=null]]输出SQL语句:
Hibernate: select customer0_.id as id1_0_0_, customer0_.age as age2_0_0_, customer0_.birth as birth3_0_0_, customer0_.createTime as createTi4_0_0_, customer0_.email as email5_0_0_, customer0_.last_name as last_nam6_0_0_ from JPA_CUSTOMER customer0_ where customer0_.id=? Hibernate: select orders0_.customer_id as customer3_0_1_, orders0_.id as id1_6_1_, orders0_.id as id1_6_0_, orders0_.customer_id as customer3_6_0_, orders0_.o_name as o_name2_6_0_ from jpa_order orders0_ where orders0_.customer_id=? Hibernate: update jpa_order set customer_id=?, o_name=? where id=?有两个表和对应的实体类Manager和Department一对一关系 关键点 在Manager.java中配置OneToOne,把关联关系交给Department的表
@OneToOne(mappedBy="manager") public Department getDepartment() { return department; }Department.java配置OnToOne
@JoinColumn(name="mgr_id",unique=true) @OneToOne(fetch=FetchType.LAZY) public Manager getManager() { return manager; }Manager.java
package com.bart.jpa.beans; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Table(name="jpa_mgr") @Entity public class Manager { @GeneratedValue(strategy=GenerationType.AUTO) @Id public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name="m_name",length=20) public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToOne(mappedBy="manager") public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } private int id; private String name; private Department department; public Manager(String name) { super(); this.name = name; } public Manager() { super(); } }Department.java
package com.bart.jpa.beans; 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.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Table(name="jpa_dept") @Entity public class Department { @GeneratedValue(strategy=GenerationType.AUTO) @Id public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name="d_name") public String getName() { return name; } public void setName(String name) { this.name = name; } @JoinColumn(name="mgr_id",unique=true) @OneToOne(fetch=FetchType.LAZY) public Manager getManager() { return manager; } public void setManager(Manager manager) { this.manager = manager; } private int id; private String name; private Manager manager; public Department(String name) { super(); this.name = name; } public Department() { super(); } }item和category,表现为多对多关系 配置多对多的时候注意的地方
多对多的时候,应该创建一个中间表来管理双方外键
Item.java,把关联关系交给Category来管理
@ManyToMany(mappedBy="items")//关联关系交给Category来维护 public Set<Category> getCategorys() { return categorys; } public void setCategorys(Set<Category> categorys) { this.categorys = categorys; }Category.java,管理关联关系
使用 @ManyToMany 注解来映射多对多关联关系 使用 @JoinTable 来映射中间表 1. name 指向中间表的名字 2. joinColumns 映射当前类所在的表在中间表中的外键 2.1 name 指定外键列的列名 2.2 referencedColumnName 指定外键列关联当前表的哪一列 3. inverseJoinColumns 映射关联的类所在中间表的外键
@JoinTable(name="category_item", joinColumns={@JoinColumn(name="c_id",referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="i_id",referencedColumnName="id")} ) //使用 @ManyToMany 注解来映射多对多关联关系 //使用 @JoinTable 来映射中间表 //1. name 指向中间表的名字 //2. joinColumns 映射当前类所在的表在中间表中的外键 //2.1 name 指定外键列的列名 //2.2 referencedColumnName 指定外键列关联当前表的哪一列 //3. inverseJoinColumns 映射关联的类所在中间表的外键 @JoinTable(name="category_item", joinColumns={@JoinColumn(name="c_id",referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="i_id",referencedColumnName="id")} ) @ManyToMany public Set<Item> getItems() { return items; } public void setItems(Set<Item> items) { this.items = items; }