PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

जेपीए और हाइबरनेट का उपयोग करके 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)
)

जेपीए इकाई

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
}

घटना श्रोताओं को हाइबरनेट करें

अब, हमें post के लिए INSERT, UPDATE, और DELETE संचालन को रोकने के लिए 3 ईवेंट श्रोताओं को पंजीकृत करना होगा इकाई।

हम इसे निम्नलिखित ईवेंट श्रोताओं के माध्यम से कर सकते हैं:

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;
    }
}

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) {

    }
}

और, हाइबरनेट को इस कस्टम 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);

हाइबरनेट निम्नलिखित 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);

हाइबरनेट सभी क्रियाओं को 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)]

पर उपलब्ध कोड ।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JSON प्रकार के अंदर सरणी तत्वों के लिए क्वेरी

  2. डेटा को सॉर्ट न करें कैसे रखें?

  3. त्रुटि:Postgres . में एक से अधिक स्वामित्व वाले अनुक्रम पाए गए

  4. वर्चर फ़ील्ड के प्रकार को पूर्णांक में बदलें:पूर्णांक टाइप करने के लिए स्वचालित रूप से कास्ट नहीं किया जा सकता

  5. Postgresql - बड़े डेटाबेस में सरणी का उपयोग करने का प्रदर्शन