内容简介:1、使用log4j的日志存储,2、一对一关系,3、二级缓存

1       整合log4j(了解)

l  slf4j 核心jar  : slf4j-api-1.6.1.jar 。slf4j是日志框架,将其他优秀的日志第三方进行整合。

l  整合导入jar包

log4j 核心包:log4j-1.2.17.jar

过渡jar(整合jar):slf4j-log4j12-1.7.5.jar

l  导入配置文件

log4j.properties  ,此配置文件通知log4j 如何输出日志

l  配置文件内容:

1.记录器

2.输出源

3.布局

l  记录器

例如: log4j.rootLogger=info, stdout,file

格式:log4j.rootLogger=日志级别, 输出源1,输出源2,。。。。

log4j 日志级别 : fatal 致命错误 error 错误 warn 警告 info 信息 debug 调试信息 trace 堆栈信息 (由高到底顺序)

l  输出源:

例如:log4j.appender.file=org.apache.log4j.FileAppender

格式:log4j.appender.输出源的名称=输出源的实现类

名称:自定义

实现类:log4j提供

输出源属性例如:log4j.appender.file.File=d\:mylog.log

输出源属性格式:log4j.appender.名称.属性=值

每一个输出源对应一个实现类,实现类都属性(setter),底层执行setter方法进行赋值

l  常见的输出源实现类

org.apache.log4j.FileAppender  输出文件中

file ,表示文件输出位置

org.apache.log4j.ConsoleAppender 输出到控制台

Target ,表示使用哪种输出方式,在控制台打印内容,取值:System.out / System.err

l  布局  -- 确定输出格式

例如:log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

格式:log4j.appender.数据源.layout=org.apache.log4j.PatternLayout

布局属性:log4j.appender. 数据源.layout.ConversionPattern=值

12:56:30,123  info

l  扩展:对指定的目录设置日志级别

例如:log4j.logger.org.hibernate.transaction=debug

格式:log4j.logger.包结构=级别

2       一对一

l  情况1:主表的主键,与从表的外键(唯一),形成主外键关系

l  情况2:主表的主键,与从表的主键,形成主外键关系 (从表的主键又是外键)

2.1.1   情况1

2.1.2   情况2

3       二级缓存【掌握】

3.1   介绍

3.1.1   缓存

    缓存(Cache): 计算机领域非常通用的概念。它介于应用程序永久性数据存储源(如硬盘上的文件或者数据

  库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能。缓存中

  的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存

缓存:程序<--(内存)-->硬盘

3.1.2   什么是二级缓存

l  hibernate 提供缓存机制:一级缓存、二级缓存

一级缓存:session级别缓存,在一次请求中共享数据。

二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂,共享一个二级缓存。

l  SessionFactory的缓存两部分:   内置缓存:使用一个Map,用于存放配置信息,预定义HQL语句等,提供

  给Hibernate框架自己使用,对外只读的。不能操作。  外置缓存:使用另一个Map,用于存放用户自定义

  数据。默认不开启。外置缓存hibernate只提供规范(接口),需要第三方实现类。外置缓存有成为二级缓存。

3.1.3   二级缓存内部结构

   二级就是由4部分构成

    类级别缓存

    集合级别缓存

     时间戳缓存

    查询缓存(二级缓存的第2大部分,三级缓存)

3.1.4   并发访问策略

l  访问策略:读写型(read-write)、只读型(read-only)

3.1.5   应用场景

l  适合放入二级缓存中的数据:

很少被修改

不是很重要的数据, 允许出现偶尔的并发问题

l  不适合放入二级缓存中的数据:

经常被修改

财务数据, 绝对不允许出现并发问题

与其他应用数据共享的数据

3.1.6   二级缓存提供商

EHCache: 可作为进程(单机)范围内的缓存, 存放数据的物理介质可以是内存或硬盘,

          对 Hibernate 的查询缓存提供了支持。--支持集群。

l  OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘,

       提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持

l  SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存

l  JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存

X表示支持

3.2   配置(操作)

1.导入jar包:ehcache-1.5.0.jar/ commons-logging.jar/ backport-util-concurrent.jar

2.开启二级缓存(我要使用二级缓存)

3.确定二级缓存提供商(我要使用哪个二级缓存)

4.确定需要缓存内容

1>配置需要缓存的类

2>配置需要缓存的集合

5.配置ehcache自定义配置文件

3.2.1   导入jar包

3.2.2   开启二级缓存

l  在hibernate.cfg.xml 配置二级缓存

<!-- 9.1 开启二级缓存 -->

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

3.2.3   确定提供商

l  hibernate.cfg.xml 配置

<!-- 9.2 提供商 -->

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

3.2.4   确定缓存内容

l  在hibernate.cfg.xml 确定 类缓存 和集合缓存配置项

l  配置

<!-- 9.3 确定缓存内容 -->

<!-- 类缓存 -->

<class-cache usage="read-write" class="com.itheima.a_init.Customer"/>

<class-cache usage="read-write" class="com.itheima.a_init.Order"/>

<!-- 集合缓存 -->

<collection-cache usage="read-write" collection="com.itheima.a_init.Customer.orderSet"/>

3.2.5   ehcache配置文件

步骤1:从jar包复制xml文件

步骤2:将xml重命名“ehcache.xml”

步骤3:将修改后的xml,拷贝到src下

3.3   演示

3.3.1   证明

@Test

public void demo01(){

//1 证明二级缓存存在

// * 修改toString()

// * 如果二级缓存开启,查询3 没有select语句,表示从二级缓存获得的。

// * 将二级缓存关闭,查询3将触发select语句。

Session s1 = factory.openSession();

s1.beginTransaction();

//1 查询id=1 -- 执行select (查询后,将数据存放在一级缓存,之后由一级缓存同步到二级缓存)

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 查询id=1 --从一级缓存获取

Customer c2 = (Customer) s1.get(Customer.class, 1);

System.out.println(c2);

s1.getTransaction().commit();

s1.close();

System.out.println("----------");

Session s2 = factory.openSession();

s2.beginTransaction();

//3 查询id=1 -- 从二级缓存获取

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

s2.getTransaction().commit();

s2.close();

}

3.3.2   类缓存

l  类缓存:只存放数据

l  一级缓存:存放对象本身

@Test

public void demo02(){

//2 类缓存:只存放数据,散装数据。

// * 使用默认的toString();

Session s1 = factory.openSession();

s1.beginTransaction();

//1 查询id=1 -- 执行select

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 查询id=1 -- 从一级缓存获取,一级缓存存放对象本身

Customer c2 = (Customer) s1.get(Customer.class, 1);

System.out.println(c2);

s1.getTransaction().commit();

s1.close();

System.out.println("----------");

Session s2 = factory.openSession();

s2.beginTransaction();

//3 查询id=1 -- 对象不一样,数据一样

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

s2.getTransaction().commit();

s2.close();

}

3.3.3   集合缓存

@Test

public void demo03(){

//3 集合缓存:只存放关联对象OID的值,如果需要数据,从类缓存中获取。

// * 3.1 默认:第一条select 查询客户,第二天 select 查询客户所有订单

// * 3.2 操作:在hibernate.cfg.xml 将 Order 类缓存删除

// *** <!--  <class-cache usage="read-write" class="com.itheima.a_init.Order"/>-->

// *** 多了10条select,通过订单的id查询订单

Session s1 = factory.openSession();

s1.beginTransaction();

//1 查询id=1

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 获得订单

for (Order o1 : c1.getOrderSet()) {

System.out.println(o1);

}

s1.getTransaction().commit();

s1.close();

System.out.println("----------");

Session s2 = factory.openSession();

s2.beginTransaction();

//3 查询id=1

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

//4 获得订单

for (Order o2 : c3.getOrderSet()) {

System.out.println(o2);

}

s2.getTransaction().commit();

s2.close();

}

3.3.4   时间戳

l  时间戳:任何操作都在时间戳中记录操作时间。

@Test

public void demo04(){

//4 时间戳: 所有的操作都会在时间戳中进行记录,如果数据不一致,将触发select语句进行查询

// * 修改toString()

Session s1 = factory.openSession();

s1.beginTransaction();

//1 查询id=1

Integer cid = 1;

Customer c1 = (Customer) s1.get(Customer.class, cid);

System.out.println(c1);

//2 绕过一级和二级缓存,修改数据库,修改客户cname=大东哥

s1.createQuery("update Customer set cname = ? where cid = ?")

.setString(0, "大东哥")

.setInteger(1, cid)

.executeUpdate();

//3打印

System.out.println(c1);

s1.getTransaction().commit();

s1.close();

System.out.println("----------");

Session s2 = factory.openSession();

s2.beginTransaction();

//4 查询id=1  -- ?

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

s2.getTransaction().commit();

s2.close();

}

3.3.5   查询缓存

l  查询缓存又称为三级缓存(民间)

l  查询缓存默认不使用。需要手动开启

l  查询缓存:将HQL语句与 查询结果进行绑定。通过HQL相同语句可以缓存内容。

默认情况Query对象只将查询结果存放在一级和二级缓存,不从一级或二级缓存获取。

查询缓存就是让Query可以从二级缓存获得内容。

步骤一:开启查询缓存

<!-- 9.4 开启查询缓存 -->

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

步骤二:在查询query对象,设置缓存内容(注意:存放和查询 都需要设置)

@Test

public void demo05(){

//5 查询缓存

Session s1 = factory.openSession();

s1.beginTransaction();

//1 query查询

Query q1 = s1.createQuery("from Customer");

q1.setCacheable(true);

List<Customer> a1 = q1.list();

for (Customer c1 : a1) {

System.out.println(c1);

}

//2 cid =1  -- 一级缓存获得

Customer customer = (Customer) s1.get(Customer.class, 1);

System.out.println(customer);

s1.getTransaction().commit();

s1.close();

System.out.println("----------");

Session s2 = factory.openSession();

s2.beginTransaction();

//2 cid =1  -- 二级缓存获得

Customer customer2 = (Customer) s2.get(Customer.class, 1);

System.out.println(customer2);

//3 query查询

Query q2 = s2.createQuery("from Customer");

q2.setCacheable(true);

List<Customer> a2 = q2.list();

for (Customer c2 : a2) {

System.out.println(c2);

}

s2.getTransaction().commit();

s2.close();

}

3.4   ehcache配置文件

l  <diskStore path="java.io.tmpdir"/>  设置临时文件存放位置。(缓存一般内存,一定程度时,写入硬盘。)

l  缓存详细设置

<defaultCache> 所有的缓存对象默认的配置

<cache name="类"> 指定对象单独配置

l  参数设置

maxElementsInMemory="10000"  内存最大数

eternal="false"  是否永久(内存常驻留)

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"  内存满了,是否写入到硬盘

maxElementsOnDisk="10000000"  硬盘最大数

diskPersistent="false"  关闭JVM,是否将内存保存硬盘中

diskExpiryThreadIntervalSeconds="120"  轮询

memoryStoreEvictionPolicy="LRU"

Least Recently Used (specified as LRU).

First In First Out (specified as FIFO)

Less Frequently Used (specified as LFU)

  • maxElementsInMemory :设置基于内存的缓存中可存放的对象最大数目
  • eternal:设置对象是否为永久的,true表示永不过期,此时将忽略timeToIdleSeconds timeToLiveSeconds属性; 默认值是false
  • timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。
  • timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。
    如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值
  • overflowToDisk:设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中
  • diskPersistent 当jvm结束时是否持久化对象 true false 默认是false
  • diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间
  •  memoryStoreEvictionPolicy
    -
    当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)

Hibernate4的更多相关文章

  1. spring hibernate4 c3p0连接池配置

    c3p0-0.9.1.2.jar,c3p0-oracle-thin-extras-0.9.1.2.jar,点此下载 <bean id="dataSource" class=& ...

  2. Hibernate4.0之HibernateSessionFactory源码详解

    import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Conf ...

  3. [转]Struts2.3.16.1+Hibernate4.3.4+Spring4.0.2 框架整合

    原文地址:http://blog.csdn.net/ycb1689/article/details/22928519 最新版Struts2+Hibernate+Spring整合 目前为止三大框架最新版 ...

  4. 基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!

    基于泛型的依赖注入.当我们的项目中有很多的Model时,相应的Dao(DaoImpl),Service(ServiceImpl)也会增多. 而我们对这些Model的操作很多都是类似的,下面是我举出的一 ...

  5. ssh中org.springframework.orm.hibernate4.support.OpenSessionInViewFilter的作用及配置

     org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 是Spring为我们解决Hibernate的Session的关闭 ...

  6. 基于Spring4+SpringMVC4+Mybatis3+Hibernate4+Junit4框架构建高性能企业级的部标GPS监控平台

    开发企业级的部标GPS监控平台,投入的开发力量很大,开发周期也很长,选择主流的开发语言以及成熟的开源技术框架来构建基础平台,是最恰当不过的事情,在设计之初就避免掉了技术选型的风险,避免以后在开发过程中 ...

  7. Hibernate3 和Hibernate4 在配置文件上的区别

    在使用hibernate之前要首先对hibernate进行一些基础的配置信息,像映射文件XXX.hbm.xml  XXX代表当前的domain的模型类名 <?xml version=" ...

  8. spring4+hibernate4+maven环境搭建

    本文主要介绍利用maven搭建spring4+hibernate4开发环境. 首先我们创建一个maven项目,具体步骤就不详细介绍了,看看我们pom.xml文件 <project xmlns=& ...

  9. Spring3 整合 Hibernate4实现数据库操作(1)

    Hibernate知识学习:http://justsee.iteye.com/blog/1061576 注意Hibernate4在开发当中的一些改变  :http://snake-hand.iteye ...

  10. Hibernate4中使用getCurrentSession报Could not obtain transaction-synchronized Session for current thread

    架个spring4+hibernate4的demo,dao层直接注入的sessionFactory,然后用getCurrentSession方法获取session,然后问题来了,直接报错: Could ...

随机推荐

  1. ansible的playbook简单使用

    一.介绍 playbook就是一个用yaml语法把多个模块堆起来的一个文件 核心组件: Hosts:执行的远程主机列表Tasks:任务,由模块定义的操作的列表:Varniables:内置变量或自定义变 ...

  2. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  3. Python:matplotlib绘制线条图

    线型图是学习matplotlib绘图的最基础案例.我们来看看具体过程:  下面我们将两条曲线绘制到一个图形里:   可以看到这种方式下,两个线条共用一个坐标轴,并且自动区分颜色. plot方法的核心是 ...

  4. Java多线程2:线程的使用及其生命周期

    一.线程的使用方式 1.继承Thread类,重写父类的run()方法 优点:实现简单,只需实例化继承类的实例,即可使用线程 缺点:扩展性不足,Java是单继承的语言,如果一个类已经继承了其他类,就无法 ...

  5. Yii2控制台命令

    Yii2控制台表格输出: 例如: $in_sheet_number_queue = []; $wms_material_in_sheet_list = \core\models\WmsMaterial ...

  6. LOADING Redis is loading the dataset in memory Redis javaAPI实例

    今天在实现Redis客户端API操作Jedis的八种调用方式详解中,遇到了LOADING Redis is loading the dataset in memory错误,经过多番查找资料,找到了解决 ...

  7. 实用的几个JS新特性(es 2016)

    在Chrome 55下测试,可用. 1.箭头函数(arrow function) 以前写的匿名函数是这样的 function(){}, 现在可以简单写成这样()=>{} 如果直接return,没 ...

  8. Vue单文件组件

    前面的话 本文将详细介绍Vue单文件组件 概述 在很多 Vue 项目中,使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: '#container '}) 在每个页 ...

  9. c++ string去除首尾 空格、\n、\r、\t

    string s = " test "; size_t n = s.find_last_not_of(" \r\n\t"); if (n != string:: ...

  10. Running ASP.NET Core applications on Windows Subsystem for Linux

    Setting up Linux on Windows 10 First thing is to enable Windows Subsystem for Linux. It doesn’t inst ...