栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何使用JPA和Hibernate复制INSERT / UPDATE / DELETE语句

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何使用JPA和Hibernate复制INSERT / UPDATE / DELETE语句

由于这是一个非常常见的问题,因此我写了 这篇文章,此答案基于该文章。

数据库表

假设您有以下两个表:

CREATE TABLE old_post (    id int8 NOT NULL,    title varchar(255),    version int4 NOT NULL,    PRIMARY KEY (id))CREATE TABLE post (    id int8 NOT NULL,    created_on date,     title varchar(255),    version int4 NOT NULL,    PRIMARY KEY (id))

JPA实体

old_post
表必须与更新的表一起复制
post
。请注意,该
post
表现在具有比旧表更多的列。

我们只需要映射

Post
实体:

@Entity(name = "Post")@Table(name = "post")public static class Post {    @Id    private Long id;    private String title;    @Column(name = "created_on")    private LocalDate createdOn = LocalDate.now();    @Version    private int version;    //Getters and setters omitted for brevity}

hibernate事件监听器

现在,我们必须注册3个事件侦听器,以拦截

Post
实体的INSERT,UPDATe和DELETE操作。

我们可以通过以下事件监听器来做到这一点:

public class ReplicationInsertEventListener         implements PostInsertEventListener {    public static final ReplicationInsertEventListener INSTANCE =         new ReplicationInsertEventListener();    @Override    public void onPostInsert( PostInsertEvent event)  throws HibernateException {        final Object entity = event.getEntity();        if(entity instanceof Post) { Post post = (Post) entity; event.getSession().createNativeQuery(     "INSERT INTO old_post (id, title, version) " +     "VALUES (:id, :title, :version)") .setParameter("id", post.getId()) .setParameter("title", post.getTitle()) .setParameter("version", post.getVersion()) .setFlushMode(FlushMode.MANUAL) .executeUpdate();        }    }    @Override    public boolean requiresPostCommitHanding( EntityPersister persister) {        return false;    }}public class ReplicationUpdateEventListener     implements PostUpdateEventListener {    public static final ReplicationUpdateEventListener INSTANCE =         new ReplicationUpdateEventListener();    @Override    public void onPostUpdate( PostUpdateEvent event) {        final Object entity = event.getEntity();        if(entity instanceof Post) { Post post = (Post) entity; event.getSession().createNativeQuery(     "UPDATE old_post " +     "SET title = :title, version = :version " +     "WHERe id = :id") .setParameter("id", post.getId()) .setParameter("title", post.getTitle()) .setParameter("version", post.getVersion()) .setFlushMode(FlushMode.MANUAL) .executeUpdate();        }    }    @Override    public boolean requiresPostCommitHanding( EntityPersister persister) {        return false;    }}public class ReplicationDeleteEventListener         implements PreDeleteEventListener {    public static final ReplicationDeleteEventListener INSTANCE =         new ReplicationDeleteEventListener();    @Override    public boolean onPreDelete( PreDeleteEvent event) {        final Object entity = event.getEntity();        if(entity instanceof Post) { Post post = (Post) entity; event.getSession().createNativeQuery(     "DELETE FROM old_post " +     "WHERe id = :id") .setParameter("id", post.getId()) .setFlushMode(FlushMode.MANUAL) .executeUpdate();        }        return false;    }}

可以使用Hibernate注册3个事件侦听器

Integrator

public class ReplicationEventListenerIntegrator         implements Integrator {    public static final ReplicationEventListenerIntegrator INSTANCE =         new ReplicationEventListenerIntegrator();    @Override    public void integrate( metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {        final EventListenerRegistry eventListenerRegistry =     serviceRegistry.getService(EventListenerRegistry.class);        eventListenerRegistry.appendListeners( EventType.POST_INSERT,  ReplicationInsertEventListener.INSTANCE        );        eventListenerRegistry.appendListeners( EventType.POST_UPDATE,  ReplicationUpdateEventListener.INSTANCE        );        eventListenerRegistry.appendListeners( EventType.PRE_DELETE,  ReplicationDeleteEventListener.INSTANCE        );    }    @Override    public void disintegrate( SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {    }}

并且,要指示Hibernate使用此自定义

Integrator
,您需要设置
hibernate.integrator_provider
配置属性:

<property name="hibernate.integrator_provider"          value="com.vladmihalcea.book.hpjp.hibernate.listener.ReplicationEventListenerIntegrator "/>

测试时间

现在,当持久化

Post
实体时:

Post post1 = new Post();post1.setId(1L);post1.setTitle(    "The High-Performance Java Persistence book is to be released!");entityManager.persist(post1);

Hibernate将执行以下SQL INSERT语句:

Query:["INSERT INTO old_post (id, title, version) VALUES (?, ?, ?)"], Params:[(1, The High-Performance Java Persistence book is to be released!, 0)]Query:["insert into post (created_on, title, version, id) values (?, ?, ?, ?)"], Params:[(2018-12-12, The High-Performance Java Persistence book is to be released!, 0, 1)]

在执行另一项更新现有

Post
实体并创建新
Post
实体的事务时:

Post post1 = entityManager.find(Post.class, 1L);post1.setTitle(post1.getTitle().replace("to be ", ""));Post post2 = new Post();post2.setId(2L);post2.setTitle(    "The High-Performance Java Persistence book is awesome!");entityManager.persist(post2);

Hibernate还将所有操作复制到

old_post
表中:

 Query:["select tablerepli0_.id as id1_1_0_, tablerepli0_.created_on as created_2_1_0_, tablerepli0_.title as title3_1_0_, tablerepli0_.version as version4_1_0_ from post tablerepli0_ where tablerepli0_.id=?"], Params:[(1)] Query:["INSERT INTO old_post (id, title, version) VALUES (?, ?, ?)"], Params:[(2, The High-Performance Java Persistence book is awesome!, 0)] Query:["insert into post (created_on, title, version, id) values (?, ?, ?, ?)"], Params:[(2018-12-12, The High-Performance Java Persistence book is awesome!, 0, 2)] Query:["update post set created_on=?, title=?, version=? where id=? and version=?"], Params:[(2018-12-12, The High-Performance Java Persistence book is released!, 1, 1, 0)] Query:["UPDATE old_post SET title = ?, version = ? WHERe id = ?"], Params:[(The High-Performance Java Persistence book is released!, 1, 1)]

删除

Post
实体时:

Post post1 = entityManager.getReference(Post.class, 1L);entityManager.remove(post1);

old_post
记录也被删除:

Query:["DELETE FROM old_post WHERe id = ?"], Params:[(1)]Query:["delete from post where id=? and version=?"], Params:[(1, 1)]

有关更多详细信息,请查看本文。

代码可在GitHub上获得。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/387374.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号