Hibernate命名查詢


hibernate命名的查詢是通過一些有意義的名稱來使用查詢的方式。就類似於使用別名一樣。 Hibernate框架提供命名查詢的概念,以便應用程式員不需要將查詢分散到所有的java程式碼,進一步提高程式碼的可維護性。

在hibernate中定義命名查詢有兩種方法:

  • 通過註釋
  • 通過對映檔案

Hibernate通過註釋命名查詢

如果要在hibernate中使用命名查詢,則需要了解@NamedQueries@NamedQuery注釋。

我們來看看使用命名查詢的例子:

@NamedQueries(  
    {  
        @NamedQuery(  
        name = "findEmployeeByName",  
        query = "from Employee e where e.name = :name"  
        )  
    }  
)

Hibernate通過註釋命名查詢的範例

我們首先建立一個 Java 專案:namedquery , 其完整的專案結構如下圖所示 -

在這個例子中,我們使用註解來定義持久化類中的命名查詢。只有三個檔案:

  1. Employee.java
  2. hibernate.cfg.xml
  3. MainTest.java

在這個例子中,我們假設資料庫中有一個em表,其中包含4列:idnamejobsalary,並且這個表中有一些記錄。

檔案:Employee.java

它是一個使用注釋定義命名查詢並將此類標記為實體的持久化類。

package com.yiibai;

import javax.persistence.*;  
import javax.persistence.Entity;  
import javax.persistence.GeneratedValue;  
import javax.persistence.Id;  

@NamedQueries(  
    {  
        @NamedQuery(  
        name = "findEmployeeByName",  
        query = "from Employee e where e.name = :name"  
        )  
    }  
)  

@Entity  
@Table(name="em")  
public class Employee {  
    int id;
    String name;
    int salary;
    String job;
    @Id  
    @GeneratedValue(strategy=GenerationType.AUTO)  

    public String toString() {
        return id + " " + name + " " + salary + " " + job;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalary() {
        return salary;
    }

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

    public String getJob() {
        return job;
    }

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

}

檔案:hibernate.cfg.xml

它是一個組態檔案,用於儲存有關資料庫的資訊,如驅動程式類,URL,使用者名,密碼和對映類等。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

    <session-factory>
        <property name="hbm2ddl.auto">update</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">true</property>
        <mapping class="com.yiibai.Employee" />
    </session-factory>

</hibernate-configuration>

檔案:MainTest.java

它是一個使用命名查詢的java類,並根據查詢列印資訊。getNamedQuery方法使用命名查詢並返回Query的範例。

package com.yiibai;

import java.util.Iterator;
import java.util.List;

import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import org.hibernate.*;

public class MainTest {
    public static void main(String[] args) {

        // 在5.1.0版本匯總,hibernate則採用如下新方式獲取:
        // 1. 組態型別安全的準服務註冊類,這是當前應用的單例物件,不作修改,所以宣告為final
        // 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定資源路徑,預設在類路徑下尋找名為hibernate.cfg.xml的檔案
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();
        // 2. 根據服務註冊類建立一個後設資料資源集,同時構建後設資料並生成應用一般唯一的的session工廠
        SessionFactory sessionFactory = new MetadataSources(registry)
                .buildMetadata().buildSessionFactory();

        /**** 上面是組態準備,下面開始我們的資料庫操作 ******/
        Session session = sessionFactory.openSession();// 從對談工廠獲取一個session
        // creating transaction object
        Transaction t = session.beginTransaction();

        // 裝點範例資料
        Employee e1 = new Employee();
        e1.setName("Maxsu");
        e1.setJob("Java開發工程師");
        e1.setSalary(8900);
        session.save(e1);

        Employee e2 = new Employee();
        e2.setName("Minalee");
        e2.setJob("Python開發工程師");
        e2.setSalary(9500);
        session.save(e2);
        t.commit();

        // Hibernate Named Query
        Query query = session.getNamedQuery("findEmployeeByName");
        query.setString("name", "Maxsu");

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

        Iterator<Employee> itr = employees.iterator();
        while (itr.hasNext()) {
            Employee e = itr.next();
            System.out.println(e);
        }

        session.close();

    }
}

方法2. Hibernate通過XML對映檔案命名查詢

如果要通過對映檔案定義命名查詢,則需要使用hibernate-mappingquery 元素來定義命名查詢。

在這種情況下,需要建立定義命名查詢的hbm檔案。 其他資源與上述範例中相同,除了持久化類Employee.java,您不需要使用任何注釋和hibernate.cfg.xml檔案,需要指定hbm檔案中的對映資源。

emp.hbm.xml檔案應該是這樣的:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.yiibai.Employee" table="em">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>
        <property name="job"></property>
        <property name="salary"></property>
    </class>

    <query name="findEmployeeByName">
<![CDATA[from Employee e where e.name = :name]]>
    </query>

</hibernate-mapping>

持久化的類應該如下所示,檔案:Employee.java -

package com.yiibai;

public class Employee {
    int id;
    String name;
    int salary;
    String job;

    public String toString() {
        return id + " " + name + " " + salary + " " + job;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalary() {
        return salary;
    }

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

    public String getJob() {
        return job;
    }

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

}

在hbm檔案中包含對映資源。檔案:hibernate.cfg.xml 如下所示 -

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

    <session-factory>
        <property name="hbm2ddl.auto">update</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">true</property>
        <mapping resource="emp.hbm.xml" />
    </session-factory>

</hibernate-configuration>

執行範例

現在執行 MainTest.java 檔案,它首先建立表結構,並向表中插入資料,然後使用命名查詢資料。得到結果如下所示-

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Tue Mar 28 23:08:07 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Hibernate: create table em (id integer not null auto_increment, name varchar(255), job varchar(255), salary integer, primary key (id)) engine=InnoDB
Hibernate: insert into em (name, job, salary) values (?, ?, ?)
Hibernate: insert into em (name, job, salary) values (?, ?, ?)
Hibernate: select employee0_.id as id1_0_, employee0_.name as name2_0_, employee0_.job as job3_0_, employee0_.salary as salary4_0_ from em employee0_ where employee0_.name=?
1 Maxsu 8900 Java開發工程師