文档章节

缓存、加载、检查、状态

CarlDing
 CarlDing
发布于 2016/06/27 14:59
字数 1485
阅读 11
收藏 0

注解实现的一对多

@Table(name = "persons")

@Entity

public class Person {

@Id

@Column(name = "person_id")

@GenericGenerator(name = "myid", strategy = "uuid")

@GeneratedValue(generator = "myid")

private String id;

@Column(name="person_name")

private String name;

@OneToMany

@Cascade(value=org.hibernate.annotations.CascadeType.SAVE_UPDATE)

@JoinColumn(name="car_personid")

private List<Car> cars = new ArrayList<>();

 

 

@Table(name="cars")

@Entity

public class Car {

@Id

@Column(name="car")

@GenericGenerator(name="uuid",strategy="uuid")

@GeneratedValue(generator="uuid")

private String id;

private String name;

@ManyToOne

@JoinColumn(name="car_personid")

private Person person;

 

 

注解实现的多对多

 

     Stud{

        @ManyToMany

        @JoinTable(name=”sc”,@JsonColumn(name=”sc_sid”,@reversJoinColum(name=”sc_cid”)

        Set<Course> set:

    

     }

 

 

 

 

对象的状态,一级缓存、二级缓存。

 

 

 

1:对象的状态

•瞬时(Transient)  —  由  new 操作符创建,且尚未与Hibernate

Session 关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数

据库中,也不会被赋予持久化标识(identifier)。 如果瞬时(Transient)对象在程序中没

有被引用,它会被垃圾回收器(garbage collector)销毁。 使用 Hibernate  Session 可以将其

变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)

 

Person p = new Person ();  领域对象,这个对象 还没有与Sesssion创建关系此时叫瞬时

 

•持久(Persistent)  —  持久(Persistent)的实例在数据库中有对应的记录,并拥有一

个持久化标识(identifier)。  持久(Persistent)的实例可能是刚被保存的,或刚被加载

的,无论哪一种,按定义,它存在于相关联的 Session 作用范围内。 Hibernate会检测到处于持

久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对

象数据(state)与数据库同步(synchronize)。 开发者不需要手动执行 UPDATE 。将对象从持

久(Persistent)状态变成瞬时(Transient)状态同样也不需要手动执行  DELETE 语句。

 

 

Session.ssave(p);//此时的p对象叫持久,与一个Session相关

 

 

•脱管(Detached) — 与持久(Persistent)对象关联的 Session 被关闭后,对象就变为脱管

(Detached)的。对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管

(Detached)对象如果重新关联到某个新的  Session 上, 会再次转变为持久(Persistent)的

(在Detached其间的改动将被持久化到数据库)。 这个功能使得一种编程模型,即中间会给用

户思考时间(user think-time)的长时间运行的操作单元(unit of work)的编程模型成为可

能。我们称之为应用程序事务,即从用户观点看是一个操作单元(unit of work)。

 

Session.close();

 

P.setname(“..”) 不会影响数据库中的值。

 

 

2:状态的与脏检查

@Test

public void test() {

Session s = HibernateUitls.openSession();

s.beginTransaction();

//根据id查询这个Person对象

Person p =

s.get(Person.class, "4028806a556d8c5701556d8c598b0000");//此时p对象叫持久化状态

p.setName("Smith");//脏检查

//s.update(p);

s.getTransaction().commit();

s.close();

}

 

3:懒加载

Session.get(Class,id) : 非懒加载,如果id不存在,则返回null- 命中数据库。

Session.load(CLass,id) :懒加载  - r返回的是一个代理,即使是id不存在,也返回一个对象

 

 <class name="cn.hib.domain.Person" table="persons" lazy="false">

        <id name="id" type="java.lang.String" length="32">

 

Session.load(CLass,id)  方法的使用的特点:

    Session s = HibernateUitls.openSession();

s.beginTransaction();

 

Stud stud = s.get(Stud.class, "S002");

//只是为了设置关系,没有必要命中数据库,只要知道C001的id即可

Course c = s.load(Course.class, "C001");

stud.getCourses().add(c);

 

s.getTransaction().commit();

s.close();

 

4:延迟加载

Enumerated Values :

- true  

- false

- extra  延迟加载

<set name="courses" table="sc" cascade="save-update" lazy="extra">

<key column="sc_sid"></key>

<many-to-many class="cn.hib.domain.Course" column="sc_cid"></many-to-many>

</set>

 

5:一级缓存与二级缓存

Session级别的缓存:一级缓存。它的特点是:容量没有限制。
                  事务级别的缓存,生命周期很短。

           openSession() :..开始。

           Session.close(); 关闭

                   一级缓存默认是打开的,且无法关闭。

 

SessionFactory级别的缓存 -

                默认的是关闭的。必须配置以后才可以打开。

                所有Session都共享同一个二级缓存。JVM级别的缓存。

                容量是配置,且必须要使用第三方的框架。

 

1:一级缓存

@Test

public void test() {

Session s = HibernateUitls.openSession();

Person p1 = s.get(Person.class, "S001");//执行过程是:1:先去命中一级缓存,2:再去命中二级缓存 3:于是命中了数据库

                                         //4:将这个对象放到二级缓存中去  5:放到一级缓存中去

Person p2 = s.get(Person.class, "S001");

System.err.println(p1==p2);

 

s.close();

 

 

 

可以操作删除一级缓存中的数据:

Session s = HibernateUitls.openSession();

Person p1 = s.get(Person.class, "S001");//执行过程是:1:先去命中一级缓存,2:再去命中二级缓存 3:于是命中了数据库

                                         //4:将这个对象放到二级缓存中去  5:放到一级缓存中去

 

//s.evict(p1);//删除放到一级缓存中的p1这一个对象

s.clear();//删除放到一级缓存中的所有对象

Person p2 = s.get(Person.class, "S001");

System.err.println(p1==p2);

 

s.close();

 

2:一级缓存与批量处理

 

 

@Test

public void test() {

Session s = HibernateUitls.openSession();

s.beginTransaction();

 

for(int i=0;i<50;i++){

Person p = new Person();

p.setName("Jerry"+i);

s.save(p);

if(i%20==0){

s.flush();

s.clear();

}

}

 

 

 

6:二级缓存

 

SessionFactory级别的缓存。

 

步1:添加第三方的缓存包 ehcache

 

 

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->

<dependency>

    <groupId>org.hibernate</groupId>

    <artifactId>hibernate-ehcache</artifactId>

    <version>5.1.0.Final</version>

</dependency>

 

 

步2:添加ehcache的配置文件

    <defaultCache

        maxElementsInMemory="100"

        eternal="false"

        timeToIdleSeconds="120"

        timeToLiveSeconds="120"

        overflowToDisk="true"

        />

</ehcache>

 

步3:配置对哪一个类进行二级缓存

 

<!-- 配置启用二级缓存 -->

<property name="hibernate.cache.use_second_level_cache">true</property>

<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

 

 

<mapping resource="cn/hib/domain/Person.hbm.xml" />

<mapping resource="cn/hib/domain/Stud.hbm.xml" />

 

<!-- 配置哪一个类进行二级缓存 -->

<class-cache usage="read-only" class="cn.hib.domain.Person" />

 

 

<!-- 配置哪一个类进行二级缓存 -->

<class-cache usage="read-only" class="cn.hib.domain.Person"/>

 

测试:

   打开两个Session

@Test

public void test() {

Session s = HibernateUitls.openSession();

Person p = s.get(Person.class, "S001");

s.close();

 

 

Session s2 = HibernateUitls.openSession();

Person p2 = s2.get(Person.class, "S001");

s2.close();

 

 

 

 

7:统计二级缓存的命中次数

<!-- 打开统计信息 -->

<property name="generate_statistics">true</property>

 

public class Demo01 {

@Test

public void test() {

Session s = HibernateUitls.openSession();

Person p = s.get(Person.class, "S001");//hit=0 miss=1 put=1

s.clear();

Person pp = s.get(Person.class, "S001");//hit=1,miss=1,put=1

s.close();

 

//删除二级缓存中的数据

HibernateUitls.getSessionFactory().getCache().evictAllRegions();

 

Session s2 = HibernateUitls.openSession();

Person p2 = s2.get(Person.class, "S001");//hit=1,miss=2,put=2

s2.close();

 

SessionFactory sf =

HibernateUitls.getSessionFactory();

Statistics stat =  sf.getStatistics();

System.err.println("命中数次:"+stat.getSecondLevelCacheHitCount());

System.err.println("没有命中:"+stat.getSecondLevelCacheMissCount());

System.err.println("放过几次:"+stat.getSecondLevelCachePutCount());

}

}

 

© 著作权归作者所有

CarlDing
粉丝 5
博文 106
码字总数 78103
作品 0
济南
其他
私信 提问
【死磕 Spring】—– IOC 之分析各 scope 的 bean 创建

原文出自:http://cmsblogs.com 在 Spring 中存在着不同的 scope,默认是 singleton ,还有 prototype、request 等等其他的 scope,他们的初始化步骤是怎样的呢?这个答案在这篇博客中给出。...

chenssy
2018/10/24
0
0
第九节——NGINX内容缓存

1 概述 缓存启用时,NGINX保存响应到磁盘缓存,客户端每次请求相同内容时无需代理请求,直接使用缓存内容响应客户端。 2 启用响应缓存 为了启用缓存,在http上下文中设置proxycachepath指令。...

Leech
2018/03/07
285
0
varnish 4.0 官方文档翻译9-用户手册- 向Vanish下发指令

CLI-bossing Varnish around CLI 向Vanish下发指令 一旦vanish启动,你可以使用命令行接口来控制它。 最轻松的使用CLI的方法是在运行varnishd的机器上运行,varnishadm varnishadm help 如果...

wild-life
2015/05/26
221
0
游戏UI框架设计(三) : 窗体的层级管理

游戏UI框架设计(三) ---窗体的层级管理   UI框架中UI窗体的“层级管理”,最核心的问题是如何进行窗体的显示管理。窗体(预设)的显示我们前面定义了三种类型: 普通、隐藏其他、反向切换。...

Liu_guozhu
2017/02/27
0
0
web内容缓存 nginx高性能缓存详解

内容缓存是显著提高web站点的性能最有效的方法之一。下面来说说nginx高性能缓存。 内容缓存的基本原则 对GET请求进行缓存。 使用:浏览器缓存,内容分发网络和/或反向代理缓存。 HTTP缓存机制...

憬薇
2017/05/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
14
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
15
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部