HQL Hibernate INNER JOIN

sze*_*efu 27 java hibernate hql

如何在Hibernate中编写这个SQL查询?我想使用Hibernate创建查询,而不是创建数据库.

SELECT * FROM Employee e INNER JOIN Team t ON e.Id_team=t.Id_team
Run Code Online (Sandbox Code Playgroud)

我在SQLServer2008中创建了实体类,

@Entity
@Table(name="EMPLOYEE")
public class Employee
{
    @Id @GeneratedValue
    @Column(name="ID_EMPLOYEE")
    private int id_employee;
    @Column(name="SURNAME")
    private String surname;
    @Column(name="FIRSTNAME")
    private String firstname;
    @Column(name="ID_PROFESSION")
    private int id_profession;
    @Column(name="ID_BOSS")
    private int id_boss;
    @Column(name="HIRED_DATE")
    private Date hired;
    @Column(name="SALARY")
    private double salary;
    @Column(name="SALARY_ADD")
    private double salary_add;
    @Column(name="ID_TEAM")
    private int id_team;
    //setters and getters
}

@Entity
@Table(name="TEAM")
public class Team
{
    @Id @GeneratedValue
    @Column(name="ID_TEAM")
    private int id_team;
    @Column(name="TEAMNAME")
    private String teamname;
    @Column(name="ADDRESS")
    private String address;
    //setters and getters
}
Run Code Online (Sandbox Code Playgroud)

我试图以多种方式构建工作选择查询,但它仍然无效.

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();                 
session.beginTransaction();
String select = "FROM Employee e INNER JOIN Team t ON e.Id_team=t.Id_team";
Query query = session.createQuery(select);
List elist = query.list();
session.getTransaction().commit();
session.close();    
Run Code Online (Sandbox Code Playgroud)

实体可能有问题吗?

JB *_*zet 42

只有在实体之间存在关联时才能使用联接.您的Employee实体不应具有映射到列的名为id_teamtype int的字段.它应该与Team实体具有ManyToOne关联,映射为JoinColumn:

@ManyToOne
@JoinColumn(name="ID_TEAM")
private Team team;
Run Code Online (Sandbox Code Playgroud)

然后,以下查询将完美地工作:

select e from Employee e inner join e.team
Run Code Online (Sandbox Code Playgroud)

这将加载所有员工,除了那些与任何团队无关的员工.

对于所有其他字段也是如此,这些字段是作为实体映射的某个其他表的外键,当然(id_boss,id_profession).

现在是时候阅读Hibernate文档了,因为你错过了一个非常重要的部分,它是什么以及它是如何工作的.


Dee*_*pak 6

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="empTable")
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String empName;

List<Address> addList=new ArrayList<Address>();


@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="emp_id")
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getEmpName() {
    return empName;
}
public void setEmpName(String empName) {
    this.empName = empName;
}

@OneToMany(mappedBy="employee",cascade=CascadeType.ALL)
public List<Address> getAddList() {
    return addList;
}

public void setAddList(List<Address> addList) {
    this.addList = addList;
}
}
Run Code Online (Sandbox Code Playgroud)

我们有两个实体 Employee 和 Address 具有一对多的关系。

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="address")
public class Address implements Serializable{

private static final long serialVersionUID = 1L;

private int address_id;
private String address;
Employee employee;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getAddress_id() {
    return address_id;
}
public void setAddress_id(int address_id) {
    this.address_id = address_id;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}

@ManyToOne
@JoinColumn(name="emp_id")
public Employee getEmployee() {
    return employee;
}
public void setEmployee(Employee employee) {
    this.employee = employee;
}
}
Run Code Online (Sandbox Code Playgroud)

这样我们就可以实现两个表之间的内连接

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;

public class Main {

public static void main(String[] args) {
    saveEmployee();

    retrieveEmployee();

}

private static void saveEmployee() {
    Employee employee=new Employee();
    Employee employee1=new Employee();
    Employee employee2=new Employee();
    Employee employee3=new Employee();

    Address address=new Address();
    Address address1=new Address();
    Address address2=new Address();
    Address address3=new Address();

    address.setAddress("1485,Sector 42 b");
    address1.setAddress("1485,Sector 42 c");
    address2.setAddress("1485,Sector 42 d");
    address3.setAddress("1485,Sector 42 a");

    employee.setEmpName("Varun");
    employee1.setEmpName("Krishan");
    employee2.setEmpName("Aasif");
    employee3.setEmpName("Dut");

    address.setEmployee(employee);
    address1.setEmployee(employee1);
    address2.setEmployee(employee2);
    address3.setEmployee(employee3);

    employee.getAddList().add(address);
    employee1.getAddList().add(address1);
    employee2.getAddList().add(address2);
    employee3.getAddList().add(address3);

    Session session=HibernateUtil.getSessionFactory().openSession();

    session.beginTransaction();

    session.save(employee);
    session.save(employee1);
    session.save(employee2);
    session.save(employee3);
    session.getTransaction().commit();
    session.close();
}

private static void retrieveEmployee() {
    try{

    String sqlQuery="select e from Employee e inner join e.addList";

    Session session=HibernateUtil.getSessionFactory().openSession();

    Query query=session.createQuery(sqlQuery);

    List<Employee> list=query.list();

     list.stream().forEach((p)->{System.out.println(p.getEmpName());});     
    session.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我已经使用 Java 8 for 循环来打印名称。确保你有 jdk 1.8 和 tomcat 8。另外添加一些更多的记录以便更好地理解。

 public class HibernateUtil {
 private static SessionFactory sessionFactory ;
 static {
    Configuration configuration = new Configuration();

    configuration.addAnnotatedClass(Employee.class);
    configuration.addAnnotatedClass(Address.class);
                  configuration.setProperty("connection.driver_class","com.mysql.jdbc.Driver");
    configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");                                
    configuration.setProperty("hibernate.connection.username", "root");     
    configuration.setProperty("hibernate.connection.password", "root");
    configuration.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
    configuration.setProperty("hibernate.hbm2ddl.auto", "update");
    configuration.setProperty("hibernate.show_sql", "true");
    configuration.setProperty(" hibernate.connection.pool_size", "10");


   // configuration
    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
    sessionFactory = configuration.buildSessionFactory(builder.build());
 }
public static SessionFactory getSessionFactory() {
    return sessionFactory;
}
} 
Run Code Online (Sandbox Code Playgroud)


Val*_*ant 5

你无需创建真正的Hibernate映射就可以做到这一点.试试这个:

SELECT * FROM Employee e, Team t WHERE e.Id_team=t.Id_team
Run Code Online (Sandbox Code Playgroud)

  • 之所以选择downvote,是因为这是一个交叉联接,并且只需执行两个表的笛卡尔坐标即可产生一堆记录。 (4认同)
  • 如果我没记错的话,这将导致交叉联接,与内部联接相比,这将是非常耗费性能的,因为在实际应用程序中使用它不值得冒这个风险。 (3认同)
  • @Pant你错了。这工作正常,因为数据库执行隐式 INNER JOIN。由于记录必须与两个表中的 ID_TEAM 相匹配,因此不会执行笛卡尔运算。 (3认同)