博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java实战之02Hibernate-02映射、一级缓存、实体对象状态
阅读量:5052 次
发布时间:2019-06-12

本文共 6863 字,大约阅读时间需要 22 分钟。

五、映射基础

1、实体类采用javabean的编写规范

JavaBean编写规范:

a、类一般是public

b、有默认的构造方法

c、字段都是私有的

d、提供公有的gettersetter方法

e、一般都实现java.io.Serializable接口

注意:hibernate采用的暴力反射

2、基本类型OR包装类型

int ---> Integer

.......

3、访问实体类数据的策略(了解)

通过上面我们可知,hibernate是采用的暴力反射,所以我们既可以通过属性页可以用过字段访问。但是一般都使用属性(即getset方法)

 

直接执行会报错,我们需要通过在配置文件中配置,来告知hibernate采用访问属性的方式进行取值和赋值。

1 
2
9 12
13
14
15
16
17
18
24
25
26
29
30
31
32
33

4、派生属性

概念:

实体类中的某些属性在数据库表中没有对应的字段,该属性的值是由数据库表中其他字段计算出来的。这样的属性叫做派生属性。

模拟测试数据:

创建一个订单表:

1 
2
3
4
5
6
7
12
13
14

5、控制insertupdate

映射文件:xml

5.1property元素(了解)

insert:默认值是true,如果改为false。表示该属性永远不会被插入。(动态生成的SQL语句)

1 
2
9 12
13
20
21
22
23
24
40
41
42
51
52
53
54
55

5.2class元素

mutable:默认值是true,如果为false,表示当前类所有属性都不会被修改。

dynamic-insert:默认是false,如果为true。会动态生成insert语句,只涉及不为null的字段。

 

dynamic-update:默认值是false。如果为true,会动态生成update语句,只更新数据有变化了的字段。

如果类的属性很多,建立动态生成insertupdate。(动态生成SQL消耗的资源可以忽略不计)。

6、避免与数据库关键字冲突的问题

例如:

我们在创建订单表时,有可能会使用Order来作为表名,但是由于order是关键字,可以在order上加入反引号。

六、映射对象标识符

1、概述

总结:应该让Hibernate来管理OID

2Hibernate主键生成策略

2.1、如何配置

1 
2   
3

2.2、常用生成策略

aincrement

OID必须是long,int,short类型的。

弊端:

适用于单应用访问同一个数据库的场合,在集群环境下不推荐使用。

bidentity

数据库系统必须支持自动增长字段类型

OID必须是longintshort类型

注意:incrementidentity的区别,一个是由Hibernate来负责维护,一个是由数据库来负责维护。

chilohibernate利用高地位算法生成OID

不依赖底层数据库,适用于所有的数据库。

OID必须是longintshort类型

该算法生成的标识符只能在一个数据库中保证唯一

1 
2
9 12
13
20
21
22
23
24
40
41
42
51
52
53
54
55

算法:

高值*(max_lo+1)+不大于max_lo的值

高值从0开始

0*(5+1)+0=0  忽略

0*(5+1)+1=1

0*(5+1)+2=2

0*(5+1)+3=3

0*(5+1)+4=4

0*(5+1)+5=5    下一个高值为1

1*(5+1)+0=6

1*(5+1)+1=7

1*(5+1)+2=8

1*(5+1)+3=9

1*(5+1)+4=10

1*(5+1)+5=11 下一个高值为2

dnative

依据底层数据库对自动生成标识符的支持能力来选择使用identitysequence来生成标识符

适合跨数据库平台开发

OID必须是longintshort类型

七、Session对象的一级缓存

1Session的一级缓存

1 //证明一级缓存的存在 2     @Test 3     public void test1(){ 4         Session s = HibernateUtil.getSession(); 5         Transaction tx = s.beginTransaction(); 6         Student s1 = s.get(Student.class, 2);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。 7         System.out.println(s1); 8         Student s2 = s.get(Student.class, 2);//不会去查询,因为一级缓存之中有数据。 9         System.out.println(s2);10         tx.commit();11         s.close();12     }

2、为什么使用缓存

a、减少访问数据库的频率。应用从缓存中读取数据的速度比从数据库获取数据要快,提高了数据的访问性能

b、当缓存中的对象之间存在循环关联关系时,Session保证不会出现访问对象的关联死循环,以及由死循环造成的JVM堆栈溢出问题

c、保证数据库中的相关记录与缓存中的对象保持同步

注意:当与数据库中的数据一致时,不会进行更新。

3、如何做到数据发生变化时进行同步

3.1、快照(SnapShot)机制

1 //修改数据 2     //快照机制 3     @Test 4     public void test2(){ 5         Session s = HibernateUtil.getSession(); 6         Transaction tx = s.beginTransaction(); 7         Student s1 = s.get(Student.class, 2);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。 8         System.out.println(s1);//gender:male 9         s1.setGender("male");//改gender,其实改的是内存对象10         System.out.println(s1);//gender:female11         tx.commit();12         s.close();//一级缓存在此行执行之后就消失了。13         14         //在此种再接着写代码15         System.out.println(s1);//gender:female16     }

4、控制Session的一级缓存

目的:学习Session中与一级缓存有关的方法。

4.1Session.clear();:清空缓存。

1 /* 2      * clear方法 3      *     作用:清空一级缓存 4      *  5      * 和close有区别: 6      *     close执行之后,一级缓存也没有了。 7      *     clear执行完成之后,session是还可以用的。 8      */ 9     @Test10     public void test1(){11         Session s = HibernateUtil.getSession();12         Transaction tx = s.beginTransaction();13         Student s1 = s.get(Student.class, 2);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。14         System.out.println(s1);15         16         s.clear();17         18         Student s2 = s.get(Student.class, 2);19         System.out.println(s2);20         tx.commit();21         s.close();22     }

4.2Session.evict(Object entity);:清除一级缓存中指定的实体对象。

1 /* 2      * evict方法 3      *     作用清除的是指定实体的缓存 4      */ 5     @Test 6     public void test2(){ 7         Session s = HibernateUtil.getSession(); 8         Transaction tx = s.beginTransaction(); 9         Student s2 = s.get(Student.class, 2);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。10         Student s3 = s.get(Student.class, 3);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。11         12         s.evict(s2);13         14         Student s4 = s.get(Student.class, 2);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。15         Student s5 = s.get(Student.class, 3);//不会去查询,因为一级缓存之中有数据16         tx.commit();17         s.close();18     }

4.3Session.refresh(Obect entity);:重新刷新缓存(用数据库中的数据同步缓存中指定的实体)

1 /* 2      * refresh方法 3      *     作用:那数据库的数据,来同步一级缓存。 4      */ 5     @Test 6     public void test3(){ 7         Session s = HibernateUtil.getSession(); 8         Transaction tx = s.beginTransaction(); 9         Student s1 = s.get(Student.class, 6);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。10         System.out.println(s1);//gender :male11         s1.setGender("female");//修改gender:female12         System.out.println(s1);13         s.refresh(s1);14         System.out.println(s1);15         tx.commit();16         s.close();17     }

4.4Session.flush();:清理缓存(同步缓存中数据到数据库中),但是不会清空。

a、清理时机:

1Transaction.commit()时会先清理缓存后提交事务。安排在此处是为了减少数据访问的频率和缩短当前事务对数据库中资源的锁定时间。

2、当应用中执行一些查询操作(Query)时,如果缓存中的对象发生了变化,会先进行清理。从而保证查询出的数据是正确的

3、显式调用Sessionflush()方法

1 /* 2      * flush方法 3      *     作用:手动刷新缓存。把数据从session中刷新出去。 4      */ 5     @Test 6     public void test5(){ 7         Session s = HibernateUtil.getSession(); 8         Transaction tx = s.beginTransaction(); 9         Student s1 = s.get(Student.class, 6);//会去数据库查询,同时会把查询出来的数据存入一级缓存之中。10         System.out.println(s1);//gender :male11         s1.setGender("male");//修改gender:female12         System.out.println(s1);13         14         s.flush();//当有此行存在时,此时就会看到update语句15         16         tx.commit();//默认此行刷出缓存中的数据。去拿缓存修改数据库的数据17         s.close();18     }

b、设置清理时机

 

八、实体对象的状态

1、各种状态图

 

2、状态说明:(判断对象处于什么状态不以数据库中有无记录作为依据,因为事务的问题,事务是否已经提交)

2.1、临时状态(transient):

new语句创建,还没有被持久化,并且不在Session的缓存中。 

标识:OIDnull,没有和Session建立关系。

2.2、持久化状态(persistent):

已经计划被持久化,并且加入到Session的缓存中。(为什么说计划:因为事务问题,是否已经提交事务)

标识:OID不为null,建立了和Session的关系。

2.3、删除状态(removed):

不在Session的缓存中,且Session已经计划将其从数据库中删除。

标识:OID不为null,计划要从Session中删除的。

2.4、游离状态(detached脱管)

已经被持久化,不在Session的缓存中

标识:OID不为null,没有和Session建立关系。

转载于:https://www.cnblogs.com/minihouseCoder/p/5599229.html

你可能感兴趣的文章
Oracle中的数据字典技术初级入门
查看>>
Java Build Practice 1:Ant
查看>>
3.RxJava详解
查看>>
【小波变换】STL版 一维离散小波变换(DWT)库,完全按matlab的wavelet toolbox 的API实现的...
查看>>
作业六:小学生四则运算之NABCD模型与产品Backlog。
查看>>
__int128的实现
查看>>
R 读取clipboard内容 (MAC)
查看>>
Problem - 1118B - Codeforces(Tanya and Candies)
查看>>
jdk1.8 api 下载
查看>>
svn 图标不显示
查看>>
getElement的几中属性介绍
查看>>
iOS 使用Quartz 2D画虚线 【转】
查看>>
平面最接近点对
查看>>
HTML列表,表格与媒体元素
查看>>
PHP、Java、Python、C、C++ 这几种编程语言都各有什么特点或优点?
查看>>
ApplicationDelegate里的方法
查看>>
C#中给WebClient添加代理Proxy
查看>>
py 的 第 10 天
查看>>
数据结构--各种排序的实现(排序小结 希尔排序 快排 堆排序 归并排序)
查看>>
Linux MMC framework2:基本组件之core
查看>>