Hibernate命名查詢

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

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

  • 通過註釋
  • 通過映射文件

Hibernate通過註釋命名查詢

如果要在hibernate中使用命名查詢,則需要了解[@NamedQueries](https://github.com/NamedQueries "@NamedQueries")[@NamedQuery](https://github.com/NamedQuery "@NamedQuery")註釋。

  • [@NameQueries](https://github.com/NameQueries "@NameQueries")註釋用於定義多個命名查詢。
  • [@NameQuery](https://github.com/NameQuery "@NameQuery")註釋用於定義單個命名查詢。

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

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

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

我們首先創建一個 Java 項目:namedquery , 其完整的項目結構如下圖所示 -
Hibernate命名查詢

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

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