Hibernate 注解 (Annotations 三)多对一双向注解
Posted 刘二雄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 注解 (Annotations 三)多对一双向注解相关的知识,希望对你有一定的参考价值。
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
接下来我们讲解一下多对一双向注解:
我以部门表和员工表作为示例讲解。
第一步:创建实体类
Dept(部门表)
package cn.onetomanydouble.entity; import org.hibernate.annotations.*; import org.hibernate.annotations.Cache; import javax.persistence.*; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Table; import java.io.Serializable; import java.util.HashSet; import java.util.Set; /** * Created by accp on 2017/2/8. */ @Entity @Table(name = "DEPT1") public class Dept implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ") @SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ",initialValue = 1,allocationSize = 10) /* 对于oracle想使用各自的Sequence,设置如下: @GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ") @SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ") 另外: 对于自动增长后,在数据表中的相应字段,要设置字段为auto_increment. */ private Integer deptno; @Column private String deptname; @OneToMany(mappedBy ="dept",cascade = {CascadeType.ALL},fetch = FetchType.LAZY) //mappedBy 属性主要针对外键而言,与之对应的是.xml中的inverse属性 //mappedBy="dept" 是把维护权交给多的一方 @LazyCollection(LazyCollectionOption.FALSE) private Set<Emp> emps=new HashSet<Emp>(); @Column private String location; public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } public String getDeptname() { return deptname; } public void setDeptname(String deptname) { this.deptname = deptname; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } }
Emp(员工表)
package cn.onetomanydouble.entity; import org.hibernate.annotations.*; import org.hibernate.annotations.Cache; import javax.persistence.*; import javax.persistence.Entity; import javax.persistence.Table; import java.io.Serializable; /** * Created by accp on 2017/2/8. */ @Entity @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @Table(name = "EMP1") public class Emp implements Serializable { @Id @GeneratedValue private Integer empno; @Column private String ename; @ManyToOne @JoinColumn(name = "deptno") private Dept dept; /* @Column private Double salary; @Column private String job;*/ /*public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public String getJob() { return job; } public void setJob(String job) { this.job = job; }*/ public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
在配置一对多双向的时候一定要搞清楚主外键关系。
第二步:在hibernate.cfg.xml文件中配置<mapping>节点
<mapping class="cn.onetomanydouble.entity.Dept"/> <mapping class="cn.onetomanydouble.entity.Emp"/>
第三步:书写测试类
package cn.onetomanydouble.test; import cn.onetomanydouble.entity.Dept; import cn.onetomanydouble.entity.Emp; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * Created by accp on 2017/2/8. */ public class ManyToOneTest { Configuration cfg; Session session; Transaction tx; SessionFactory factory; @Before public void mybefore(){ cfg=new Configuration().configure(); factory=cfg.buildSessionFactory(); session=factory.openSession(); tx=session.beginTransaction(); } @After public void myafter(){ tx.commit(); session.close(); } @Test public void demo(){ System.out.println(123); } @Test public void select(){ /** * load()方法 * fetch = FetchType.EAGER(立即加载) fetch = FetchType.LAZY(懒加载) * 情况一:当在一的一方设置是否加载时 * fetch = FetchType.EAGER (立即加载) * 不查询不发送sql语句 * 左外连接 两表查询 * 查询关联表的属性时 不在重新发送sql * * * fetch = FetchType.LAZY(懒加载) * 不查询不发送sql语句 * 查询单一属性时 只查询当前表的 当查询关联属性时 * 重新向数据库发送sql * * get()方法 * fetch = FetchType.EAGER (立即加载) fetch = FetchType.LAZY(懒加载) * (1) 情况一:当在多的一方设置 * fetch = FetchType.EAGER (立即加载) * 先向数据库查询一次 * 左外连接 两表查询 * 当用到属性时 直接打印对应的属性值 * * fetch = FetchType.LAZY(懒加载) * 只加载当前类的语句 * 当查询当前表的属性时 只向数据库发送查询当前表的sql * * 当查询关联表的属性时 发送关联表的sql语句 * */ /*Transaction tx = factory.getCurrentSession().beginTransaction(); Dept dept = factory.getCurrentSession().get(Dept.class, 1); for (Emp emp:dept.getEmps()) { System.out.println(emp.getEname()); } tx.commit(); factory.getCurrentSession().close(); System.out.println("====================="); Transaction tx2 = factory.getCurrentSession().beginTransaction(); Dept dept2 = factory.getCurrentSession().get(Dept.class, 1); for (Emp emp:dept2.getEmps()) { System.out.println(emp.getEname()); } tx2.commit(); */ Dept dept = session.get(Dept.class, 1); System.out.println("============="); System.out.println(dept.getClass()); System.out.println(dept.getDeptname()); System.out.println(dept.getEmps().iterator().next().getEname()); /* Emp emp = session.get(Emp.class, 2); System.out.println("===========");*/ /* System.out.println(emp.getEname()); System.out.println(emp.getDept().getDeptname());*/ } @Test public void add(){ /*//创建部门 Dept dept=new Dept(); dept.setDeptname("产品部"); //创建员工 Emp emp=new Emp(); emp.setEname("刘二雄"); emp.setDept(dept); dept.getEmps().add(emp); //因为cascade级联只需保存部门即可保存员工 session.save(dept);*/ Dept dept=new Dept(); dept.setDeptname("清洁部"); //创建员工 Emp emp=new Emp(); emp.setEname("飘哥"); emp.setDept(dept); dept.getEmps().add(emp); session.save(dept); } }
执行完代码后一定要看看生成的sql语句,加深印象。
以上是关于Hibernate 注解 (Annotations 三)多对一双向注解的主要内容,如果未能解决你的问题,请参考以下文章