如何比较HQL中的13位时间戳转换成时间字段

Hibernate设置时间戳的默认值和更新时间的自动更新
Generated and default property values
生成的和默认的属性值
The database sometimes generates a property value, usually when you insert a row for the first time.
通常会在第一次插入一条数据的时候产生一个属性值。
Examples of database-generated values are a creation timestamp, a default price for an item, and a trigger that runs for every modification.
数据库产生值得一个例子就是创建时的时间戳,物品的初始默认价格,以及每次修改时运行的触发器。
Typically, Hibernate applications need to refresh instances that contain any properties for which the database generates values, after saving.
典型的,HIbernate应用程序在保存之后需要刷新包含由数据库为其生成值的任何属性对象。
This means you would have to make another round trip to the database to read the value after inserting or updating a row.
这就意味着,你不得不进行另一次的数据库访问来读取插入或者更新一行数据之后的值。
Marking properties as generated, however, lets the application delegate this responsibility to Hibernate.
然而,把属性标识为已生成,就让应用程序把责任委托给了hibernate。
Essentially, whenever Hibernate issues an SQL INSERT or UPDATE for an entity that has declared generated properties, it does a SELECT immediately afterward to retrieve the generated values.
基本上,当hibernate为一个声明了已生成标识的属性的实体执行SQL插入或者更新的时候,它会立刻执行一个select来获取新生成的值。
You mark generated properties with the @org.hibernate.annotations.Generated annotation.
你使用注解@org.hibernate.annotations.Generated来标识一个已生成属性。
Listing 5.4 Database-generated property values
代码清单5.4 数据库生成的属性值展示
@Temporal(TemporalType.TIMESTAMP)
@Column(insertable = false, updatable = false)
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.ALWAYS
protected Date lastM
@Column(insertable = false)
@org.hibernate.annotations.ColumnDefault(&1.00&)
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.INSERT
protected BigDecimal initialP
Available settings for GenerationTime are ALWAYS and INSERT.
GenerationTime的可用的设置选项是ALWAYS和INSERT。
With ALWAYS, Hibernate refreshes the entity instance after every SQL UPDATE or INSERT.
当使用ALWAYS的时候,Hibernate每次执行SQL UPADATE或者INSERT插入的时候就会刷新实体。
The example assumes that a database trigger will keep the lastModified property current.
例子假定数据库的触发器能保持让lastModified属性保持是当前时间。
The property should also be marked read-only, with the updatable and insertable parameters of @Column.
属性也应该标识为只读,只读属性使用注解@Column的updatable和insertable来实现。
If both are set to false, the property&s column(s) never appear in the INSERT or UPDATE statements, and you let the database generate the value.
如果两个都设置了false,属性列表就用于不会在INSERT或者UPADATE语句中出现了,这些列的数值就由数据库来产生值咯。
With GenerationTime.INSERT, refreshing only occurs after an SQL INSERT, to retrieve the default value provided by the database.
使用GenerationTime.INSERT,只会在SQL INSERT的时候出现,来获取数据库的默认值。
Hibernate also maps the property as not insertable. hibernate也会映射为属性不可插入。
The @ColumnDefault Hibernate annotation sets the default value of the column when Hibernate exports and generates the SQL schema DDL.
@ColumnDefault属性注解,设置列表的默认属性,当hibernate导出和生成SQL schenma DDL的时候。
Timestamps are frequently automatically generated values, either by the database,as in the previous example, or by the application. Let&s have a closer look at the @Temporal annotation you saw in listing 5.4.
Timestamps是自动生成值中经常使用的,或者是通过数据库产生,如之前的例子,或者是通过应用程序生成,可以通过仔细观看下面代码清单5.4中的注解。
The lastModified property of the last example was of type java.util.Date, and a database trigger on SQL INSERT generated its value.
在、上个例子的java.utia.Date类型中的 lastModifiied属性和数据库的SQL INSERT触发器产生值。
The JPA specification requires that you annotate temporal properties with @Temporal to declare the accuracy of the
SQL data type of the mapped column.
JPA规范要求使用@Temporal注解来声明映射的SQL数据类型。
temporal types are java.util.Date,java.util.Calendar, java.sql.Date, java.sql.Time, and java.sql.Timestamp.
java类型有如下java.util.Date,java.util.Calendar, java.sql.Date, java.sql.Time, and java.sql.Timestamp。
Hibernate also supports the classes of the java.time package available in JDK 8. (Actually, the annotation isn&t required if a converter is applied or applicable for the property.You&ll see converters again later in this chapter.)
hibernate也提供JDK8中的java.time包。(实际上如果使用了converter转换器之后,注解是不需要了。在下一节会看在次看到转换器)
The next listing shows a JPA-compliant example: a typical &this item was created on& timestamp property that is saved once but never updated.
下一个代码清单展示一个JPA的兼容性例子。一个典型的 被创建于字段 一次保存的时候创建不被更新。
@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
@org.hibernate.annotations.CreationTimestamp
protected Date createdOn;
// Java 8 API
// protected Instant reviewedOn;
OK书本内容就是这样写的,下面看我们自己的需求和实现。
我们在定义JPA的entity时,有需要设置数据库时间戳的需求,一般情况下,会有一个字段需求记录创建时间,一个字段记录更新时间。那么在hibernate配置中是如何操作的呢?
@Table(name=&RS_SIGNUPUSER&)
public class RsSignUpUser {
@GenericGenerator(name=&UUIDGENERATE&,strategy=&uuid2&)
@GeneratedValue(generator=&UUIDGENERATE&)
@Column(name=&ID&,length=36)
private String ID;
@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
@org.hibernate.annotations.CreationTimestamp
private Date CREATETIME;
@Column(name=&UPDATETIME&)
@org.hibernate.annotations.UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date UPDATETIME;
略去了getters和setters方法。
创建的时候
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist( new Event( &Our very first event!&, new Date() ) );
RsSignUpUser rsuu = new RsSignUpUser();
rsuu.setUSERZYBM(&1&);
rsuu.setZONECODE(&1&);
entityManager.persist(rsuu);
睡眠一秒,更新
entityManager.getTransaction().commit();
entityManager.close();
// now lets pull events from the database and list them
entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
List result1 = entityManager.createQuery( &from RsSignUpUser&, RsSignUpUser.class ).getResultList();
for ( RsSignUpUser event : result1 ) {
event.setBZ(&bb&);
entityManager.getTransaction().commit();
entityManager.close();
可以看到数据库的数值:
时间是存在的。当然也可以在数据库的定义中增加,但是目前发现hibernate自动生成的表结构中,不能生成表注释和字段注释啊,一大遗憾啊。由 匿名 (未验证)
一、Hbernate中的日志框架_整合log4j(了解)
Hibernate 利用 Simple Logging Facade for Java (SLF4J)来记录不同系统事件的日志。SLF4J 可以根据你选择的绑定把日志输出到几个日志框架(NOP、Simple、log4j version1.2、JDK 1.4 logging、JCL 或 logback)上。
slf4j 核心jar:slf4j-api-1.6.1.jar 。slf4j 是日志框架,将其他优秀的日志第三方进行了整合。
整合导入jar包,添加至构建路径&&1、log4j 核心包:log4j-1.2.17.jar&&2、过渡jar(整合jar):slf4j-log4j12-1.7.5.jar
导入配置文件,该文件在 \hibernate-distribution-3.6.10.Final\project\etc 中,拷贝至项目的src 目录下&&log4j.properties,此配置文件配置log4j 如何输出日志。
编写配置文件内容:&&1、记录器&&2、输出源&&3、布局
记录器:&&例如:log4j.rootLogger=info, stdout, file&&格式:log4j.rootLogger=日志级别, 输出源1, 输出源2, &&&&log4j 日志级别:fatal 致命错误、error 错误、warn 警告、info 信息、debug 调试信息、trace 堆栈信息 (输出信息多少:日志信息量逐渐增加),项目上线时用error,项目开发中用info。
输出源:&&例如:log4j.appender.file=org.apache.log4j.FileAppender&&格式:log4j.appender.输出源的名称=输出源的实现类&&&&输出源的名称:自定义&&&&输出源的实现类:log4j提供&&输出源的属性,例如:log4j.appender.file.File=d:\mylog.log&&输出源的属性格式:log4j.appender.名称.属性=值&&每一个输出源对应一个实现类,实现类都是属性(setter),底层执行setter方法进行赋值。
常见的输出源实现类:&&org.apache.log4j.FileAppender
输出文件中&&&&file,表示文件输出位置&&org.apache.log4j.ConsoleAppender 输出到控制台&&&&Target,表示使用哪种输出方式,在控制台打印内容,取值:System.out / System.err
布局 =& 确定输出格式&&例如:log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&&格式:log4j.appender.数据源.layout=org.apache.log4j.PatternLayout&&布局属性:log4j.appender. 数据源.layout.ConversionPattern=值&&&&例如1:log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&&&&输出为:21:57:26,197
INFO SessionFactoryImpl:927 - closing&&&&例如2:log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n&&&&输出为:closing
扩展:对指定的目录设置日志级别&&例如:log4j.logger.org.hibernate.transaction=debug&&格式:log4j.logger.包结构=级别
二、Hibernate的关联关系映射(一对一)(了解)
情况1:主表的主键,与从表的外键(唯一),形成主外键关系。
情况2:主表的主键,与从表的主键,形成主外键关系 (从表的主键又是外键,即主键同步)-- 推荐使用该方式。
如下图所示:
2.1、情况1示例
Company.hbm.xml
&?xml&version="1.0"&encoding="UTF-8"?&&!DOCTYPE&hibernate-mapping&PUBLIC&&&&&"-//Hibernate/Hibernate&Mapping&DTD&3.0//EN"&&&&"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&&hibernate-mapping&&package="com.itheima.domain"&&&&&&class&name="Company"&table="t_company"&&&&&&&&&&id&name="cid"&column="cid"&&&&&&&&&&&&&&generator&class="native"&&/generator&&&&&&&&&&/id&&&&&&&&&&property&name="cname"&column="cname"&type="string"&&/property&&&&&&&&&&!--&一方的配置:一对一,特殊的多对一。&&&&&&&&&&&&&one-to-one:默认使用主键同步策略完成一对一的表关系体现。&&&&&&&&&&&&&&&&但是我们现在使用的是主外键引用来完成一对一的表关系体现。那么需要进行修正。&&&&&&&&&&&&&&&&使用&property-ref="company"&&&值是对方引用本方的属性名称&&&&&&&&--&&&&&&&&&&one-to-one&name="address"&class="Address"&property-ref="company"&&/one-to-one&&&&&&/class&&/hibernate-mapping&
Address.hbm.xml
&?xml&version="1.0"&encoding="UTF-8"?&&!DOCTYPE&hibernate-mapping&PUBLIC&&&&&"-//Hibernate/Hibernate&Mapping&DTD&3.0//EN"&&&&"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&&hibernate-mapping&&package="com.itheima.domain"&&&&&&class&name="Address"&table="t_address"&&&&&&&&&&id&name="aid"&column="aid"&&&&&&&&&&&&&&generator&class="native"&&/generator&&&&&&&&&&/id&&&&&&&&&&property&name="aname"&column="aname"&type="string"&&/property&&&&&&&&&&!--&多方的配置:一对一,特殊的多对一。外键唯一(外键不能重复),提供外键名称,unique默认值是false&--&&&&&&&&&&many-to-one&name="company"&class="Company"&column="company_id"&unique="true"&&/many-to-one&&&&&&/class&&/hibernate-mapping&
测试代码如下:
package&com.itheima.a_one2import&org.hibernate.Simport&org.junit.Timport&com.itheima.domain.Aimport&com.itheima.domain.Cimport&com.itheima.utils.HibernateU//&演示:一对一public&class&Demo1&{&&&&@Test&&&&//&一对一保存&&&&public&void&fun1()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&Company&c&=&new&Company();&&&&&&&&c.setCname("传智播客");&&&&&&&&Address&a&=&new&Address();&&&&&&&&a.setAname("北京市朝阳区平房乡红门村28号");&&&&&&&&//&注意:在一对一使用外键引用的时候,即情况1,外键所在的对象才能维护外键关系,另一方无法维护外键关系。&&&&&&&&a.setCompany(c);&//&维护外键关系&&&&&&&&//&注意:在一对一使用主外键同步的时候,即情况2,双方都能维护外键关系。&&&&&&&&//&a.setCompany(c);&//&维护外键关系&&&&&&&&//&c.setAddress(a);&//&维护外键关系&&&&&&&&session.save(c);&&&&&&&&session.save(a);&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}&&&&@Test&&&&//&一对一查询&&&&//&注意:Hibernate中一对一查询,一定会使用表连接查询,所以也就没有懒加载的问题了。&&&&public&void&fun2()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&Company&c&=&(Company)&session.get(Company.class,&1);&&&&&&&&System.out.println(c);&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}}
2.2、情况2示例
Company.hbm.xml
&?xml&version="1.0"&encoding="UTF-8"?&&!DOCTYPE&hibernate-mapping&PUBLIC&&&&&"-//Hibernate/Hibernate&Mapping&DTD&3.0//EN"&&&&"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&&hibernate-mapping&&package="com.itheima.domain"&&&&&&class&name="Company"&table="t_company"&&&&&&&&&&id&name="cid"&column="cid"&&&&&&&&&&&&&&generator&class="native"&&/generator&&&&&&&&&&/id&&&&&&&&&&property&name="cname"&column="cname"&type="string"&&/property&&&&&&&&&&!--&一方的配置:一对一,真正的一对一。不需要进行修正了。&&&&&&&&&&&&&one-to-one:默认使用主键同步策略完成一对一的表关系体现。我们现在就使用默认的策略。&&&&&&&&&&&&&&注意:此时可以使用以下3个属性。&&&&&&&&&&&&&&&&cascade&&&&&lazy&&&&&&&&fetch&&&&&&&&--&&&&&&&&&&one-to-one&name="address"&class="Address"&&&/one-to-one&&&&&&/class&&/hibernate-mapping&
Address.hbm.xml
&?xml&version="1.0"&encoding="UTF-8"?&&!DOCTYPE&hibernate-mapping&PUBLIC&&&&&"-//Hibernate/Hibernate&Mapping&DTD&3.0//EN"&&&&"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&&hibernate-mapping&&package="com.itheima.domain"&&&&&&class&name="Address"&table="t_address"&&&&&&&&&&id&name="aid"&column="aid"&&&&&&&&&&&&&&!--&foreign:声明该键既是主键又是外键&--&&&&&&&&&&&&&&generator&class="foreign"&&&&&&&&&&&&&&&&&&!--&当本方作为外键时,注入的是引用对方的属性名称&--&&&&&&&&&&&&&&&&&&param&name="property"&company&/param&&&&&&&&&&&&&&/generator&&&&&&&&&&/id&&&&&&&&&&property&name="aname"&column="aname"&type="string"&&/property&&&&&&&&&&!--&一方的配置:一对一,真正的一对一。既是主键又是外键,需要在某一方声明外键&,constrained表示约束,默认值是false--&&&&&&&&&&one-to-one&name="company"&class="Company"&constrained="true"&&/one-to-one&&&&&&/class&&/hibernate-mapping&
测试代码同上:
三、二级缓存【掌握】
3.1.1、缓存
&&缓存(Cache):是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。&&缓存:程序 &-- (内存) --& 硬盘
3.1.2、什么是二级缓存?
Hibernate 提供缓存机制:一级缓存、二级缓存。一级缓存:Session 级别缓存,在一次请求中共享数据。(当前有多少个线程连接到数据库,就会有多少个一级缓存。)二级缓存:SessionFactory 级别缓存,整个应用程序共享一个会话工厂,共享一个二级缓存。(二级缓存中存放的是经常使用的、不经常被修改的数据。)
SessionFactory的缓存两部分:内置缓存:使用一个Map,用于存放配置信息,如预定义的HQL语句等,提供给Hibernate框架自己使用,对外只读。不能操作。外置缓存:使用另一个Map,用于存放用户自定义数据。默认不开启。对于外置缓存,Hibernate只提供规范(接口),需要第三方实现类,所以我们使用二级缓存,还得导入第三方的jar包。外置缓存又称为二级缓存。
3.1.3、二级缓存的内部结构
二级缓存就是由4部分构成:&&类级别缓存&&集合级别缓存&&时间戳缓存&&查询级别缓存(二级缓存的第2大部分:三级缓存)内部结构如下所示:
3.1.4、并发访问策略
访问策略:读写型(read-write)、只读型(read-only)
3.1.5、应用场景
适合放入二级缓存中的数据:很少被修改不是很重要的数据,允许出现偶尔的并发问题
不适合放入二级缓存中的数据:经常被修改财务数据,绝对不允许出现并发问题与其他应用数据共享的数据
3.1.6、二级缓存提供商(即实现了二级缓存接口的厂商)
EHCache:可作为进程(单机)范围内的缓存,存放数据的物理介质可以是内存或硬盘,对 Hibernate 的查询缓存提供了支持。且支持集群。
OpenSymphony:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘。提供了丰富的缓存数据过期策略,对 Hibernate 的查询缓存提供了支持。
SwarmCache:可作为集群范围内的缓存,但不支持 Hibernate 的查询缓存。
JBoss Cache:可作为集群范围内的缓存,支持 Hibernate 的查询缓存。
&&配置即操作:亦即使用二级缓存提供商的提供的jar。
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、开启二级缓存(我要使用二级缓存)
  先在 hibernate.properties 中找到对应的键和值:
  再在 hibernate.cfg.xml 中配置开启二级缓存:
3.2.3、确定二级缓存提供商(我要使用哪个二级缓存)
  先在 hibernate.properties 中找到对应的键和值:
  再在 hibernate.cfg.xml 中配置确定二级缓存提供商:
3.2.4、确定缓存内容
  在 hibernate.cfg.xml 中确定 类级别缓存 和 集合级别缓存 配置项:  先确定这两个缓存所在配置文件中的位置:
  具体配置:
3.2.5、ehcache配置文件
步骤1:从jar包复制 ehcache-failsafe.xml 文件
步骤2:将 ehcache-failsafe.xml 重命名 ehcache.xml
步骤3:将修改后的 ehcache.xml,拷贝到src下
步骤4:删除掉 ehcache.xml 文件中无用的注释,得到清爽的 ehcache.xml 文件,文件内容如下:
ehcache.xml
&&ehcache&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"&&&&&&diskStore&path="java.io.tmpdir"/&&&&&&defaultCache&&&&&&&&&&&&maxElementsInMemory="10000"&&&&&&&&&&&&eternal="false"&&&&&&&&&&&&timeToIdleSeconds="120"&&&&&&&&&&&&timeToLiveSeconds="120"&&&&&&&&&&&&overflowToDisk="true"&&&&&&&&&&&&maxElementsOnDisk=""&&&&&&&&&&&&diskPersistent="false"&&&&&&&&&&&&diskExpiryThreadIntervalSeconds="120"&&&&&&&&&&&&memoryStoreEvictionPolicy="LRU"&&&&&&&&&&&&/&&/ehcache&
  一般,该文件的配置不是我们的工作,我们使用默认的配置即可,如果想配置,请看下文的 3.4、ehcache配置文件详解 。
3.3.1、证明二级缓存存在
  示例代码如下:见类缓存中的示例代码
3.3.2、类缓存
类缓存:只存放数据
一级缓存:存放对象本身如下图所示:示例代码如下:
package&com.itheima.a_one2import&org.hibernate.Simport&org.junit.Timport&com.itheima.domain.Cimport&com.itheima.utils.HibernateU//&演示:二级缓存public&class&Demo1&{&&&&@Test&&&&//&演示:证明二级缓存存在&+&二级缓存中的类缓存&&&&public&void&fun1()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&//&证明二级缓存存在&&&&&&&&Customer&c1&=&(Customer)&session.get(Customer.class,&1);&//&有select语句&&&&&&&&session.clear();&//&清空一级缓存中的内容&&&&&&&&Customer&c2&=&(Customer)&session.get(Customer.class,&1);&//&没有select语句&&&&&&&&//&二级缓存中的类缓存&&&&&&&&System.out.println(c1&==&c2);&//&false&&&&&&&&//&由以上说明,二级缓存中的类缓存在缓存数据时,并不是以对象的形式进行缓存的,而是缓存的是对象数据的散列,每次从二级缓存中取出数据,会在类缓存中组装成对象,并返回对象。&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}}
3.3.3、集合缓存
  如下图所示:
  示例代码如下:
package&com.itheima.a_one2import&java.util.Iimport&org.hibernate.Simport&org.junit.Timport&com.itheima.domain.Cimport&com.itheima.domain.Oimport&com.itheima.utils.HibernateU//&演示:二级缓存操作public&class&Demo2&{&&&&@Test&&&&//&演示:二级缓存中的集合缓存&&&&public&void&fun1()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&Customer&c1&=&(Customer)&session.get(Customer.class,&1);&//&一条&select&语句,查客户,是类&&&&&&&&for&(Order&o&:&c1.getOrders())&{&//&一条&select&语句,查客户的订单,是集合&&&&&&&&&&&&System.out.println(o.getOname());&&&&&&&&}&&&&&&&&session.clear();&//&清空一级缓存&&&&&&&&//&二级缓存中的集合缓存&&&&&&&&Customer&c2&=&(Customer)&session.get(Customer.class,&1);&//&没有select语句//&&&&&&&&//&增强for遍历//&&&&&&&&for&(Order&o&:&c1.getOrders())&{&//&没有select语句//&&&&&&&&&&&&System.out.println(o.getOname());//&&&&&&&&}&&&&&&&&//&迭代器遍历&&&&&&&&Iterator&Order&&it&=&c2.getOrders().iterator();&//&没有select语句&&&&&&&&while&(it.hasNext())&{&&&&&&&&&&&&Order&o&=&it.next();&&&&&&&&&&&&System.out.println(o.getOname());&&&&&&&&}&&&&&&&&//&如果在使用二级缓存的集合缓存的时候,如果把集合对应的类缓存没有配置上去的话,那么在遍历集合中的元素的时候,select语句会发送很多次。&&&&&&&&//&由上可知,二级缓存中的集合缓存中放的是对象的OID,每次从二级缓存中取出数据时,会根据IOD先从类缓存中查找OID对应的数据,如果没找到,会拿着OID从数据库中找。&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}}
3.3.4、查询缓存
查询缓存又称为三级缓存(民间叫法)
查询缓存默认不使用。需要手动开启。
查询缓存:将HQL语句与查询结果进行绑定。通过HQL相同语句可以缓存内容。默认情况Query对象只将查询结果存放在一级和二级缓存中,不从一级或二级缓存中获取。查询缓存就是让Query可以从二级缓存中获得内容。
步骤一:开启查询缓存
  先在 hibernate.properties 中找到对应的键和值:
  再在 hibernate.cfg.xml 中配置开启查询缓存: 步骤二:在查询query对象时,需要设置缓存内容(注意:存放和查询 都需要设置)  示例代码如下:
package&com.itheima.a_one2import&java.util.Limport&org.hibernate.Qimport&org.hibernate.Simport&org.junit.Timport&com.itheima.domain.Cimport&com.itheima.utils.HibernateU//&演示:二级缓存操作public&class&Demo3&{&&&&@SuppressWarnings({&"unused",&"unchecked"&})&&&&@Test&&&&//&演示:二级缓存中的查询缓存&&&&//&查询缓存是对hql语句查询的缓存&&&&public&void&fun1()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&Query&query&=&session.createQuery("from&Customer");&&&&&&&&//&使用二级缓存中的查询缓存时,需要单独再打开&&&&&&&&query.setCacheable(true);&//&查询时,会先从二级缓存中取结果,取不到就执行语句,将执行结果放入二级查询缓存中&&&&&&&&List&Customer&&list&=&query.list();&//&一条&select&语句&&&&&&&&session.clear();&//&清空一级缓存&&&&&&&&Query&query2&=&session.createQuery("select&c&from&Customer&c");&&&&&&&&query2.setCacheable(true);&&&&&&&&List&Customer&&list2&=&query2.list();&//&没有select语句&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}}
3.3.5、时间戳缓存
时间戳:任何操作都在时间戳中记录操作时间。
  示例代码如下:
package&com.itheima.a_one2import&org.hibernate.Simport&org.junit.Timport&com.itheima.domain.Cimport&com.itheima.utils.HibernateU//&演示:二级缓存操作public&class&Demo4&{&&&&@SuppressWarnings("unused")&&&&@Test&&&&//&演示:时间戳缓存&&&&public&void&fun1()&{&&&&&&&&Session&session&=&HibernateUtils.openSession();&&&&&&&&session.beginTransaction();&&&&&&&&Customer&c1&=&(Customer)&session.get(Customer.class,&1);&//&一条&select&语句&&&&&&&&session.createQuery("update&Customer&set&cname=:cname&where&cid&=:cid").setString("cname",&"rose").setInteger("cid",&1).executeUpdate();&//&使用HQL绑定参数&&&&&&&&session.clear();&//&清空一级缓存&&&&&&&&Customer&c2&=&(Customer)&session.get(Customer.class,&1);&//&又一条&select&语句,因为所有的操作都会在时间戳中进行记录,如果数据不一致(时间戳不一样),将触发select语句进行查询&&&&&&&&session.getTransaction().commit();&&&&&&&&session.close();&&&&}}
  二级缓存中类缓存、集合缓存、查询缓存、时间戳缓存的总结图:
3.4、ehcache配置文件详解
&ehcache&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"&&&&&&diskStore&path="java.io.tmpdir"/&&&&&&defaultCache&&&&&&&&&&&&maxElementsInMemory="10000"&&&&&&&&&&&&eternal="false"&&&&&&&&&&&&timeToIdleSeconds="120"&&&&&&&&&&&&timeToLiveSeconds="120"&&&&&&&&&&&&overflowToDisk="true"&&&&&&&&&&&&maxElementsOnDisk=""&&&&&&&&&&&&diskPersistent="false"&&&&&&&&&&&&diskExpiryThreadIntervalSeconds="120"&&&&&&&&&&&&memoryStoreEvictionPolicy="LRU"&&&&&&&&&&&&/&&/ehcache&&!--&&&&&&diskStore&path="java.io.tmpdir"/&&&设置临时文件存放位置。(缓存一般写入内存,一定程度时,写入硬盘。)&&&&缓存详细设置&&&&&defaultCache&/&&&&&所有的缓存对象默认的配置&&&&&cache&name="类"&&&&&指定对象单独配置&&&&参数设置&&&&&&&&maxElementsInMemory="10000"&&&&&内存最大数(类内存中存储对象数据的散列的最大数)&&&&&&&&eternal="false"&&&&&&&&&&&&&&&&&是否永久(内存常驻留)&&&&&&&&timeToIdleSeconds="120"&&&&&&&&&对象在内存中最多空闲多少秒&&&&&&&&timeToLiveSeconds="120"&&&&&&&&&对象在内存中最多存活多少秒&&&&&&&&overflowToDisk="true"&&&&&&&&&&&内存满了,是否写入到硬盘&&&&&&&&maxElementsOnDisk=""&&&&硬盘最大数(硬盘中存储对象数据的散列的最大数)&&&&&&&&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结束时是否持久化对象,默认是false&&&&&&&&&diskExpiryThreadIntervalSeconds&&&&指定专门用于清除过期对象的监听线程的轮询时间。&&&&&&&&&memoryStoreEvictionPolicy&&&&&&&&&&当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&默认是LRU(移除最近最少使用的元素),可选的有LFU(移除最不常使用的元素)和FIFO(先进先出)&。--&
四、Hibernate小案例

我要回帖

更多关于 java时间戳比较 的文章

 

随机推荐