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语句,加深印象。

时间: 2024-10-26 13:17:15

Hibernate 注解 (Annotations 三)多对一双向注解的相关文章

Hibernate 注解(Annotations 四)多对多双向注解

注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释. 接下来讲解多对多双向注解: 我以用户和房子作为示例讲解. 第一步:准备实体类 House(房间表) package cn.manytomany.entity; import javax.persistence.*; import java.util.HashSet; im

跟王老师学注解(三):元注解

跟王老师学注解(三):元注解 主讲教师:王少华   QQ群号:483773664 元注解,是用来修饰其他的注解定义.java.lang.annotation包下提供了4个元注解,分别是@Target注解.@Retention注解.@Documented注解以及@Inherited注解. 一.@Target (一)简介 用于指定被修饰的注解能用于修饰哪些程序元素 @Target注解类型有唯一的value作为成员变量,value的类型为java.lang.annotation.ElementType

hibernate的映射之四(多对多双向关联)

Many-to-Many 多对多的映射可以使用一组Java集合不包含任何重复的元素来实现.我们已经看到了Hibernate如何设置映射集合. 集(SET)被映射到与映射表中<set>元素,并以java.util.HashSet初始化.您可以使用Set集合在类中时,集合不需要重复的元素. 多对多双向关联: 由于是双向关联,所以需要在二个实体中植入对方的实体集合. 我依旧以员工和项目为例子. 1.准备JavaBean(持久化类) 员工实体类 public class Employee { priv

hibernate之实体@onetomany和@manytoone双向注解(转)

下面是User类: @onetomany @Entity @Table(name="user") public class User implements Serializable{ private static final long serialVersionUID = 6177417450707400228L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="id") priva

Hibernate之关于多对多双向关联映射

[Hibernate]之关于多对多双向关联映射 多对多的双向关联映射在项目实战中还是相当重要的,所以这里着重写一下!以学生表(Student)和老师表(Teacher)为例. 首先我们还是先看Annotations配置! @Entity @Table(name="t_student") public class Student {     private Integer id;     private String name;     private Integer age;     

Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)

One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XML/Annotation) 懒加载和积极加载 一对多双向外键关联(XML/Annotation) Many to Many 映射关系 多对多单向外键关联(XML/Annotation) 多对多双向外键关联(XML/Annotation) set的inverse元素详解 问题小结 关联关系的优缺点 多对一单向外键关联关系 注意多对一关联是多方持有一方的引用.看一个例子,去淘宝购物,那么一个

hibernate one-to-many many-to-one 双向注解

建表语句: DROP TABLE IF EXISTS `t_company`; CREATE TABLE `t_company` ( `companyId` int(10) unsigned NOT NULL AUTO_INCREMENT, `companyName` varchar(30) NOT NULL, PRIMARY KEY (`companyId`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=gb2312; INSERT INT

idea中注解配置一对多,多对一,双向多对一映射(不详细)

一对多 package cn.pojo; import javax.persistence.*; import java.io.Serializable; import java.util.Set; @Entity //声明这是一个实体类 必写 public class District implements Serializable { private static final long serialVersionUID = 8009273978191878070L; //编号 @Id //标

hibernate中多对多的注解配置

hibernate多对多的注解配置中的自动生成中间表的配置: @Entity@Table(name="test_student")public class Students { @Id @SequenceGenerator(name="seqStudents",sequenceName="seq_test_student") @GeneratedValue(generator="seqStudents") private In