1. 首先创建\META-INF\persistence.xml配置文件并做简单的配置

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
                version="2.0">

       <persistence-unit name="org.hibernate.tutorial.envers">
           <description>
              Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
           </description>

           <properties>
               <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
               <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/databaseName?useSSL=false&amp;serverTimezone=UTC&amp;verifyServerCertifate=false&amp;allowPublicKeyRetrieval=true" />
               <property name="javax.persistence.jdbc.user" value="root" />
               <property name="javax.persistence.jdbc.password" value="passwd" />
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true"/>
               <property name="hibernate.hbm2ddl.auto" value="create" />
           </properties>

       </persistence-unit>

    </persistence>
  2. 创建实体Java类

    import java.util.Date;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;

    import org.hibernate.annotations.GenericGenerator;
    import org.hibernate.envers.Audited;

    @Entity
    @Table( name = "EVENTS" )
    @Audited  // <--- this tell Envers to audit (track changes to) this entity
    public class Event {
       private Long id;

       private String title;
       private Date date;

    public Event() {
    // this form used by Hibernate
    }

    public Event(String title, Date date) {
    // for application use, to create new events
    this.title = title;
    this.date = date;
    }

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
       public Long getId() {
    return id;
      }

       private void setId(Long id) {
    this.id = id;
      }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "EVENT_DATE")
       public Date getDate() {
    return date;
      }

       public void setDate(Date date) {
    this.date = date;   }​    public String getTitle() { return title;   }​    public void setTitle(String title) { this.title = title;   }​ @Override public int hashCode() { int result = title.hashCode(); result = 31 * result + date.hashCode(); return result; }}
  3. 向META-INF/persistence.xml文件中添加映射信息

    <class>类路径.Event</class>
  4. JUnit测试测试程序

    import java.util.Date;
    import java.util.List;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;

    import junit.framework.TestCase;

    import org.hibernate.envers.AuditReader;
    import org.hibernate.envers.AuditReaderFactory;

    /**
    * Illustrates the set up and use of Envers.
    * <p>
    * This example is different from the others in that we really need to save multiple revisions to the entity in
    * order to get a good look at Envers in action.
    *
    * @author Steve Ebersole
    */
    public class EnversIllustrationTest extends TestCase {
    private EntityManagerFactory entityManagerFactory;

    @Override
    protected void setUp() throws Exception {
    // like discussed with regards to SessionFactory, an EntityManagerFactory is set up once for an application
    // IMPORTANT: notice how the name here matches the name we gave the persistence-unit in persistence.xml!
    entityManagerFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.envers" );
    }

    @Override
    protected void tearDown() throws Exception {
    entityManagerFactory.close();
    }

    public void testBasicUsage() {
    // create a couple of events
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    entityManager.getTransaction().begin();
    entityManager.persist( new Event( "Our very first event!", new Date() ) );
    entityManager.persist( new Event( "A follow up event", new Date() ) );
    entityManager.getTransaction().commit();
    entityManager.close();

    // now lets pull events from the database and list them
    entityManager = entityManagerFactory.createEntityManager();
    entityManager.getTransaction().begin();
           List<Event> result = entityManager.createQuery( "from Event", Event.class ).getResultList(); for ( Event event : result ) { System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() ); }        entityManager.getTransaction().commit();        entityManager.close();​ // so far the code is the same as we have seen in previous tutorials. Now lets leverage Envers...​ // first lets create some revisions entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Event myEvent = entityManager.find( Event.class, 2L ); // we are using the increment generator, so we know 2 is a valid id myEvent.setDate( new Date() ); myEvent.setTitle( myEvent.getTitle() + " (rescheduled)" );        entityManager.getTransaction().commit();        entityManager.close();​ // and then use an AuditReader to look back through history entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); myEvent = entityManager.find( Event.class, 2L ); assertEquals( "A follow up event (rescheduled)", myEvent.getTitle() ); AuditReader reader = AuditReaderFactory.get( entityManager ); Event firstRevision = reader.find( Event.class, 2L, 1 ); assertFalse( firstRevision.getTitle().equals( myEvent.getTitle() ) ); assertFalse( firstRevision.getDate().equals( myEvent.getDate() ) ); Event secondRevision = reader.find( Event.class, 2L, 2 ); assertTrue( secondRevision.getTitle().equals( myEvent.getTitle() ) ); assertTrue( secondRevision.getDate().equals( myEvent.getDate() ) ); entityManager.getTransaction().commit();        entityManager.close(); }}
  5. 运行测试

Hibernate 5 入门指南-基于Envers的更多相关文章

  1. Hibernate 5 入门指南-基于映射文件

    由于Hibernate 4版本混乱,Hibernate 3有些过时,Hibernate 5的开发文档尚不完善,所以构建一份简单的Hibernate 5的入门指南 注:案例参考Hibernate 官方参 ...

  2. Hibernate 5 入门指南-基于JPA

    首先创建\META-INF\persistence.xml配置文件并做简单的配置 <persistence xmlns="http://java.sun.com/xml/ns/pers ...

  3. Hibernate 5 入门指南-基于类注解

    首先创建hibernate.cfg.xml配置文件并做简单的配置 <hibernate-configuration>    <session-factory>        & ...

  4. 张高兴的 .NET IoT 入门指南:(八)基于 GPS 的 NTP 时间同步服务器

    时间究竟是什么?这既可以是一个哲学问题,也可以是一个物理问题.古人对太阳进行观测,利用太阳的投影发明了日晷,定义了最初的时间.随着科技的发展,天文观测的精度也越来越准确,人们发现地球的自转并不是完全一 ...

  5. Vue.js 入门指南之“前传”(含sublime text 3 配置)

    题记:关注Vue.js 很久了,但就是没有动手写过一行代码,今天准备入手,却发现自己比菜鸟还菜,于是四方寻找大牛指点,才终于找到了入门的“入门”,就算是“入门指南”的“前传”吧.此文献给跟我一样“白痴 ...

  6. 【翻译】Fluent NHibernate介绍和入门指南

    英文原文地址:https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started 翻译原文地址:http://www.cnblogs ...

  7. Flume NG Getting Started(Flume NG 新手入门指南)

    Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...

  8. ReactJS入门指南

    ReactJS入门指南 本文旨在介绍ReactJS的基本知识,并一步步详细介绍React的基本概念和使用方法等,以及相应的Demo.本文在很大程度上参考了React官方文档和官方指南.如果你英语还不错 ...

  9. Webpack 入门指南 - 1.安装

    Webpack 是目前流行的打包工具,如何安装它呢? 1. 安装 Node Js 首先,Webpack 是基于 NodeJs 的工具,你必须首先安装 NodeJs. NodeJs 仅仅只需要在你的系统 ...

随机推荐

  1. Spring基础系列-容器启动流程(2)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9503210.html 一.概述 这里是Springboot项目启动大概流程,区别于SSM ...

  2. Java——static关键字

    前言 static关键字算是Java中比较复杂的关键字之一,它可以修饰变量.方法.类以及代码块.下面将介绍static的具体使用. static引入的目的 static的作用 static修饰变量 s ...

  3. You must reset your password using ALTER USER statement before executing this statement.

    MySQL 5.7之后,刚初始化的MySQL实例要求先修改密码.否则会报错: mysql> create database test; ERROR 1820 (HY000): You must ...

  4. backbond整体架构

    (function(factory) { // 在这里是backbone模块化的一个接口.支持AMD,CMD和全局变量模式.代码很好理解. })(function(root, factory, _, ...

  5. 跨域 webpack + vue-cil 中 proxyTable 处理跨域

    博客地址:https://ainyi.com/27 跨域 了解同源政策:所谓"同源"指的是"三个相同". 协议相同 域名相同 端口相同 解决跨域 jsonp 缺 ...

  6. RNN入门(一)识别MNIST数据集

    RNN介绍   在读本文之前,读者应该对全连接神经网络(Fully Connected Neural Network, FCNN)和卷积神经网络( Convolutional Neural Netwo ...

  7. Spring Boot入门(11)实现文件下载功能

      在这篇博客中,我们将展示如何在Spring Boot中实现文件的下载功能.   还是遵循笔者写博客的一贯风格,简单又不失详细,实用又能让你学会.   本次建立的Spring Boot项目的主要功能 ...

  8. C# 可访问性不一致问题(修改成员的访问修饰符)。

    错误实例一:父类的访问性低于子类 class Person { } public class Students:Person { } 错误实例二:方法的访问修饰符需要和参数的类型的访问修饰符一致 cl ...

  9. 6.7 使用show profile 进行sql分析

    1. 查看是否开启 show variables like 'profiling'; 2. 开启功能 set profiling = on 3. 运行sql #写的尽量耗时的sql,利于分析 sele ...

  10. Stackoverflow每日问题 系列前言

    都是程序员,想必都对stackoverflow有一定的了解,这个网站是世界上最为活跃的编程知识的论坛网站,上面活跃着数以万计的大神.提问各种有意义有价值的问题,还有这些问题的详细的回答. 但是毕竟是国 ...