hibernate09--连接查询

Posted 丿少女梦丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate09--连接查询相关的知识,希望对你有一定的参考价值。

创建实体类

复制代码
package cn.bdqn.bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 小豆腐
 *
 *员工的实体类
 */
public class Emp {

    private Integer empNo; 
    private String empName;
    private String job;
    private Double salary;
    private Date hireDate;
    
    //多个员工属于一个部门
    private  Dept dept;

    public Integer getEmpNo() {
        return empNo;
    }

    public void setEmpNo(Integer empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Emp(Integer empNo, String empName, String job, Double salary,
            Date hireDate, Dept dept) {
        super();
        this.empNo = empNo;
        this.empName = empName;
        this.job = job;
        this.salary = salary;
        this.hireDate = hireDate;
        this.dept = dept;
    }

    public Emp() {
        super();
    }

    @Override
    public String toString() {
        return "Emp [empNo=" + empNo + ", empName=" + empName + ", job=" + job
                + ", salary=" + salary + ", hireDate=" + hireDate + ", dept="
                + dept + "]";
    }
}
复制代码

 

复制代码
package cn.bdqn.bean;

import java.util.HashSet;
import java.util.Set;

import com.sun.org.apache.bcel.internal.generic.NEW;

/**
 * 
 *  部门的实体类
 */
public class Dept {
    
    private  Integer  deptNo;
    private  String  deptName;
    private  String  location;  
    //一个部门对应多个员工
    private  Set<Emp> emps=new HashSet<>();
    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 String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    public Set<Emp> getEmps() {
        return emps;
    }
    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }
    public Dept(Integer deptNo, String deptName, String location, Set<Emp> emps) {
        super();
        this.deptNo = deptNo;
        this.deptName = deptName;
        this.location = location;
        this.emps = emps;
    }
    public Dept() {
        super();
    }
    @Override
    public String toString() {
        return "Dept [deptNo=" + deptNo + ", deptName=" + deptName
                + ", location=" + location + ", emps=" + emps.size() + "]";
    }
    
    
    
    
}
复制代码

 

创建对应的数据库表

 

创建对应的映射文件

复制代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.bdqn.bean">
    <class name="Dept">
       <id name="deptNo"> 
          <generator class="assigned"/><!-- 手动给主键赋值 -->
       </id>  
       <property name="deptName" column="dName"/>
       <property name="location" column="loc"/>
       <!-- 设置一对多  
       name:本类中的关联属性名  集合的名称
       column: 就是数据库表中的外键
       order-by="id desc" 按照 街道的id 进行 降序排列
       inverse:是由谁来维护表与表之间的关系! 默认是false!(维护)    true(不维护)
       -->
       <set name="emps" cascade="all" inverse="true">
        <key column="DEPTNO"/>
         <one-to-many class="Emp"/>
       </set>
  </class>
</hibernate-mapping>
复制代码

 

复制代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.bdqn.bean">
  <class name="Emp">
       <id name="empNo"> 
          <generator class="assigned"/><!-- 手动给主键赋值 -->
       </id>  
       <property name="empName"/>
       <property name="job"/>
       <property name="salary"/>
       <property name="hireDate"/>
       <!-- 配置多对一关联
       name:对应的是  本类中 关联关系的属性名
       column:对应数据库中 两个表的  外键!
       class:关联的实体类
       -->
       <many-to-one  name="dept" column="DEPTNO" class="Dept"/> 
  </class>
</hibernate-mapping>
复制代码

 

在hibernate.cfg.xml文件中 管理两个映射文件之后,创建测试类代码

复制代码
public class EmpTest {
    Session session =null;
    Transaction transaction=null;
    
    @Before
    public  void  before(){
         session = HibernateSessionUtil.getCurrentSession();
         transaction= session.beginTransaction();
    }
    
    /**
     * 先给两个表中 增加测试数据
     */
    @Test
    public  void  testAdd(){
        /**
         * 因为我们设置了级联操作 cascade=all
         * 那么我们就可以在保存部门信息的时候保存员工
         */
        Dept dept=new Dept();
        dept.setDeptNo(2);
        dept.setDeptName("市场部");
        dept.setLocation("2楼");
        //创建员工
        Emp emp1=new Emp(5, "员工5", "程序猿5", 5000.0,dept);
        Emp emp2=new Emp(6, "员工6", "程序猿6", 545000.0,dept);
        Emp emp3=new Emp(7, "员工7", "程序猿7", 2000.0,dept);
        Emp emp4=new Emp(8, "员工8", "程序猿8", 98000.0,dept);
        Set<Emp> emps=new HashSet<>();
        emps.add(emp1);
        emps.add(emp2);
        emps.add(emp3);
        emps.add(emp4);
        dept.setEmps(emps);  //把所有的员工放入了集合中
        session.save(dept);
        transaction.commit();
    }
    
    
    /**
     *  所有的迫切连接返回的都是一个对象!     有fetch===》迫切连接
     *  所有的非迫切连接返回的都是一个数组!
     *  
     *  
     *  01.使用内连接查询  两个表的所有数据
     *  sql语句
     *  select * from emp inner join dept 
          on dept.deptno=emp.deptno
        
        hql语句
        from Emp e inner join e.dept(Emp类中的关联属性名)
     */
    @Test
    public  void  test01(){
        String hql="from Emp e inner join e.dept";
         List<Object[]> list = session.createQuery(hql).list();
         for (Object[] objects : list) {
            System.out.println(objects[0]);  //Emp对象
            System.out.println(objects[1]); //Dept对象
        }
    }
    
    /**
     * 02.迫切内连接   返回的就是一个对象
     */
    @Test
    public  void  test02(){
        String hql="from Emp e inner join fetch e.dept";
         List<Emp> list = session.createQuery(hql).list();
         for (Emp emp : list) {
            System.out.println(emp);  //Emp对象
        }
    }
    /**
     * 03.隐式内连接   返回的就是一个对象
     * e.dept.deptNo  通过这个属性 进行关联连接
     */
    @Test
    public  void  test03(){
        String hql="from Emp e  where e.dept.deptNo=:dNo";
        List<Emp> list = session.createQuery(hql).setParameter("dNo", 2).list();
        for (Emp emp : list) {
            System.out.println(emp);  //Emp对象
        }
    }
    /**
     * 04.隐式内连接 投影 查询        查询部门编号为2的所有员工的姓名和薪水
     * e.dept.deptNo  通过这个属性 进行关联连接
     */
    @Test
    public  void  test04(){
        String hql="select empName,salary from Emp e where e.dept.deptNo=:dNo ";
        List<Object[]> list = session.createQuery(hql).setParameter("dNo", 2).list();
        for (Object[] objects : list) {
            System.out.print(objects[0]+"\\t");  //姓名
            System.out.println(objects[1]);  //薪水
        }
    }
    /**
     * 05.使用左外连接   查询员工和部门的信息
     *  以左表为准,右表中没有对应的数据,返回null!
     */
    @Test
    public  void  test05(){
        String  hql="from  Emp e left join e.dept";
        List <Object[]>list = session.createQuery(hql).list();
        for (Object[] objects : list) {
            System.out.print(objects[0]+"\\t"); //Emp对象
            System.out.println(objects[1]); //Dept对象
        }
    }
    /**
     * 06.使用迫切左外连接   查询员工和部门的信息
     *  以左表为准,右表中没有对应的数据,对象的属性null!
     *  Emp类中的dept属性为null!
     */
    @Test
    public  void  test06(){
        String  hql="from  Emp e left join fetch e.dept";
        List <Emp>list = session.createQuery(hql).list();
        for (Emp emp : list) {
            System.out.println(emp); //Emp对象
        }
    }
    /**
     * 07.使用右外连接   查询员工和部门的信息
     *  以右表为准,左表中没有对应的数据,返回null!
     */
    @Test
    public  void  test07(){
        String  hql="from  Emp e right join e.dept";
        List <Object[]>list = session.createQuery(hql).list();
        for (Object[] objects : list) {
            System.out.print(objects[0]+"\\t"); //Emp对象
            System.out.println(objects[1]); //Dept对象
            System.out.println("***********************************");
        }
    }
    /**
     * 08.使用迫切右外连接   查询员工和部门的信息
     *  对象就是null!   虽然可以写  迫切右外连接  但是没有实际的意义!
     *  @Test
      public  void  test08(){
        String  hql="from  Emp e right join fetch e.dept";
        List <Emp>list = session.createQuery(hql).list();
        for (Emp emp : list) {
            System.out.println(emp.getEmpName()); //Emp对象   空指针异常
        }
    }
     */
    
    
    
}

以上是关于hibernate09--连接查询的主要内容,如果未能解决你的问题,请参考以下文章

具有运行时 pojos 的带有 Hibernate 的 OSGi 片段包

Hibernate - OneToMany 注释导致选择查询的左连接不匹配

11hibernate查询连接池二级缓存

Hibernate查询连接池逆向工程

Hibernate 生成的查询 - 不存在的表

hibernate 查询二级缓存连接池