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.zaixian;

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.zaixian.Employee" />
    </session-factory>

</hibernate-configuration>

檔:MainTest.java

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

package com.zaixian;

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.zaixian.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.zaixian;

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開發工程師


上一篇: Hibernate標準查詢語言 下一篇: Hibernate緩存