• 欢迎来到本博客,希望可以y一起学习与分享

Hibernate(二)

Java benz 4年前 (2018-02-19) 122次浏览 0个评论 扫描二维码
文章目录[隐藏]

一、Hibernate持久化类的编写规则

什么是持久化类:

Hibernate是持久层的ORM映射框架,专注于数据的持久化工作。所谓的持久化,就是将内存中的数据永久存储到关系型数据库中。那么知道了什么是持久化,什么又是持久化类呢?其实所谓的持久化类指的是一个Java类与数据库表建立了映射关系,那么这个类称为是持久化类。其实你可以简单的理解为持久化类就是一个Java类有了一个映射文件与数据库的表建立了关系。那么我们在编写持久化类的时候有哪些要求呢?接下来我们来看一下。

持久化类的编写规则:

我们在编写持久化类的时候需要有以下几点需要注意:

  1. 持久化类需要提供无参数的构造方法。因为在Hibernate的底层需要使用反射生成类的实例。
  2. 持久化类的属性需要私有,对私有的属性提供公有的get和set方法。因为在Hibernate底层会将查询到的数据进行封装。
  3. 持久化类的属性要尽量使用包装类的类型。因为包装类和基本数据类型的默认值不同,包装类的类型语义描述更清晰而基本数据类型不容易描述。举个例子:
    假设表中有一列员工工资,如果使用double类型,如果这个员工工资忘记录入到系统中,系统会将默认值 0 存入到数据库,如果这个员工工资被扣完了,也会向系统中存入 0 那么这个 0 就有了多重含义,而如果使用包装类类型就会避免以上情况,如果使用Double类型,忘记录入工资就会存入null,而这个员工工资被扣完了,就会存入 0,不会产生歧义。
  4. 持久化类要有一个唯一标识OID与表的主键对应。因为Hibernate中需要通过这个唯一标识OID区分在内存中是否是同一个持久化类。在.Java中通过地址区分是否是同一个对象的,在关系型数据库的表中是通过主键区分是否同一条记录。那么Hibernate就是通过这个OID来进行区分的。Hibernate是不允许在内存中出现两个OID相同的持久化对象的。
  5. 持久化类尽量不要使用final进行修饰。因为Hibernate中有延迟加载的机制,这个机制中会产生代理对象,Hibernate产生代理对象使用的是字节码的增强技术完成的,其实就是产生了当前类的一个子类对象实现的。如果使用了final修饰持久化类。那么就不能产生子类,从而就不会产生代理对象,那么Hibernate的延迟加载策略(是一种优化手段)就会失效。

持久化类我们己经可以正常编写了,但是在持久化类中需要有一个唯一标识OID与表的主键去建立映射关系。而且主键一般我们是不会让客户手动录入的,一般我们是由程序生成主键。那么Hibernate中也提供了相应的主键生成的方式,那么我们来看下Hibernate的主键生成策略。

二、Hibernate主键生成策略

主键的类型:

在讲解Hibernate的主键生成策略之前,先来了解两个概念,即自然主键和代理主键,具体如下:
自然主键:把具有业务含义的字段作为主键,称之为自然主键。例如在customer表中,如果把name字段作为主键,其前提条件必须是:每一个客户的姓名不允许为null,不允许客户重名,并且不允许修改客户姓名。尽管这也是可行的,但是不能满足不断变化的业务需求,一日出现了允许客户重名的业务需求,就必须修改数据模型,重新定义表的主键,这给数据库的维护增加了难度。
代理主键:把不具备业务含义的字段作为主键,称之为代理主键。该字段一般取名为“ID”,通常为整数类型,因为整数类型比字符串类型要节省更多的数据库空间。在上面例子中,显然更合理的方式是使用代理主键。

Hibernate的主键生成策略:

Hibernate中,提供了几个内置的主键生成策略,其常用主键生成策略的名称和描述如下

主键生成策略

名称 描述
increment     用于long、short或int类型,由 Hibernate自动以递增的方式生成唯一标识符,每次增量为1。只有当没有其它进程向同一张表中插入数据时才可以使用,不能在集群环境下使用。适用于代理主键。
indentity     采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型。在DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL数据库中可以使用该生成器,该生成器要求在数据库中把主键定义成为自增长类型。适用于代理主键。
sequence     Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。适用于代理主键。
native     根据底层数据库对自动生成表示符的能力来选择identity、sequence、hilo三种生成器中的一种,适合跨数据库平台开发。适用于代理主键。
uuid     Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,其UUID被编码为一个长度为32位的十六进制字符串。这种策略并不流行,因为字符串类型的主键比整数类型的主键占用更多的数据库空间。适用于代理主键。
assigned     由 java程序负责生成标识符,如果不指定id元素的generator属性,则默认使用该主键生成策略。适用于自然主键。

三、Hibernate的持久化对象的三种状态

持久化对象三种状态的概述

了解了主键的生成策略之后,我们可以进一步来了解持久化类了。Hibernate为了更好的来管理持久化类,特将持久化类分成了三种状态。在Hibernate中持久化的对象可以划分为三种状态,分别是瞬时态、持久态和脱管态,一个持久化类的实例可能处于三种不同状态中的某一种,三种状态的详细介绍如下。
1、瞬时态(transient)
脚时态也称为临时态或者自由态,脚时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚术与Hibernate Session关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是一个信息携带的载体
2、持久态(persistent )
持久态的对象存在持久化标识OID,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在事务还未提交前变成持久态的。

3、脱管态(detached)
脱管态也称离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。

区分对象的三种状态:

为了帮助大家更好的理解持久化对象的三种状态,接下来通过具体的案例来演示持久化对象的三种状态。

  1. customer对象由new关键字创建,此时还未与Session进行关联,它的状态称为瞬时态;
  2. 在执行了session.save(customer)操作后,book对象纳入了Session的管理范围,这时的customer对象变成了持久态对象,此时Session的事务还没有被提交;
  3. 程序执行完commit()操作并关闭了Session后,customer对象与Session的关联被关闭,此时customer对象就变成了脱管态。

至此,便介绍完持久化对象的三种状态。在Hibernate的学习过程中,三种状态的特征变化以及各自的特点是非常重要,有助于更好的理解Hibernate,所以希望大家能够掌握。

附:其中HibernateUtils如下:

Hibernate持久化对象的三种状态转换

己经了解了Hibernate持久化对象的三种状态,然而这三种状态是可以通过一系列方法进行转换的,首先来看一下持久化对象的状态演化图

从图中可以看出,当一个对象被执行new关键字创建后,该对象处于瞬时态;当对瞬时态对象执行Session的save()或saveOrUpdate()方法后,该对象将被放入Session的一级缓存(在后面会有介绍),对象进入持久态;当对持久态对象执行evict()、close()或clear()操作后,对象进入脱管态;当直接执行Session的get()、load()、find()或iterate()等方法从数据库里查询对象时,查询到的对象也处于持久态;当对数据库中的纪录进行update()、saveOrUpdate()以及lock()等操作后,此时脱管态的对象就过渡到持久态;由于瞬时态和脱管态的对象不在session的管理范围,所以会在一段时间后被JVM回收。
持久化对象的三种状态可以通过调用Session中的一系列方法实现状态间的转换,具体如下:
1、瞬时态转换到其他状态
通过前面学习可知,瞬时态的对象自new关键字创建,瞬时态对象转换到其他状态总结如下:

  1. 瞬时态转换为持久态:执行Session的save()或saveOrUpdate()方法。
  2. 瞬时态转换为脱管态:为瞬时态对象设置持久化标识OID。

由于持久化对象状态演化图中没有涉及到瞬时态转换到脱管态的情况,这里做下简要的说明,在前面学习中可知,脱管态对象存在OID,但是没有Session的关联,也就是说脱管态和瞬时态的区别就是OID有没有值,所以可以通过为瞬时态对象设置OID,使其变成脱管态对象。

2、持久态对象转换到其他状态
持久化对象可以直接通过Hibernate中Session的get()、load()方法,或者Query查询从数据库中获得,持久态对象转换到其他状态总结如下:

  1. 持久态转换为瞬时态:执行Session的delete()方法,需要注意的是被删除的持久化对象,不建议再次使用。
  2. 持久态转换为脱管态:执行Session的evict()、close()或clear()方法。evict()方法用于清除一级缓存中某一个对象;close()方法用于关闭Session清除一级缓存;clear()方法用于清除一级缓存的所有对象。

3、脱管态对象转换到其他状态
脱管态对象无法直接获得,是由其他状态对象转换而来的,脱管态对象转换到其他状态总结如下:

  1. 脱管态转换为持久态:执行Session的update()、saveOrUpdate()或lock()方法。
  2. 脱管态转换为瞬时态:将脱管态对象的持久化标识OID设置为null。

由于持久化对象状态演化图中没有涉及到脱管态转换到瞬时态的情况,这里做下简要的说明,跟瞬时态转换到脱管态的情况相似,脱管态和瞬时态的区别就是OID有没有值,所以可以通过将脱管态对象的OID设置为null,使其变成瞬时态对象。例如在session.close()操作后,加入代码
customer. setCust_id(null); , customer对象将由脱管态转换为瞬时态。

持久态对象能够自动更新数据库

我们之前己经介绍了持久化对象的三种状态了,其实我们主要去研究持久态对象就够了,持久态对象其实有一个非常重要的特性:持久态对象可以自动更新数据库。

执行测试我们会发现,我们并没有手动调用update方法,Hibernate就可以将数据自动更新了。持久态对象就有这样的一个功能。持久态对象之所以有这样的功能其实都依赖了Hibernate的一级缓存。接下来我们就开始学习Hibernate的一级缓存。

Hibernate的一级缓存

缓存是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能
缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。
Hibernate的缓存分为一级缓存和二级缓存,Hibernate的这两级缓存都位于持久化层,存储的都是数据库数据的备份。其中第一级缓存为Hibernate的内置缓存,不能被卸载。接下来围绕Hibernate的一级缓存进行详细地讲解。

什么是Hibernate的一级缓存

Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。Hibernate的一级缓存的作用就是减少对数据库的访问次数。
在Session接口的实现中包含一系列的Java集合,这些Java集合构成了Session缓存。只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。固一级缓存也被称为是Session基本的缓存。
Hibernate的一级缓存有如下特点:

  1. 当应用程序调用Session接口的save()、update()、saveOrUpdate()时,如果Session缓存中没有相应的对象,Hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去。
  2. 当调用session按口的load()、get()方法,以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象,并添加到一级缓存中。
  3. 当调用Session的close()方法时,Session缓存会被清空。

测试一级缓存:

我们已经大致了解了什么是一级缓存了,那么一级缓存具体是否存在呢,我们可以通过如下的程序来证明一级缓存是存在的。

在以上代码中,第一次执行Session的get()方法获取customer1对象时,由于一级缓存中没有数据,所以Hibernate会向数据库发送一条sql语句,查询id等于1的对象;当再次调用了Session的get()方法获取customer2对象时,将不会再发送sql语句,这是因为customer2对象是从一级缓存中获取的。
接下来,验证一下代码的执行结果是否和描述的相一致。在Customer customer1= session.get(Customer.class, 1l);这一行设置断点,用debug方式执行 levelOneCache()方法,程序进入断点后点击单步跳过(或者按F6),代码执行过System.out.println(customer1);语句后,控制台的输出结果,如下图所示。

输出结果

从上图的输出结果中可以看出,执行第一次session.get()方法后Hibernate向数据库发送了一条select语句,这说明此时customer1对象是从数据库中查找的。执行输出语句输出customer1对象中的数据后,继续执行程序,当执行到输出customer2对象的代码处时,控制台输出结果如下图所示。

输出结果

从上图的输出结果可以看出,customer2对象的查询结果被直接打印了,说明第二次调用Session对象的get()方法没有向数据库发送select语句,而是直接从一级缓存中获取customer2对象。
之前我们介绍过Hibernate的持久态对象能够自动更新数据库,其实就是依赖了一级缓存,那么一级缓存为什么就可以去更新数据库了呢,其实是因为一级缓存的一块特殊的区域就是快照区。

一级缓存的内部结构:(快照区)

Hibernate向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库,并更新快照;如果一致,则不执行update语句。Hibernate快照的作用就是确保一级缓存中的数据和数据库中的数据一致。

四、Hibernate的事务控制

Hibernate是对JDBC的轻量级封装,其主要功能是操作数据库。在操作数据库过程中,经常会遇到事务处理的问题,那么我们接下来就来介绍Hibernate中的事务管理。
在学习Hibernate中的事务处理之前,先来回顾一下什么是事务。

什么是事务

在数据库操作中,一项事务(Transaction )是由一条或多条操作数据库的SQL语句组成的一个不可分割的工作单元。当事务中的所有操作都正常完成时,整个事务才能被提交到数据库中,如果有一项操作没有完成,则整个事务会被回滚。
其实事务总结起来理解为:逻辑上的一组操作,组成这组操作的各个单元,要么一起成功,要么一起失败。

事务的四个特性

事务有很严格的定义,需要同时满足四个特性,即原子性、一致性、隔离性、持久性。这四个特性通常称之为ACID特性,具体如下:

  1. 原子性( Atomic ):表示将事务中所做的操作捆绑成一个不可分割的单元,即对事务所进行的数据修改等操作,要么全部执行,要么全都不执行。
  2. 一致性( Consistency ):表示事务完成时,必须使所有的数据都保持一致状态。
  3. 隔离性( Isolation ):指一个事务的执行不能被其它事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性(Durability ):持久性也称永久性(permanence ),指一个事务一但提交,它对数据库中数据的改变就应该是永久性的。提交后的其他操作或故障不会对其有任何影响。

事务的并发问题

在实际应用过程中,数据库是要被多个用户所共同访问的。在多个事务同时使用相同的数据时,可能会发生并发的问题,具体如下。

  1. (1)脏读:一个事务读取到另一个事务未提交的数据。
  2. (2)不可重复读:一个事务读到了另一个事务己经提交的update的数据,导致在同一个事务中的多次查询结果不一致。
  3. (3)虚读/幻读:一个事务读到了另一个事务己经提交的insert的数据,导致在同一个事务中的多次查询结果不一致。

事务的隔离级别

为了避免事务并发问题的发生,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。

  1. 读未提交(Read Uncommitted, 1级):一个事务在执行过程中,既可以访问其他事务未提交的新插入的数据,又可以访问未提交的修改数据。如果一个事务己经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。此隔离级别可防止丢失更新。
  2. 己提交读(Read committed, 2级):一个事务在执行过程中,既可以访问其他事务成功提交的新插入的数据,又可以访问成功修改的数据。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。此隔离级别可有效防止脏读。
  3. 可重复读 (Repeatable Read, 4级):一个事务在执行过程中,可以访问其他事务成功提交的新插入的数据,但不可以访问成功修改的数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。此隔离级别可有效的防止不可重复读和脏读。
  4. 序列化/串行化(Serializable, 8级):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。此隔离级别可有效的防止脏读、不可重复读和幻读。
隔离级别 含义
READ_UNCOMMITTED 允许你读取还米提交的改变了的数据。可能导致脏、幻、不可重复读
READ_COMMITTED 允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生
REPEATABLE_READ 对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏读、不可重复读,但幻读仍可能发生。
SERIALIZABLE 完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。

事务的隔离级别,是由数据库提供的,并不是所有数据库都支持四种隔离级别

  1. MySQL:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE(默认REPEATABLE_READ)
  2. Oracle:READ_UNCOMMITTED、READ_COMMITTED、SERIALIZABLE(默认READ_COMMITTED)

在使用数据库时候,隔离级别越高,安全性越高,性能越低。
实际开发中,不会选择最高或者最低隔离级别,选择READ_COMMITTED (Oracle默认)、REPEATABLE_READ (MySQL默认)

Hibernate中的事务管理

在Hibernate中,可以通过代码来操作管理事务,如通过“Transaction tx = session.beginTransaction();”开启一个事务;持久化操作后,通过“tx. commit();”提交事务;如果事务出现异常,又通过“tx.rollback();”操作来撤销事务(事务回滚)。
除了在代码中对事务开启、提交和回滚操作外,还可以在Hibernate的配置文件中对事务进行配置。配置文件中,可以设置事务的隔离级别。其具体的配置方法是在hibernate.cfg.xml文件中的标签元素中进行的。配置方法如下所示。

到这我们己经设置了事务的隔离级别,那么我们在真正进行事务管理的时候,需要考虑事务的应用的场景,也就是说我们的事务控制不应该是在DAO层实现的,应该在Service层实现,并且在Service中调用多个DAO实现一个业务逻辑的操作。具体操作如下显示:

其实最主要的是如何保证在Service中开启的事务时使用的Session对象和DAO中多个操作使用的是同一个Session对象。
其实有两种办法可以实现:

  1. 可以在业务层获取到Session,并将Session作为参数传递给DAO。
  2. 可以使用ThreadLocal将业务层获取的Session绑定到当前线程中,然后在DAO中获取Session的时候,都从当前线程中获取。

其实使用第二种方式肯定是最优方案,那么具体的实现己经不用我们来完成了,Hibernate的内部己经将这个事情做完了。我们只需要完成一段配置即可。
Hibernates中自身提供了三种管理Session对象的方法

  1. Session对象的生命周期与本地线程绑定
  2. Session对象的生命周期与JTA事务绑定
  3. Hibernate委托程序管理Session对象的生命周期

在Hibernate的配置文件中,hibernate.current_session_context_class属性用于指定Session管理方式,可选值包括

  1. thread: Session对象的生命周期与本地线程绑定
  2. jta: Session对象的生命周期与JTA事务绑定
  3. managed: Hibernate委托程序来管理Session对象的生命周期

在hibernate.cfg.xml中进行如下配置:

hibernate提供sessionFactory.getCurrentSession()创建一个session和ThreadLocal绑定方法。

在HibernateUtil 工具类中更改getCurrentSession方法:

而且Hibernate中提供的这个与线程绑定的session可以不用关闭,当线程执行结束后,就会自动关闭了。
到这里我们已经对Hibernate的事务管理有了基本的了解,但是之前我们所做的CRUD的操作其实还没有查询多条记录。那如果我们需要查询多条记录要如何完成呢,我们接下来去学习一下Hibernate的其他的相关的API。

五、Hibernate的其他API

Query

Query代表面向对象的一个Hibernate查询操作。在Hibernate中,通常使用session.createQuery()方法接受一个HQL语句,然后调用Query的list()或uniqueResult()方法执行查询。所谓的HQL是Hibernate Query Language缩写,其语法很像SQL语法,但它是完全面向对象的。
在Hibernate中使用Query对象的步骤,具体所示:

  1. (1)获得Hibernate的Session对象。
  2. (2)编写HQL语句。
  3. (3)调用session.createQuery创建查询对象。
  4. (4)如果HQL语句包含参数,则调用Query的setXxx设置参数。
  5. (5)用Query对象的list()或uniqueResult()方法执行查询。

了解了使用Query对象的步骤后,接下来,通过具体示例来演示Query对象的查询操作。

程序通过使用Query接口,将customer表中的三条数据全部输出。更详细的HQL使用,会在后续讲解,此处只需了解Hibernate中是如何使用Query接口进行数据查询的即可。
Query中除了使用list()方法查询全部数据外,还有其它一些常用方法,具体如下:

  1. setter方法:Query接口中提供了一系列的setter方法用于设置查询语句中的参数,针对不同的数据类型,需要用到不同的setter方法。
  2. iterator()方法:该方法用于查询语句,返回的结果是一个Iterator对象,在读取时只能按照顺序方式读取,它仅把使用到的数据转换成Java实体对象。
  3. uniqueResult()方法:该方法用于返回唯一的结果,在确保只有一条记录的查询时可以使用该方法。
  4. executeUpdate()方法:该方法是Hibernate3的新特性,它支持HQL语句的更新和删除操作。
  5. setFirstResult()方法:该方法可以设置获取第一个记录的位置,也就是它表示从第几条记录开始查询,默认从0开始计算。
  6. setMaxResult()方法:该方法用于设置结果集的最大记录数,通常与setFirstResult()方法结合使用,用于限制结果集的范围,以实现分页功能。

Criteria

Criteria是一个完全面向对象,可扩展的条件查询API,通过它完全不需要考虑数据库底层如何实现,以及SQL语句如何编写,它是Hibernate框架的核心查询对象。Criteria查询,又称为QBC查询( Query By Criteria ),它是Hibernate的另一种对象检索方式。
org.hibernate.criterion.Criterion是Hibernate提供的一个面向对象查询条件接口,一个单独的查询就是Criterion接口的一个实例,用于限制Criteria对象的查询,在Hibernate中Criterion对象的创建通常是通过Restrictions工厂类完成的,它提供了条件查询方法。
通常,使用Criteria对象查询数据的主要步骤,具体如下:

  1. (1) 获得Hibernate的Session对象。
  2. (2) 通过Session获得Criteria对象。
  3. (3) 使用Restrictions的静态方法创建Criterion条件对象。Restrictions类中提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。
  4. (4) 向Criteria对象中添加Criterion查询条件。Criteria的add()方法用于加入查询条件。
  5. (5) 执行Criterita的 list() 或 uniqueResult() 获得结果。

了解了Criteria对象的使用步骤后,接下来,通过具体示例来演示。Criteria对象的查询操作。

在Criteria 对象中,除了使用criteria.list()方法查询全部数据外,还有其它一些常用方法:如果只返回一个值时,可以使用Criteria 的uniqueResult()方法;如果需要分页时可以使用setFirstResult()和setMaxResult()两个方法,setFirstResult()方法表示从第几条记录开始查询,setMaxResult()方法表示查询几条记录。

SQLQuery

SQLQuery这个就比较简单了,这个接口用于接收一个 sql 语句进行查询,然后调用list()或者uniqueResult()方法进行查询。但是sql语句不会直接封装到实体对象中,需要我们手动写代码才可以封装到实体中。


文章 Hibernate(二) 转载需要注明出处
喜欢 (0)

您必须 登录 才能发表评论!