Hibernate详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xin917480852/article/details/52565734

什么是Hibernate

Hibernate 是一个高性能的对象/关系型持久化存储和查询的服务

什么是JDBC

JDBC 代表 Java Database Connectivity ,它是提供了一组 Java API 来访问关系数据库的 Java 程序

什么是对象关系映射

ORM 表示 Object-Relational Mapping (ORM),是一个方便在关系数据库和类似于 Java, C# 等面向对象的编程语言中转换数据的技术
java object --------ORM----------Database



Hibernate的配置对象

有两种基础组件:
  • 数据库连接:由 Hibernate 支持的一个或多个配置文件处理。这些文件是 hibernate.properties 和hibernate.cfg.xml
  • 类映射设置:这个组件创造了 Java 类和数据库表格之间的联系。

SessionFactory 对象

配置对象被用于创造一个 SessionFactory 对象,使用提供的配置文件为应用程序依次配置 Hibernate,并允许实例化一个会话对象

Session 对象

一个会话被用于与数据库的物理连接。Session 对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。

Transaction 对象

一个事务代表了与数据库工作的一个单元并且大部分 RDBMS 支持事务功能。在 Hibernate 中事务由底层事务管理器和事务(来自 JDBC 或者 JTA)处理。

Query 对象

Query 对象使用 SQL 或者 Hibernate 查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。

Criteria 对象

Criteria 对象被用于创造和执行面向规则查询的对象来检索对象

怎么搭建Hibernate

这个链接一
这个链接二

Hibernate的配置

Hibernate 需要事先知道在哪里找到映射信息,这些映射信息定义了 Java 类怎样关联到数据库表。Hibernate 也需要一套相关数据库和其它相关参数的配置设置。所有这些信息通常是作为一个标准的 Java 属性文件提供的,名叫 hibernate.properties。又或者是作为 XML 文件提供的,名叫 hibernate.cfg.xml
hibernate.cfg.xml的属性

Hibernate 属性

下面是一个重要的属性列表,你可能需要表中的属性来在单独的情况下配置数据库。

S.N. 属性和描述
1 hibernate.dialect 
这个属性使 Hibernate 应用为被选择的数据库生成适当的 SQL。
2 hibernate.connection.driver_class
JDBC 驱动程序类。
3 hibernate.connection.url 
数据库实例的 JDBC URL。
4 hibernate.connection.username
数据库用户名。
5 hibernate.connection.password 
数据库密码。
6 hibernate.connection.pool_size 
限制在 Hibernate 应用数据库连接池中连接的数量。
7 hibernate.connection.autocommit 
允许在 JDBC 连接中使用自动提交模式。

如果您正在使用 JNDI 和数据库应用程序服务器然后您必须配置以下属性:

S.N. 属性和描述
1 hibernate.connection.datasource 
在应用程序服务器环境中您正在使用的应用程序 JNDI 名。
2 hibernate.jndi.class 
JNDI 的 InitialContext 类。
3 hibernate.jndi.<JNDIpropertyname> 
在 JNDI的 InitialContext 类中通过任何你想要的 Java 命名和目录接口属性。
4 hibernate.jndi.url 
为 JNDI 提供 URL。
5 hibernate.connection.username 
数据库用户名。
6 hibernate.connection.password 
数据库密码。
与Mysql链接:hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

	<session-factory>
		<property name="myeclipse.connection.profile">
			database
		</property>
		<property name="dialect">
			org.hibernate.dialect.MySQLDialect
		</property>
		<property name="connection.username">root</property>
		<property name="connection.url">
			jdbc:mysql://localhost:3306/testdatabase
		</property>
		<property name="connection.driver_class">
			com.mysql.jdbc.Driver
		</property>
		
		<property name="show_sql">true</property>
		<property name="format_sql">true</property>
		<property name="hbm2ddl.auto">create</property>
		<!--   java映射表要在这里配置 -->
		<mapping resource="enity/Student.hbm.xml" />
		<mapping resource="enity/Grade.hbm.xml" />

	</session-factory>

</hibernate-configuration>

会话

Session 用于获取与数据库的物理连接 该 Session 对象不应该长时间保持开放状态,因为它们通常不能保证线程安全,而应该根据需求被创建和销毁。Session 的主要功能是为映射实体类的实例提供创建,读取和删除操作
HibernateSessionFactory这个类(Util类获取session)
package util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

/**
 * Configures and provides access to Hibernate sessions, tied to the
 * current thread of execution.  Follows the Thread Local Session
 * pattern, see {@link http://hibernate.org/42.html }.
 */
public class HibernateSessionFactory {

    /** 
     * Location of hibernate.cfg.xml file.
     * Location should be on the classpath as Hibernate uses  
     * #resourceAsStream style lookup for its configuration file. 
     * The default classpath location of the hibernate config file is 
     * in the default package. Use #setConfigFile() to update 
     * the location of the configuration file for the current session.   
     */
	private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static org.hibernate.SessionFactory sessionFactory;
	
    private static Configuration configuration = new Configuration();
    private static ServiceRegistry serviceRegistry; 

	static {
    	try {
			configuration.configure();
			serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
			try {
				sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
			} catch (Exception e) {
				StandardServiceRegistryBuilder.destroy(serviceRegistry);
				e.printStackTrace();
			}
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
    }
    private HibernateSessionFactory() {
    }
	
	/**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws HibernateException
     */
    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();

		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				rebuildSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}

        return session;
    }

	/**
     *  Rebuild hibernate session factory
     *
     */
	public static void rebuildSessionFactory() {
		try {
			configuration.configure();
			serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
			try {
				sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
			} catch (Exception e) {
				StandardServiceRegistryBuilder.destroy(serviceRegistry);
				e.printStackTrace();
			}
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
	}

	/**
     *  Close the single hibernate session instance.
     *
     *  @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

	/**
     *  return session factory
     *
     */
	public static org.hibernate.SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	/**
     *  return hibernate configuration
     *
     */
	public static Configuration getConfiguration() {
		return configuration;
	}

}
Session  接口提供了很多方法
序号 Session 方法及说明
1 Transaction beginTransaction()
开始工作单位,并返回关联事务对象。
2 void cancelQuery()
取消当前的查询执行。
3 void clear()
完全清除该会话。
4 Connection close()
通过释放和清理 JDBC 连接以结束该会话。
5 Criteria createCriteria(Class persistentClass)
为给定的实体类或实体类的超类创建一个新的 Criteria 实例。
6 Criteria createCriteria(String entityName)
为给定的实体名称创建一个新的 Criteria 实例。
7 Serializable getIdentifier(Object object)
返回与给定实体相关联的会话的标识符值。
8 Query createFilter(Object collection, String queryString)
为给定的集合和过滤字符创建查询的新实例。
9 Query createQuery(String queryString)
为给定的 HQL 查询字符创建查询的新实例。
10 SQLQuery createSQLQuery(String queryString)
为给定的 SQL 查询字符串创建 SQLQuery 的新实例。
11 void delete(Object object)
从数据存储中删除持久化实例。
12 void delete(String entityName, Object object)
从数据存储中删除持久化实例。
13 Session get(String entityName, Serializable id)
返回给定命名的且带有给定标识符或 null 的持久化实例(若无该种持久化实例)。
14 SessionFactory getSessionFactory()
获取创建该会话的 session 工厂。
15 void refresh(Object object)
从基本数据库中重新读取给定实例的状态。
16 Transaction getTransaction()
获取与该 session 关联的事务实例。
17 boolean isConnected()
检查当前 session 是否连接。
18 boolean isDirty()
该 session 中是否包含必须与数据库同步的变化?
19 boolean isOpen()
检查该 session 是否仍处于开启状态。
20 Serializable save(Object object)
先分配一个生成的标识,以保持给定的瞬时状态实例。
21 void saveOrUpdate(Object object)
保存(对象)或更新(对象)给定的实例。
22 void update(Object object)
更新带有标识符且是给定的处于脱管状态的实例的持久化实例。
23 void update(String entityName, Object object)
更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

持久化类

一个标准的POJO类
public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

映射文件

一个对象/关系型映射一般定义在 XML 文件中。映射文件指示 Hibernate 如何将已经定义的类或类组与数据库中的表对应起来。
尽管有些 Hibernate 用户选择手写 XML 文件,但是有很多工具可以用来给先进的 Hibernate 用户生成映射文件。这样的工具包括 XDocletMiddlegen 和 AndroMDA
上面那个POJO类的映射文件是
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
      <property name="salary" column="salary" type="int"/>
   </class>
</hibernate-mapping>

你需要以格式 <classname>.hbm.xml保存映射文件。我们保存映射文件在 Employee.hbm.xml 中。让我们来详细地看一下在映射文件中使用的一些标签:

  • 映射文件是一个以 <hibernate-mapping> 为根元素的 XML 文件,里面包含所有<class>标签。
  • <class> 标签是用来定义从一个 Java 类到数据库表的特定映射。Java 的类名使用 name 属性来表示,数据库表明用 table 属性来表示。
  • <meta> 标签是一个可选元素,可以被用来修饰类。
  • <id> 标签将类中独一无二的 ID 属性与数据库表中的主键关联起来。id 元素中的 name 属性引用类的性质,column 属性引用数据库表的列。type 属性保存 Hibernate 映射的类型,这个类型会将从 Java 转换成 SQL 数据类型。
  • 在 id 元素中的 <generator> 标签用来自动生成主键值。设置 generator 标签中的 class 属性可以设置 native 使 Hibernate 可以使用 identitysequence 或 hilo 算法根据底层数据库的情况来创建主键。
  • <property> 标签用来将 Java 类的属性与数据库表的列匹配。标签中 name 属性引用的是类的性质,column 属性引用的是数据库表的列。type 属性保存 Hibernate 映射的类型,这个类型会将从 Java 转换成 SQL 数据类型。

映射类型

在映射文件中已经声明被使用的 types 不是 Java 数据类型;它们也不是 SQL 数据库类型。这种类型被称为 Hibernate 映射类型

原始类型

映射类型 Java 类型 ANSI SQL 类型
integer int 或 java.lang.Integer INTEGER
long long 或 java.lang.Long BIGINT
short short 或 java.lang.Short SMALLINT
float float 或 java.lang.Float FLOAT
double double 或 java.lang.Double DOUBLE
big_decimal java.math.BigDecimal NUMERIC
character java.lang.String CHAR(1)
string java.lang.String VARCHAR
byte byte 或 java.lang.Byte TINYINT
boolean boolean 或 java.lang.Boolean BIT
yes/no boolean 或 java.lang.Boolean CHAR(1) ('Y' or 'N')
true/false boolean 或 java.lang.Boolean CHAR(1) ('T' or 'F')

日期和时间类型

映射类型 Java 类型 ANSI SQL 类型
date java.util.Date 或 java.sql.Date DATE
time java.util.Date 或 java.sql.Time TIME
timestamp java.util.Date 或 java.sql.Timestamp TIMESTAMP
calendar java.util.Calendar TIMESTAMP
calendar_date java.util.Calendar DATE

二进制和大型数据对象

映射类型 Java 类型 ANSI SQL 类型
binary byte[] VARBINARY (or BLOB)
text java.lang.String CLOB
serializable any Java class that implements java.io.Serializable VARBINARY (or BLOB)
clob java.sql.Clob CLOB
blob java.sql.Blob BLOB

JDK 相关类型

映射类型 Java 类型 ANSI SQL 类型
class java.lang.Class VARCHAR
locale java.util.Locale VARCHAR
timezone java.util.TimeZone VARCHAR
currency java.util.Currency VARCHAR

例子:使用Hibernate创建Java应用程序

1.创建POJO类
public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}
2.创建数据库(也可以不用创建,会根据映射文件自动生成)
create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

3.创建映射的配置文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
      <property name="salary" column="salary" type="int"/>
   </class>
</hibernate-mapping>

4.在 hibernate.cfg.xml 中添加
<mapping resource="(这里面是映射的配置文件)enity/Student.hbm.xml" />
5.通过 HibernateSessionFactory这个类获取会话进行CRUD操作

O/R映射

集合映射(不推荐使用)

如果一个实例或者类中有特定变量的值的集合,那么我们可以应用 Java 中的任何的可用的接口来映射这些值。Hibernate 可以保存 java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List 和其它持续的实例或者值的任何数组的实例。

集合类型 映射和描述
java.util.Set 它和 \<set> 元素匹配并且用 java.util.HashSet 初始化。
java.util.SortedSet 它和 \<set> 元素匹配并且用 java.util.TreeSet 初始化。sort 属性可以设置成比较器或者自然排序。
java.util.List 它和 \<list> 元素匹配并且用 java.util.ArrayList 初始化。
java.util.Collection 它和 \<bag> 或者 \<ibag> 元素匹配以及用 java.util.ArrayList 初始化。
java.util.Map 它和 \<map> 元素匹配并且用 java.util.HashMap 初始化。
java.util.SortedMap") 它和 \<map> 元素匹配并且用 java.util.TreeMap 初始化。sort 属性可以设置成比较器或者 自然排序。

关联映射

实体类之间的关联映射以及表之间的关系是 ORM 的灵魂之处。对象间的关系的子集可以用下列四种方式解释。关联映射可以是单向的也可以是双向的。

映射类型 描述
Many-to-One 使用 Hibernate 映射多对一关系
One-to-One 使用 Hibernate 映射一对一关系
One-to-Many 使用 Hibernate 映射一对多关系
Many-to-Many 使用 Hibernate 映射多对多关系

组件映射

作为变量的一员实体类很可能和其它类具有相关关系。如果引用的类没有自己的生命周期并且完全依靠于拥有它的那个实体类的生命周期的话,那么这个引用类因此就可以叫做组件类。

注释(注解)配置配置文件

使用Hibernate 3.x 注释包
这个是数据库中的表
create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

持久化类
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

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

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

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

   public Employee() {}
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}
Hibernate 检测到 @Id 注释字段并且认定它应该在运行时通过字段直接访问一个对象上的属性。如果你将 @Id 注释放在 getId() 方法中,你可以通过默认的 getter 和 setter 方法来访问属性。因此,所有其它注释也放在字段或是 getter 方法中,决定于选择的策略。

@Entity 注释

EJB 3 标准的注释包含在 javax.persistence 包,所以我们第一步需要导入这个包。第二步我们对 Employee 类使用@Entity 注释,标志着这个类为一个实体 bean,所以它必须含有一个没有参数的构造函数并且在可保护范围是可见的。

@Table 注释

@table 注释允许您明确表的详细信息保证实体在数据库中持续存在。

@table 注释提供了四个属性,允许您覆盖的表的名称,目录及其模式,在表中可以对列制定独特的约束。现在我们使用的是表名为 EMPLOYEE。

@Id 和 @GeneratedValue 注释

每一个实体 bean 都有一个主键,你在类中可以用 @Id 来进行注释。主键可以是一个字段或者是多个字段的组合,这取决于你的表的结构。

默认情况下,@Id 注释将自动确定最合适的主键生成策略,但是你可以通过使用 @GeneratedValue 注释来覆盖掉它。strategy 和 generator 这两个参数我不打算在这里讨论,所以我们只使用默认键生成策略。让 Hibernate 确定使用哪些生成器类型来使代码移植于不同的数据库之间。

@Column Annotation

@Column 注释用于指定某一列与某一个字段或是属性映射的细节信息。您可以使用下列注释的最常用的属性:

  • name 属性允许显式地指定列的名称。
  • length 属性为用于映射一个值,特别为一个字符串值的列的大小。
  • nullable 属性允许当生成模式时,一个列可以被标记为非空。
  • unique 属性允许列中只能含有唯一的内容

查询语言(HQL)

Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。

FROM 语句

如果你想要在存储中加载一个完整并持久的对象,你将使用 FROM 语句。以下是 FROM 语句的一些简单的语法:

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

如果你需要在 HQL 中完全限定类名,只需要指定包和类名,如下:

String hql = "FROM com.hibernatebook.criteria.Employee";
Query query = session.createQuery(hql);
List results = query.list();

AS 语句

在 HQL 中 AS 语句能够用来给你的类分配别名,尤其是在长查询的情况下。例如,我们之前的例子,可以用如下方式展示:

String hql = "FROM Employee AS E";
Query query = session.createQuery(hql);
List results = query.list();

SELECT 语句

SELECT 语句比 from 语句提供了更多的对结果集的控制。如果你只想得到对象的几个属性而不是整个对象你需要使用 SELECT 语句。下面是一个 SELECT 语句的简单语法示例,这个例子是为了得到 Employee 对象的 first_name 字段:

String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

值得注意的是 Employee.firstName 是 Employee 对象的属性,而不是一个 EMPLOYEE 表的字段

WHERE 语句

如果你想要精确地从数据库存储中返回特定对象,你需要使用 WHERE 语句。下面是 WHERE 语句的简单语法例子:

String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

ORDER BY 语句

为了给 HSQ 查询结果进行排序,你将需要使用 ORDER BY 语句。你能利用任意一个属性给你的结果进行排序,包括升序或降序排序。下面是一个使用 ORDER BY 语句的简单示例:

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();

GROUP BY 语句

这一语句允许 Hibernate 将信息从数据库中提取出来,并且基于某种属性的值将信息进行编组,通常而言,该语句会使用得到的结果来包含一个聚合值。下面是一个简单的使用 GROUP BY 语句的语法:

String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " +
             "GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

使用命名参数

Hibernate 的 HQL 查询功能支持命名参数。这使得 HQL 查询功能既能接受来自用户的简单输入,又无需防御 SQL 注入攻击。下面是使用命名参数的简单的语法:

String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

UPDATE 语句

HQL Hibernate 3 较 HQL Hibernate 2,新增了批量更新功能和选择性删除工作的功能。查询接口包含一个 executeUpdate() 方法,可以执行 HQL 的 UPDATE 或 DELETE 语句。

UPDATE 语句能够更新一个或多个对象的一个或多个属性。下面是使用 UPDATE 语句的简单的语法:

String hql = "UPDATE Employee set salary = :salary "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

DELETE 语句

DELETE 语句可以用来删除一个或多个对象。以下是使用 DELETE 语句的简单语法:

String hql = "DELETE FROM Employee "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

INSERT 语句

HQL 只有当记录从一个对象插入到另一个对象时才支持 INSERT INTO 语句。下面是使用 INSERT INTO 语句的简单的语法:

String hql = "INSERT INTO Employee(firstName, lastName, salary)"  + 
             "SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

聚合方法

HQL 类似于 SQL,支持一系列的聚合方法,它们以同样的方式在 HQL 和 SQL 中工作,以下列出了几种可用方法:

S.N. 方法 描述
1 avg(property name) 属性的平均值
2 count(property name or *) 属性在结果中出现的次数
3 max(property name) 属性值的最大值
4 min(property name) 属性值的最小值
5 sum(property name) 属性值的总和

distinct 关键字表示只计算行集中的唯一值。下面的查询只计算唯一的值:

String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

使用分页查询

以下为两种分页查询界面的方法:

S.N. 方法&描述
1 Query setFirstResult(int startPosition) 
该方法以一个整数表示结果中的第一行,从 0 行开始。
2 Query setMaxResults(int maxResult) 
这个方法告诉 Hibernate 来检索固定数量,即 maxResults 个对象。
举个例子实现分页
1.实体类
package com.cy.beans;

import java.util.List;

/**
 * 定义一个分页对象
 * @author acer
 *
 */
public class Pager {
    
    private int page;//当前页码
    private int pageTotal;//总页码
    private int rowsTotal;//总条数
    private int rows;//每页显示条数
        private String hql;//分页语句    
    private List<?> list;//返回的数据集合
    

    public Pager() {
        super();
    }
    
    public String getHql() {
        return hql;
    }



    public void setHql(String hql) {
        this.hql = hql;
    }



    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    public int getPageTotal() {
        return pageTotal;
    }
    public void setPageTotal(int pageTotal) {
        this.pageTotal = pageTotal;
    }
    public int getRowsTotal() {
        return rowsTotal;
    }
    public void setRowsTotal(int rowsTotal) {
        this.rowsTotal = rowsTotal;
        pageTotal = rowsTotal%rows==0 ? rowsTotal/rows : rowsTotal/rows+1;
    }
    public int getRows() {
        return rows;
    }
    public void setRows(int rows) {
        this.rows = rows;
    }
    public List<?> getList() {
        return list;
    }
    public void setList(List<?> list) {
        this.list = list;
    }


    @Override
    public String toString() {
        return "Pager [list=" + list + ", page=" + page + ", pageTotal="
                + pageTotal + ", rows=" + rows + ", rowsTotal=" + rowsTotal
                + "]";
    }
    

}

分页代码
public Pager pagerff(Pager p, Map<String, Object> pram) {
        Session session = null;
        Transaction tx = null;
        try {
            session=HibernateUtils.getSessionFactory().openSession();
            tx=session.beginTransaction();
            String hql=p.getHql();//获取查询语句
            Query query= session.createQuery(hql).setCacheable(true);
            //设置参数
            query.setProperties(pram);
            //查询具体数据
            int count=query.list().size();
            p.setRowsTotal(count);
            int nowPage=1;
            if(p.getPage()>0){
                nowPage=p.getPage();
            }
            //指定从那个对象开始查询,参数的索引位置是从0开始的,
            query.setFirstResult((p.getPage()-1)*p.getRows());
            //分页时,一次最多产寻的对象数
            query.setMaxResults(p.getRows());
            List<?> list1=query.list();        
            p.setList(list1);
            tx.commit();
            
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally{
            session.close();
        }
        return  p;
    }

这个分页里主要使用了两个方法。

setFirstResult():设置从哪条数据开始查询的(分页的索引是从0开始的);
setProperties():设置每页显示的条数。

标准查询

Hibernate Session 接口提供了 createCriteria() 方法,可用于创建一个 Criteria 对象,使当您的应用程序执行一个标准查询时返回一个持久化对象的类的实例。

以下是一个最简单的标准查询的例子,它只是简单地返回对应于员工类的每个对象:

Criteria cr = session.createCriteria(Employee.class);  
List results = cr.list();  

对标准的限制

你可以使用 Criteria 对象可用的 add() 方法去添加一个标准查询的限制。

以下是一个示例,它实现了添加一个限制,令返回工资等于 2000 的记录:

Criteria cr = session.createCriteria(Employee.class);    
cr.add(Restrictions.eq("salary", 2000));    
List results = cr.list();  

Hibernate Session 接口提供了 createCriteria() 方法,可用于创建一个 Criteria 对象,使当您的应用程序执行一个标准查询时返回一个持久化对象的类的实例。

以下是一个最简单的标准查询的例子,它只是简单地返回对应于员工类的每个对象:

Criteria cr = session.createCriteria(Employee.class);  
List results = cr.list();  

你可以模仿以下示例,使用逻辑表达式创建 AND 或 OR 的条件组合:

Criteria cr = session.createCriteria(Employee.class);

Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");

// To get records matching with OR condistions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );

// To get records matching with AND condistions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );

List results = cr.list();

排序结果

标准 API 提供了 org.hibernate.criterion.order 类可以去根据你的一个对象的属性把你的排序结果集按升序或降序排列。这个例子演示了如何使用 Order 类对结果集进行排序:

Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To sort records in descening order
crit.addOrder(Order.desc("salary"));

// To sort records in ascending order
crit.addOrder(Order.asc("salary"));

List results = cr.list();  

预测与聚合

标准 API 提供了 org.hibernate.criterion.projections 类可得到各属性值的平均值,最大值或最小值。Projections 类与 Restrictions 类相似,均提供了几个获取预测实例的静态工厂方法。

以下是几个例子,涵盖了不同的情况,可按要求进行使用:

Criteria cr = session.createCriteria(Employee.class);

// To get total row count.
cr.setProjection(Projections.rowCount());

// To get average of a property.
cr.setProjection(Projections.avg("salary"));

// To get distinct count of a property.
cr.setProjection(Projections.countDistinct("firstName"));

// To get maximum of a property.
cr.setProjection(Projections.max("salary"));

// To get minimum of a property.
cr.setProjection(Projections.min("salary"));

// To get sum of a property.
cr.setProjection(Projections.sum("salary"));  

原生SQL

未完待续。。。

猜你喜欢

转载自blog.csdn.net/xin917480852/article/details/52565734