Hibernate(30)Hibernate的Named Query是什么?

Hibernate的Named Query

Named Query(命名查询)是Hibernate提供的一种机制,允许开发者在实体类或映射文件中定义静态的SQL或HQL查询。命名查询的好处包括:

  • 代码复用:可以在多个地方使用相同的查询。
  • 预编译:命名查询在应用启动时被预编译,运行时性能更好。
  • 可维护性:查询逻辑分离,便于维护和管理。

定义Named Query

Named Query可以使用注解或XML配置来定义:

  1. 注解方式
    • 使用@NamedQuery@NamedQueries注解。
  2. XML配置方式
    • 在Hibernate的映射文件中使用<query>标签。

示例代码

使用注解定义Named Query

实体类 Person
java 复制代码
package com.example.domain;

import javax.persistence.*;

@Entity
@Table(name = "person")
@NamedQueries({
    @NamedQuery(
        name = "Person.findByName",
        query = "FROM Person WHERE name = :name"
    ),
    @NamedQuery(
        name = "Person.findAll",
        query = "FROM Person"
    )
})
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private int age;

    public Person() {}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters 和 Setters

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

使用XML配置定义Named Query

配置文件 Person.hbm.xml
xml 复制代码
<!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.example.domain.Person" table="person">
        <id name="id" column="id">
            <generator class="identity"/>
        </id>
        <property name="name" column="name"/>
        <property name="age" column="age"/>
    </class>

    <!-- Named Queries -->
    <query name="Person.findByName">
        <![CDATA[
            FROM Person WHERE name = :name
        ]]>
    </query>
    <query name="Person.findAll">
        <![CDATA[
            FROM Person
        ]]>
    </query>
</hibernate-mapping>

使用Named Query示例

HibernateUtil类
java 复制代码
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            // 从配置文件创建SessionFactory
            sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        } catch (Throwable ex) {
            // 记录启动失败的错误
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
查询示例
java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.query.Query;

import java.util.List;

public class HibernateNamedQueryExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 插入示例数据
        insertSampleData(sessionFactory);

        // 使用Named Query查询数据
        queryByName(sessionFactory, "John Doe");
        queryAll(sessionFactory);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void insertSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Person person1 = new Person("John Doe", 30);
            Person person2 = new Person("Jane Doe", 28);

            session.save(person1);
            session.save(person2);
            transaction.commit();
            System.out.println("Inserted sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    private static void queryByName(SessionFactory sessionFactory, String name) {
        Session session = sessionFactory.openSession();
        try {
            Query<Person> query = session.createNamedQuery("Person.findByName", Person.class);
            query.setParameter("name", name);
            List<Person> persons = query.getResultList();
            System.out.println("Query by name (" + name + "):");
            for (Person person : persons) {
                System.out.println(person.getName() + " - " + person.getAge());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    private static void queryAll(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        try {
            Query<Person> query = session.createNamedQuery("Person.findAll", Person.class);
            List<Person> persons = query.getResultList();
            System.out.println("Query all persons:");
            for (Person person : persons) {
                System.out.println(person.getName() + " - " + person.getAge());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

Named Query详细解释

  1. 注解方式定义Named Query :在Person实体类上使用@NamedQuery@NamedQueries注解定义查询。

    java 复制代码
    @NamedQueries({
        @NamedQuery(
            name = "Person.findByName",
            query = "FROM Person WHERE name = :name"
        ),
        @NamedQuery(
            name = "Person.findAll",
            query = "FROM Person"
        )
    })
  2. XML配置方式定义Named Query :在Person.hbm.xml中使用<query>标签定义查询。

    xml 复制代码
    <query name="Person.findByName">
        <![CDATA[
            FROM Person WHERE name = :name
        ]]>
    </query>
    <query name="Person.findAll">
        <![CDATA[
            FROM Person
        ]]>
    </query>
  3. HibernateUtil类:创建并管理SessionFactory。

    java 复制代码
    public class HibernateUtil {
        private static final SessionFactory sessionFactory;
    
        static {
            try {
                // 从配置文件创建SessionFactory
                sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
            } catch (Throwable ex) {
                // 记录启动失败的错误
                System.err.println("Initial SessionFactory creation failed." + ex);
                throw new ExceptionInInitializerError(ex);
            }
        }
    
        public static SessionFactory getSessionFactory() {
            return sessionFactory;
        }
    }
  4. 使用Named Query示例:演示如何使用Named Query进行查询。

    java 复制代码
    public class HibernateNamedQueryExample {
        public static void main(String[] args) {
            // 获取SessionFactory
            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    
            // 插入示例数据
            insertSampleData(sessionFactory);
    
            // 使用Named Query查询数据
            queryByName(sessionFactory, "John Doe");
            queryAll(sessionFactory);
    
            // 关闭SessionFactory
            sessionFactory.close();
        }
    
        private static void insertSampleData(SessionFactory sessionFactory) {
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            try {
                Person person1 = new Person("John Doe", 30);
                Person person2 = new Person("Jane Doe", 28);
    
                session.save(person1);
                session.save(person2);
                transaction.commit();
                System.out.println("Inserted sample data");
            } catch (Exception e) {
                if (transaction != null) {
                    transaction.rollback();
                }
                e.printStackTrace();
            } finally {
                if (session != null) {
                    session.close();
                }
            }
        }
    
        private static void queryByName(SessionFactory sessionFactory, String name) {
            Session session = sessionFactory.openSession();
            try {
                Query<Person> query = session.createNamedQuery("Person.findByName", Person.class);
                query.setParameter("name", name);
                List<Person> persons = query.getResultList();
                System.out.println("Query by name (" + name + "):");
                for (Person person : persons) {
                    System.out.println(person.getName() + " - " + person.getAge());
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (session != null) {
                    session.close();
                }
            }
        }
相关推荐
Victor35620 小时前
Hibernate(29)什么是Hibernate的连接池?
后端
源代码•宸20 小时前
GoLang八股(Go语言基础)
开发语言·后端·golang·map·defer·recover·panic
czlczl2002092520 小时前
OAuth 2.0 解析:后端开发者视角的原理与流程讲解
java·spring boot·后端
颜淡慕潇20 小时前
Spring Boot 3.3.x、3.4.x、3.5.x 深度对比与演进分析
java·后端·架构
布列瑟农的星空20 小时前
WebAssembly入门(一)——Emscripten
前端·后端
小突突突1 天前
Spring框架中的单例bean是线程安全的吗?
java·后端·spring
iso少年1 天前
Go 语言并发编程核心与用法
开发语言·后端·golang
掘金码甲哥1 天前
云原生算力平台的架构解读
后端
码事漫谈1 天前
智谱AI从清华实验室到“全球大模型第一股”的六年征程
后端