Reladomo ist ein Java ORM-Framework, das von Goldman Sachs als OSS veröffentlicht wurde. Ich mag es, weil es eine charakteristische Funktion hat, die es einfach macht, den Änderungsverlauf in RDBMS zu verwalten.
In Reladomo können Java und DDL durch Definieren der Entität in XML generiert werden. Durch Nutzung der generierten API können Sie CRUD-Operationen für die entsprechenden Tabellen ausführen.
Dieses Mal werde ich kurz auf die grundlegenden Operationen von Reladomo, die Arten von Datenmodellen usw. eingehen.
Zu diesem Zeitpunkt ist es in Bezug auf das bitemporale Datenmodell (später beschrieben) einfacher zu verstehen, wenn man das tatsächliche Verhalten betrachtet. Ich möchte einen Blick auf eine Beispiel-REST-API in Kombination mit Spring Boot werfen. https://github.com/amtkxa/spring-boot-reladomo
Um den Änderungsverlauf der Daten verfolgen zu können, müssen die Verlaufsdaten gespeichert werden. Zeit, die eine Bedeutung hat, sollte zusammen gespart werden.
Transaction Time, Vaild Time
Reladomo macht es einfach, zwei Mal zu verwalten, um den Datenänderungsverlauf zu verfolgen.
Die folgenden vier Datenmodelle können berücksichtigt werden, je nachdem, ob Transaktionszeit und Vaild-Zeit verwendet werden oder nicht. Reladomo bietet Ihnen auch die Flexibilität, ein Datenmodell nach Entität auszuwählen.
Datenmodell | Erläuterung |
---|---|
Snapshot-Datenmodell | Es wird keine Zeitdimension unterstützt (keine Verlaufsverwaltung) |
Transaktionszeitdatenmodell | Es wird nur die Transaktionszeit unterstützt |
Gültiges Zeitdatenmodell | Nur gültige Zeit unterstützt |
Bitemporales Datenmodell | Unterstützt sowohl Vaild Time als auch Transaction Time |
Lassen Sie uns zunächst das Transaktionszeitdatenmodell behandeln und die grundlegende Verwendung von Reladomo ansprechen.
Da der Zweck darin besteht, die Funktion von Reladomo zu bestätigen, haben wir ein einfaches Domänenmodell erstellt, das möglich zu sein scheint.
Erstellen Sie zunächst eine XML-Datei, die die Objekte definiert, die den Tabellen in Ihrer Datenbank entsprechen.
Account.xml
<MithraObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
objectType="transactional"
xsi:noNamespaceSchemaLocation="../config/mithraobject.xsd">
<PackageName>com.amtkxa.springbootreladomosimple.domain.entity</PackageName>
<ClassName>Account</ClassName>
<DefaultTable>ACCOUNT</DefaultTable>
<AsOfAttribute name="processingDate" fromColumnName="PROCESSING_DATE_FROM" toColumnName="PROCESSING_DATE_TO"
toIsInclusive="false"
isProcessingDate="true"
infinityDate="[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]"
defaultIfNotSpecified="[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]"
/>
<Attribute name="accountId" javaType="int" columnName="ACCOUNT_ID" primaryKey="true"
primaryKeyGeneratorStrategy="SimulatedSequence">
<SimulatedSequence sequenceName="Account"
sequenceObjectFactoryName="com.amtkxa.springbootreladomosimple.infrastructure.util.ObjectSequenceObjectFactory"
hasSourceAttribute="false"
batchSize="1"
initialValue="1"
incrementSize="1"/>
</Attribute>
<Attribute name="customerId" javaType="int" columnName="CUSTOMER_ID" nullable="false"/>
<Attribute name="balance" javaType="double" columnName="BALANCE"/>
</MithraObject>
Eine kurze Beschreibung jedes Attributs lautet wie folgt.
Element | Erläuterung |
---|---|
PackageName | Das Paket, zu dem das generierte Objekt gehört. |
ClassName | Der Klassenname des Objekts. |
DefaultTable | Die Tabelle, der das Objekt entspricht. |
Attribute | Objektattribute. Entspricht den in DefaultTable definierten Spalten der Tabelle. |
AsOfAttribute | Es entspricht der Spalte für die Verlaufsverwaltung, und der Zeitraum wird durch zwei Spalten von von bis bis dargestellt. |
SimulatedSequence | Sequenzwert, der zum Zeitpunkt von INSERT automatisch nummeriert wird. |
Sie können auch auf mithraobject.xsd
verweisen, um weitere Informationen zu den hier festgelegten Einstellungen zu erhalten.
Aus der zuvor definierten XML-Datei können Sie eine Java-Datei für das entsprechende Objekt generieren.
MithraClassList.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Mithra xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/mithraobject.xsd">
<MithraObjectResource name="ObjectSequence"/>
<MithraObjectResource name="Customer"/>
<MithraObjectResource name="Account"/>
<MithraObjectResource name="Transaction"/>
</Mithra>
Definieren Sie die Aufgabe "gen-reladomo" in "pom.xml". Diese Ant-Task verwendet den MithraGenerator
, um eine Java-Datei basierend auf der``MithraClassList.xml`-Datei zu generieren.
pom.xml
<tasks>
<property name="plugin_classpath" refid="maven.plugin.classpath"/>
<taskdef name="gen-reladomo" classpath="plugin_classpath"
classname="com.gs.fw.common.mithra.generator.MithraGenerator"/>
<gen-reladomo
xml="${project.basedir}/src/main/resources/reladomo/model/MithraClassList.xml"
generateGscListMethod="true"
generatedDir="${project.build.directory}/generated-sources/reladomo"
nonGeneratedDir="${project.basedir}/src/main/java"
/>
</tasks>
Hier werden zwei Ausgabeziele durch "generateDir" und "nonGeneratedDir" definiert.
generatedDir
nonGeneratedDir
Die Task "gen-reladomo" generiert eine Java-Datei, z. B. durch Ausführen von "mvn clean install".
generateDir
generiert eine abstrakte Klasse, die jedes Mal neu erstellt wird, um XML-Änderungen zu folgen, und nonGeneratedDir
erstellt eine konkrete Klasse, in der der Benutzer seine eigene Geschäftslogik hinzufügt. Die generierten Klassen und Abhängigkeiten sind wie folgt.
Die hier generierte abstrakte Klasse enthält den größten Teil des Codes, der zum Ausführen von CRUD-Operationen für eine Entität erforderlich ist.
Sie können DDL für von Reladomo unterstützte Datenbanken generieren. DDL scheint Tabellen, Indizes und externe Schlüssel zu unterstützen.
Definieren Sie die Aufgabe "gen-reladomo-db" in "pom.xml". Diese Ant-Task verwendet den MithraDbDefinitionGenerator
, um eine DDL basierend auf der MithraClassList.xml
-Datei zu generieren.
pom.xml
<tasks>
<property name="plugin_classpath" refid="maven.plugin.classpath"/>
<taskdef name="gen-reladomo-db" classpath="plugin_classpath"
classname="com.gs.fw.common.mithra.generator.dbgenerator.MithraDbDefinitionGenerator"/>
<gen-reladomo-db
xml="${project.basedir}/src/main/resources/reladomo/model/MithraClassList.xml"
generatedDir="${project.build.directory}/generated-resources/db"
databaseType="postgres"/>
</tasks>
Die Task "gen-reladomo-db" generiert eine DDL, z. B. durch Ausführen von "mvn clean install". Die DDL, die generiert wurde, als "postgres" auf "databaseType" gesetzt wurde, hatte den folgenden Inhalt.
target/generated-resources/db/ACCOUNT.ddl
drop table if exists ACCOUNT;
create table ACCOUNT
(
ACCOUNT_ID int not null,
CUSTOMER_ID int not null,
BALANCE float8,
PROCESSING_DATE_FROM timestamp not null,
PROCESSING_DATE_TO timestamp not null
);
target/generated-resources/db/ACCOUNT.idx
alter table ACCOUNT add constraint ACCOUNT_PK primary key (ACCOUNT_ID, PROCESSING_DATE_TO);
drop index if exists ACCOUNT_IDX0;
create index ACCOUNT_IDX0 on ACCOUNT(CUSTOMER_ID, PROCESSING_DATE_TO);
Bei der Verwaltung des Verlaufs mit Reladomo wird anscheinend keine Fremdschlüssel-DDL aus dem entsprechenden XML generiert. Übrigens scheint es, dass die hier generierte DDL nicht so verwendet wird, wie sie ist, sondern darauf basierend angepasst werden soll.
The DDLs generated by Reladomo are not meant to be used as is. They are merely meant to be a starting point for further customization. There are two common reasons to customize the generated DDLs. One is to add database specific clauses for specifying table spaces, schemas etc. Another is to add additional indices based on usage patterns seen in the application. Guided Tour Of Reladomo - 2.3. Database DDL Generation
Ich bin dankbar für die DDL-Generierungsfunktion.
CRUD (Create)
Fügen Sie der von Reladomo generierten konkreten Klasse den folgenden Konstruktor hinzu.
Account.java
public Account(int customerId, double balance) {
this(com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity());
this.setCustomerId(customerId);
this.setBalance(balance);
}
Versuchen Sie dann, den folgenden Code auszuführen.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
Account account = new Account(1, 100);
account.insert();
return null;
});
Anschließend wurde der Datensatz in der Tabelle ACCOUNT der Verbindungsziel-DB registriert.
testdb=> select * from account;
account_id | customer_id | balance | processing_date_from | processing_date_to
------------+-------------+---------+------------------------+---------------------
1 | 1 | 100 | 2018-12-23 14:42:14.61 | 9999-12-01 23:59:00
Da der nummerierte Sequenzwert auf "account_id" gesetzt ist, für den kein Wert gesetzt ist, wird er dort ergänzt. Wenn Sie Folgendes in die entsprechende Spalte von Account.xml eingeben, die zuvor definiert wurde, können Sie den Sequenzwert nummerieren.
Account.xml
<Attribute name="accountId" javaType="int" columnName="ACCOUNT_ID" primaryKey="true"
primaryKeyGeneratorStrategy="SimulatedSequence">
<SimulatedSequence sequenceName="Account"
sequenceObjectFactoryName="com.amtkxa.springbootreladomosimple.infrastructure.util.ObjectSequenceObjectFactory"
hasSourceAttribute="false"
batchSize="1"
initialValue="1"
incrementSize="1"/>
</Attribute>
Die in "Account.xml" angegebene "ObjectSequenceObjectFactory" wird separat erstellt.
ObjectSequenceObjectFactory.java
public class ObjectSequenceObjectFactory implements MithraSequenceObjectFactory {
public MithraSequence getMithraSequenceObject(String sequenceName, Object sourceAttribute, int initialValue) {
ObjectSequence objectSequence = ObjectSequenceFinder.findByPrimaryKey(sequenceName);
if (objectSequence == null) {
objectSequence = new ObjectSequence();
objectSequence.setSimulatedSequenceName(sequenceName);
objectSequence.setNextValue(initialValue);
objectSequence.insert();
}
return objectSequence;
}
}
Die zu nummerierenden Werte werden in der Tabelle OBJECT_SEQUENCE verwaltet, die auch die Metadaten in XML definiert.
ObjectSequence.xml
<MithraObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
objectType="transactional"
xsi:noNamespaceSchemaLocation="../config/mithraobject.xsd">
<PackageName>com.amtkxa.springbootreladomosimple.domain.entity</PackageName>
<ClassName>ObjectSequence</ClassName>
<DefaultTable>OBJECT_SEQUENCE</DefaultTable>
<Attribute name="simulatedSequenceName" javaType="String" columnName="SEQUENCE_NAME" primaryKey="true" maxLength="64"/>
<Attribute name="nextValue" javaType="long" columnName="NEXT_VALUE"/>
</MithraObject>
testdb=> select * from object_sequence;
sequence_name | next_value
---------------+------------
Account | 2
Sie können auch mehrere Datensätze registrieren, indem Sie die von Reladomo generierte "AccountList" verwenden.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
AccountList accountList = new AccountList();
accountList.add(new Account(2, 200));
accountList.add(new Account(3, 300));
accountList.insertAll();
return null;
});
Als ich diesen Code ausführte, wurden mehrere Datensätze registriert.
testdb=> select * from account where customer_id in (2, 3);
account_id | customer_id | balance | processing_date_from | processing_date_to
------------+-------------+---------+------------------------+---------------------
2 | 2 | 200 | 2018-12-23 15:10:37.92 | 9999-12-01 23:59:00
3 | 3 | 300 | 2018-12-23 15:10:37.92 | 9999-12-01 23:59:00
CRUD (Read)
Der Suchvorgang verwendet die von Reladomo generierte Finder-Klasse.
Sie können eine Instanz der Klasse "Operation" mithilfe der Klasse "Finder" erstellen. Die Klasse "Operation" kann den Teil der ausgegebenen Abfrage festlegen, der die WHERE-Klausel sein wird.
Lassen Sie mich einige Beispiele geben.
// where NAME = 'tanaka'
Operation op1 = CustomerFinder.name().eq("tanaka");
// where NAME <> 'tanaka'
Operation op2 = CustomerFinder.name().notEq("tanaka");
// where NAME like 'tanaka%'
Operation op3 = CustomerFinder.name().startsWith("tanaka");
// where NAME like '%taro'
Operation op4 = CustomerFinder.name().endsWith("taro");
// where NAME like '%tanaka%'
Operation op5 = CustomerFinder.name().wildCardEq("*tanaka*");
// where CUSTOMER_ID < 3
Operation op6 = CustomerFinder.customerId().lessThan(3);
Zusätzlich zu den hier aufgeführten gibt es auch "isNull" und "enthält".
Sie können Operation
s auch wie folgt verketten:
// where NAME like '%tanaka%' and CUSTOMER_ID < 3
Operation op = op5.and(op6);
Sie können einen einzelnen Datensatz erhalten, indem Sie "findOne" der Klasse "Finder" verwenden.
// select t0.ACCOUNT_ID,t0.CUSTOMER_ID,t0.BALANCE,t0.PROCESSING_DATE_FROM,t0.PROCESSING_DATE_TO from ACCOUNT t0
// where t0.ACCOUNT_ID = 1 and t0.PROCESSING_DATE_TO = '9999-12-01 23:59:00.000'
Account account = AccountFinder.findOne(AccountFinder.accountId().eq(1));
Die Bedingung der tatsächlich ausgegebenen Abfrage lautet "t0.PROCESSING_DATE_TO =" 9999-12-01 23: 59: 00.000 "und bezieht sich auf den Datensatz, der dem neuesten Verlauf entspricht.
Wenn Sie findMany
der Finder
-Klasse verwenden, können Sie mehrere Datensätze in List abrufen.
// select t0.CUSTOMER_ID,t0.NAME,t0.COUNTRY,t0.PROCESSING_DATE_FROM,t0.PROCESSING_DATE_TO from CUSTOMER t0
// where t0.NAME like 'tanaka%' and t0.PROCESSING_DATE_TO = '9999-12-01 23:59:00.000'
CustomerList customerList = CustomerFinder.findMany(CustomerFinder.name().startsWith("tanaka"));
CRUD (Update)
Wenn Sie Änderungen an einem Objekt vornehmen, das mit der Klasse "Finder" abgerufen wurde, werden die Änderungen auch in der DB-Tabelle angezeigt. Ich habe die folgenden Daten vorbereitet, um das Verhalten zu überprüfen.
testdb=> select * from customer where customer_id = 7;
customer_id | name | country | processing_date_from | processing_date_to
-------------+---------+---------+------------------------+---------------------
7 | Pikachu | Japan | 2018-12-23 19:36:07.06 | 9999-12-01 23:59:00
Pikachu wechselt zu Raichu. Angenommen, der folgende Code wird ausgeführt, um die Änderungen vorzunehmen.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
Customer customer = CustomerFinder.findOne(CustomerFinder.customerId().eq(7));
customer.setName("Raichu");
return null;
});
Das Ausführungsergebnis ist wie folgt.
testdb=> select * from customer where customer_id = 7;
customer_id | name | country | processing_date_from | processing_date_to
-------------+---------+---------+------------------------+------------------------
7 | Pikachu | Japan | 2018-12-23 19:36:07.06 | 2018-12-23 19:46:13.91
7 | Raichu | Japan | 2018-12-23 19:46:13.91 | 9999-12-01 23:59:00
Die tatsächlich ausgegebene Abfrage lautet wie folgt.
--Holen Sie sich die neuesten Verlaufsdaten
select t0.CUSTOMER_ID,t0.NAME,t0.COUNTRY,t0.PROCESSING_DATE_FROM,t0.PROCESSING_DATE_TO from CUSTOMER t0
where t0.CUSTOMER_ID = 7 and t0.PROCESSING_DATE_TO = '9999-12-01 23:59:00.000' FOR SHARE OF t0;
--Aktualisieren Sie den Gültigkeitszeitraum der neuesten Verlaufsdaten
update CUSTOMER set PROCESSING_DATE_TO = '2018-12-23 19:46:13.910'
where CUSTOMER_ID = 7 AND PROCESSING_DATE_TO = '9999-12-01 23:59:00.000';
--Registrieren Sie die geänderten Daten als neuesten Verlauf
insert into CUSTOMER(CUSTOMER_ID,NAME,COUNTRY,PROCESSING_DATE_FROM,PROCESSING_DATE_TO)
values (7,'Raichu','Japan','2018-12-23 19:46:13.910','9999-12-01 23:59:00.000');
CRUD (Delete)
Dies kann in der Tabelle wiedergegeben werden, indem das mit der Finder-Klasse erhaltene Objekt gelöscht wird. In diesem Fall ist das Verhalten für "delete ()", "terminate ()" und "purge ()" unterschiedlich. Verschieben wir es also einfach.
delete()
delete ()
kann für Objekte verwendet werden, die Reladomo nicht im Verlauf verwaltet (abhängig davon, ob XML über AsOfAttribute
verfügt).
Dadurch wird der Datensatz physisch aus der Tabelle gelöscht.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
Transaction transaction = TransactionFinder.findOne(TransactionFinder.transactionId().eq(4));
transaction.delete();
return null;
});
Die tatsächlich ausgeführte Abfrage lautet wie folgt.
select t0.LOG_ID,t0.ACCOUNT_ID,t0.TRANSACTION_TYPE,t0.AMOUNT,t0.TRANSACTION_DATE from TRANSACTION t0
where t0.LOG_ID = 4 FOR SHARE OF t0;
delete from TRANSACTION where LOG_ID = 4;
terminate()
terminate ()
beendet den Verlauf von Objekten, die von Reladomo verwaltet werden. (Aufzeichnung als Geschichte bleibt)
Die folgenden Daten wurden vorbereitet, um das Verhalten zu überprüfen.
testdb=> select * from customer where customer_id = 7;
customer_id | name | country | processing_date_from | processing_date_to
-------------+---------+---------+------------------------+------------------------
7 | Pikachu | Japan | 2018-12-23 19:36:07.06 | 2018-12-23 19:46:13.91
7 | Raichu | Japan | 2018-12-23 19:46:13.91 | 9999-12-01 23:59:00
Führen Sie als Antwort diesen Code aus.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
Customer customer = CustomerFinder.findOne(CustomerFinder.customerId().eq(7));
customer.terminate();
return null;
});
Dann wird das als "9999-12-01 23: 59: 00" in "process_date_to" registrierte Teil aktualisiert.
testdb=> select * from customer where customer_id = 7;
customer_id | name | country | processing_date_from | processing_date_to
-------------+---------+---------+------------------------+------------------------
7 | Pikachu | Japan | 2018-12-23 19:36:07.06 | 2018-12-23 19:46:13.91
7 | Raichu | Japan | 2018-12-23 19:46:13.91 | 2018-12-23 22:10:36.68
Die tatsächlich ausgeführte Abfrage lautet wie folgt.
select t0.CUSTOMER_ID,t0.NAME,t0.COUNTRY,t0.PROCESSING_DATE_FROM,t0.PROCESSING_DATE_TO from CUSTOMER t0
where t0.CUSTOMER_ID = 7 and t0.PROCESSING_DATE_TO = '9999-12-01 23:59:00.000' FOR SHARE OF t0;
update CUSTOMER set PROCESSING_DATE_TO = '2018-12-23 22:10:36.680'
where CUSTOMER_ID = 7 AND PROCESSING_DATE_TO = '9999-12-01 23:59:00.000';
purge()
purge ()
löscht den Verlauf des von Reladomo verwalteten Objekts.
MithraManagerProvider.getMithraManager().executeTransactionalCommand((tx) -> {
Customer customer = CustomerFinder.findOne(CustomerFinder.customerId().eq(6));
customer.purge();
return null;
});
Die tatsächlich ausgeführte Abfrage lautet wie folgt.
select t0.CUSTOMER_ID,t0.NAME,t0.COUNTRY,t0.PROCESSING_DATE_FROM,t0.PROCESSING_DATE_TO from CUSTOMER t0
where t0.CUSTOMER_ID = 6 and t0.PROCESSING_DATE_TO = '9999-12-01 23:59:00.000' FOR SHARE OF t0;
delete from CUSTOMER where CUSTOMER_ID = 6;
Verwenden Sie eine Beispiel-REST-API, die mit einem bitemporalen Datenmodell in Kombination mit Spring Boot funktioniert. https://github.com/amtkxa/spring-boot-reladomo
Die Transaktionszeit und die Vaild-Zeit, die im bitemporalen Datenmodell verarbeitet werden, haben häufig das gleiche Timing. Hier werden wir jedoch den Fall verfolgen, in dem Sie den Vorteil der gleichzeitigen Verwaltung der beiden sehen können.
Ich habe bereits die grundlegende Verwendung von Reladomo erwähnt, daher werde ich die Teile vorstellen, die nicht viel behandelt werden.
Der allererste Verlaufsdatensatz wurde registriert.
sampledb=> select * from account where account_id = 10;
account_id | customer_id | balance | business_date_from | business_date_to | processing_date_from | processing_date_to
------------+-------------+---------+---------------------+---------------------+------------------------+---------------------
12 | 1 | 10000 | 2019-01-01 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:17:17.49 | 9999-12-01 23:59:00
Angenommen, Sie könnten aufgrund von Problemen keine Einzahlung vornehmen. Daher ändert sich der Tabelleninhalt nicht.
Die Geschichte wurde aufgrund der Einzahlung von 20000 Yen gekürzt.
sampledb=> select * from account where account_id = 12 order by 4, 6;
account_id | customer_id | balance | business_date_from | business_date_to | processing_date_from | processing_date_to
------------+-------------+---------+---------------------+---------------------+------------------------+------------------------
12 | 1 | 10000 | 2019-01-01 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:33:09.54 | 2018-12-22 16:38:27.48
12 | 1 | 10000 | 2019-01-01 00:00:00 | 2019-01-20 00:00:00 | 2018-12-22 16:38:27.48 | 9999-12-01 23:59:00
12 | 1 | 30000 | 2019-01-20 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:38:27.48 | 9999-12-01 23:59:00
Angenommen, der am 17. Januar eingezahlte Geldbetrag wurde am 25. Januar geändert. Wenn Sie in diesem Fall "incrementBalance ()" verwenden, um das Objekt zu aktualisieren, das durch Angabe des 17. Januar für business_date erfasst wurde, wird die entsprechende Tabelle auf den folgenden Inhalt aktualisiert.
sampledb=> select * from account where account_id = 12 order by 6, 4;
account_id | customer_id | balance | business_date_from | business_date_to | processing_date_from | processing_date_to
------------+-------------+---------+---------------------+---------------------+------------------------+------------------------
12 | 1 | 10000 | 2019-01-01 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:33:09.54 | 2018-12-22 16:38:27.48
12 | 1 | 10000 | 2019-01-01 00:00:00 | 2019-01-20 00:00:00 | 2018-12-22 16:38:27.48 | 2018-12-22 16:45:31.94
12 | 1 | 30000 | 2019-01-20 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:38:27.48 | 2018-12-22 16:45:31.94
12 | 1 | 10000 | 2019-01-01 00:00:00 | 2019-01-17 00:00:00 | 2018-12-22 16:45:31.94 | 9999-12-01 23:59:00
12 | 1 | 15000 | 2019-01-17 00:00:00 | 2019-01-20 00:00:00 | 2018-12-22 16:45:31.94 | 9999-12-01 23:59:00
12 | 1 | 35000 | 2019-01-20 00:00:00 | 9999-12-01 23:59:00 | 2018-12-22 16:45:31.94 | 9999-12-01 23:59:00
Wir konnten bestätigen, dass der Saldo der zu ändernden historischen Daten aktualisiert werden konnte, während die historischen Daten vor der Änderung beibehalten wurden.
Nachdem ich Reladomo tatsächlich verwendet hatte, wurde mir klar, dass die Verwaltung des Datenverlaufs einfach zu realisieren ist. Insbesondere in Fällen, in denen Sie den Änderungsverlauf später für Audits usw. verfolgen möchten, können Sie anscheinend eine Verbesserung der Entwicklungseffizienz erwarten. Dies kann in vielen Situationen nützlich sein, wenn Sie mit der JVM-Sprache entwickeln.
Auswahl der Cache-Strategie für jede Entität, Multi-Threaded Matcher Loader (MTLoader) usw. Ich interessiere mich besonders für die Hochleistungsfunktionen von Reladomo Das möchte ich auch zu einem anderen Zeitpunkt untersuchen.
Als ich diesmal nachschlug, hatte ich das Gefühl, dass es viele englische Dokumente gab, aber alle waren von hoher Qualität.
Es gibt auch sehr leicht verständliche japanische Materialien, was sehr hilfreich war.
Recommended Posts