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();
                }
            }
        }
相关推荐
短剑重铸之日17 分钟前
《SpringCloud实用版》SpringCloud Alibaba和SpringCloud的区别
后端·spring·spring cloud·sca
码农水水1 小时前
SpringBoot配置优化:Tomcat+数据库+缓存+日志全场景教程
java·数据库·spring boot·后端·算法·tomcat·哈希算法
Liuqz20091 小时前
Go 安装与配置
开发语言·后端·golang
csdn_aspnet2 小时前
如何在 ASP.NET Core Identity 中实现用户身份验证
后端·asp.net·.net core·identity
康小庄2 小时前
SpringBoot 拦截器 (Interceptor) 与切面 (AOP):示例、作用、及适用场景
java·数据库·spring boot·后端·mysql·spring·spring cloud
中科院提名者2 小时前
如何配置go环境并用vscode运行
开发语言·后端·golang
huahailing10242 小时前
Spring Boot 3.x + JDK17 参数校验全场景实战(含List列表_嵌套_分组)
spring boot·后端
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 基于spring boot的摩托车合格证管理系统为例,包含答辩的问题和答案
java·spring boot·后端
毕设源码-赖学姐3 小时前
【开题答辩全过程】以 基于spring boot的国学诗词网站设计与实现--为例,包含答辩的问题和答案
java·spring boot·后端
千寻技术帮3 小时前
10410_基于Springboot的文化旅游宣传网站
spring boot·后端·vue·源码·旅游·安装·在线旅游