Hibernate框架入门(二)

 

                                 第一章 hibernate中的实体规则

1.1 实体类创建的注意事项

1.持久化类需要提供无参的构造方法,因为hibernate底层需要使用反射生成类的实例。

2.成员变量私有,且要提供共有的get/set方法(类中的属性必须要有get/set方法,不管get/set方法是否有意义,如果没有的话那仅仅是成员变量)。

3.持久化类的属性尽量使用包装类型,不要用八大基本类型,比如int与integer,long与Long。包装类型能表达成null,数据库中很多字段不是必填的,很多是null,hibernate往基本数据类型放的时候会出问题。】

4.持久化类需要提供oid,与数据库中的主键列对应。

5.不要用final修饰class,hibernate使用的cglib代理生成代理对象,代理对象是继承被代理对象,如果被final修饰,将无法生成代理。

1.2 主键类型

自然主键:表的业务列中,有某列业务符合,必须有,并且不重复的特征时,该列可以作为主键。

代理主键:表的业务列中,没有某列业务符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键。

1.3 主键生成策略

每条记录录入时,主键的生成规则。

identity:主键自增,由数据库来维护主键的值,录入时不需要指定主键。

sequence:Oracle中的主键生成策略。

increment(了解):主键自增,由hibernate来维护,每次插入前会先查询表中id最大值。+1作为新主键值。

hilo(了解):高低位算法,主键自增,由hibernate来维护。

native:hilo+sequence+identity 自动三选一 策略

uuid:产生一个随机字符串,理论上不会重复,注意主键类型必须为uid。

assigned:自然主键生成策略。hibernate不会管理主键值,由开发人员自己指定。

                                 第二章 hibernate中的对象状态

对象分为三种状态,瞬时态,持久化状态,游离/托管状态

瞬时态:没有id,没有与session关联

持久化状态:有id,与session有关联

游离/托管状态:有id,没有与session关联

其实与session有关联实际上就是放入了session缓存中。

save方法其实不能理解为保存,理解成将瞬时状态转换为持久化状态。

主键自增:执行save方法时,为了将对象转换为持久化状态,必须生成id值,所以需要执行insert语句交由数据库来生成id值。

increment:执行save方法,为了生成id,会执行查询id最大值的sql语句。

三种状态的转换图:

学习对象三种状态结论:将我们希望同步到数据库的数据,对应的对象转换为持久化状态,

                                     第三章 hibernate一级缓存

缓存:提高效率,hibernate中的一级缓存也是为了提高操作数据库的效率。

当我们对同一个对象查询五次后,我们发现只用了一条语句。

缓存原理:以对象为单位进行缓存。

当我们对某对象进行修改时,修改两次却发现只发送了一条update语句,这是快照技术。

实例:

当用update时,将c1放入缓存中,不打印sql语句,当get时,因为缓存中存在c1,所以也不打印sql语句,最后事务提交时,根据上面的快照原理,因为缓存中存在c1,而快照中不存在对象,所以打印sql语句。

                                     第四章 hibernate中的事务

4.1 事务的概念

a:原子性 事务所包括的操作时最小且不可分割的,要么全成功,要么全失败。

c:一致性  数据的总量不发生变化,一致性是原子性的衍生物。

i:隔离性 多个事务在并发中可能会出现一系列问题,如脏读,幻读等等,隔离性提供了一定的隔离级别,来解决并发产生的问题。

事物的并发问题: 脏读 不可重复读  幻读

脏读:读未提交的数据

不可重复读:两次读取的数据不一致,比如第一次读取完后有人进行了修改等等。

幻|虚读:在一个事务进行过程中,另一个事务进行一些操作,使第一个事务没有达到预期效果,让人感觉产生了幻觉。如:一个进行全部修改的操作,在快要修改结束时插入了另一个条数据,结果显示修改成功时,数据里仍存在未修改的数据。

通过设置隔离级别可以解决并发中的问题

读未提交:三种问题都有

读已提交:解决脏读

可重复读:解决不可重复读的问题,就是在事务执行期间会锁定该事务以任何方式引用的所有行,所以多次读取的数据就一样了(mysql的默认隔离级别)。

串行化:对数据的访问只允许串行,不允许并发,可解决所有问题,但是效率很低。

d:持久性 保证在事务提交后所涉及到的数据必须被写入到硬盘中。

4.2 在hibernate中设置数据库的隔离级别

在主配置文件中,对隔离级别进行设置。

4.3 在项目中如何管理事务

之前是在service层中管理事务,即在业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常,回滚事务。

所以下面的代码就有问题,我们要在service层中对事务进行控制。

在dao层操作数据库需要使用session对象,在service层中也需要使用session对象完成,我们要确保dao层和service层使用的是同一个session对象,类似于以前的connection对象,在service层中要使用connection对象,在dao层中也要使用connection对象,所以应用了一个线程本地化的threadlocal类,将connection绑定在了线程上,来确保在同一个线程内用的都是同一个connection,所以我们在这里还是采用这种方法,我们将session绑定在线程上。

在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了,我们开发人员只需调用sf.getCurrentSession()方法,即可获得与当前线程绑定的session对象。

注意:1.调用getCurrentSession()方法必须配合主配置中的一段配置。

2.通过getCurrentSession()方法获得的session对象,当事务提交时,session会自动关闭,不要手动调用close关闭。否则会抛出异常。

实例代码:

dao层:

service层:

                                   第五章 hibernate中的批量查询

5.1 HQL查询

全称hibernate Query language,是hibernate独家查询语言,属于面向对象的查询语言。

下图是查询所有,因为是查询所有所以select * 可以省略,其次要全类名,如果类是唯一的,可以只填写类名。

查询id为1的customer,注意要填类中的属性名,一般来说HQL语句中只会不会出现数据的表名和列名。

问号占位符的使用

set后面的类型,取决于查询标识的类型,比如id为long,那么查询要用long型。同时在hibernate中第一个?是从零开始的。若搞不清楚类型或者图省事可以用setParameter,

命名占位符的使用,冒号后跟一个字符串即可。

分页查询

setFirstResult是从第几页开始抓,setMaxResult是每页抓多少个。第一页是从零开始查。

5.2 Criteria查询

hibernate自创的无语句面对对象查询

一般都先要创建查询对象Criteria

查询所有

条件查询

在HQL语句中,不可能出现任何数据库的相关的信息,在Criteria对象中,利用add方法添加限制Restrictions来进行查询。

一般的条件有 

分页:和上面的HQL有相似之处

查询总记录数:用setProjection来设置查询的聚合函数。

5.3 原生SQL查询

首先书写sql语句,创建查询对象传入sql语句,然后用List<Object[]>数组来接收查询结果。

要是想放到对象中,那么要先指定放到哪里

条件查询

分页查询

                                          

猜你喜欢

转载自blog.csdn.net/q610376681/article/details/81142467
今日推荐