initial
This commit is contained in:
commit
6b23c32c6d
29
pom.xml
Normal file
29
pom.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>DataMigration_Selfmade</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>2.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
75
src/main/java/Main.java
Normal file
75
src/main/java/Main.java
Normal file
@ -0,0 +1,75 @@
|
||||
import data.source.PersonSource;
|
||||
import data.target.PersonTarget;
|
||||
import etl.Extractor;
|
||||
import etl.Loader;
|
||||
import etl.Transformer;
|
||||
import utils.*;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.time.Period;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main
|
||||
{
|
||||
public static void main(final String[] args) throws SQLException
|
||||
{
|
||||
// mysqlDb();
|
||||
// postgresqlDb();
|
||||
// mariaDb();
|
||||
|
||||
var p = testExtract();
|
||||
var pt = testTransform(p);
|
||||
testLoad(pt);
|
||||
}
|
||||
|
||||
private static List<PersonSource> testExtract() throws SQLException
|
||||
{
|
||||
final var dbInfo = new DatabaseInformation("localhost", "sourcedb1", "test", "test", 5435);
|
||||
final var connection = new ConnectionHelper(DatabaseType.MARIADB, dbInfo).createConnection();
|
||||
|
||||
DataStorer<PersonSource> personSourceDataStorer = (rs) -> {
|
||||
var persons = new ArrayList<PersonSource>();
|
||||
while (rs.next())
|
||||
{
|
||||
persons.add(new PersonSource(rs.getInt("personId"),
|
||||
rs.getString("name"),
|
||||
rs.getBoolean("mortal")));
|
||||
}
|
||||
return persons;
|
||||
};
|
||||
|
||||
var sql = "select * from person;";
|
||||
|
||||
return new Extractor<>(connection, personSourceDataStorer, sql).doExtract();
|
||||
}
|
||||
|
||||
private static List<PersonTarget> testTransform(List<PersonSource> persons)
|
||||
{
|
||||
DataTransformer<PersonSource, PersonTarget> personTransformer = (personSource) -> {
|
||||
return new PersonTarget(personSource.getPersonId(),
|
||||
personSource.getName(),
|
||||
personSource.isMortal());
|
||||
};
|
||||
|
||||
return new Transformer<>(personTransformer, persons).doTransform();
|
||||
}
|
||||
|
||||
private static void testLoad(List<PersonTarget> transformedData)
|
||||
{
|
||||
final var dbInfo = new DatabaseInformation("localhost", "targetdb", "test", "test", 5432);
|
||||
final var connection = new ConnectionHelper(DatabaseType.POSTGRESQL, dbInfo).createConnection();
|
||||
|
||||
StatementPreparer<PersonTarget> statementPreparer = (preparedStatement, data) -> {
|
||||
preparedStatement.setInt(1, data.getPersonId());
|
||||
preparedStatement.setString(2, data.getName());
|
||||
preparedStatement.setBoolean(3, data.isMortal());
|
||||
};
|
||||
|
||||
var sql = "insert into person values (?, ?, ?)";
|
||||
|
||||
new Loader<>(connection, statementPreparer, transformedData, sql).doLoad();
|
||||
}
|
||||
}
|
5
src/main/java/data/Dataset.java
Normal file
5
src/main/java/data/Dataset.java
Normal file
@ -0,0 +1,5 @@
|
||||
package data;
|
||||
|
||||
public interface Dataset
|
||||
{
|
||||
}
|
38
src/main/java/data/source/PersonSource.java
Normal file
38
src/main/java/data/source/PersonSource.java
Normal file
@ -0,0 +1,38 @@
|
||||
package data.source;
|
||||
|
||||
import data.Dataset;
|
||||
|
||||
public class PersonSource implements Dataset
|
||||
{
|
||||
private int personId;
|
||||
private String name;
|
||||
private boolean mortal;
|
||||
|
||||
public PersonSource(int personId, String name, boolean mortal)
|
||||
{
|
||||
this.personId = personId;
|
||||
this.name = name;
|
||||
this.mortal = mortal;
|
||||
}
|
||||
|
||||
public int getPersonId()
|
||||
{
|
||||
return personId;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isMortal()
|
||||
{
|
||||
return mortal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Person { %d, %s, %s }", this.personId, this.name, this.mortal);
|
||||
}
|
||||
}
|
38
src/main/java/data/target/PersonTarget.java
Normal file
38
src/main/java/data/target/PersonTarget.java
Normal file
@ -0,0 +1,38 @@
|
||||
package data.target;
|
||||
|
||||
import data.Dataset;
|
||||
|
||||
public class PersonTarget implements Dataset
|
||||
{
|
||||
private int personId;
|
||||
private String name;
|
||||
private boolean mortal;
|
||||
|
||||
public PersonTarget(int personId, String name, boolean mortal)
|
||||
{
|
||||
this.personId = personId;
|
||||
this.name = name;
|
||||
this.mortal = mortal;
|
||||
}
|
||||
|
||||
public int getPersonId()
|
||||
{
|
||||
return personId;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isMortal()
|
||||
{
|
||||
return mortal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Person [ %d, %s, %s ]", this.personId, this.name, this.mortal);
|
||||
}
|
||||
}
|
43
src/main/java/etl/Extractor.java
Normal file
43
src/main/java/etl/Extractor.java
Normal file
@ -0,0 +1,43 @@
|
||||
package etl;
|
||||
|
||||
import data.Dataset;
|
||||
import utils.DataStorer;
|
||||
import utils.StatementPreparer;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class Extractor<T extends Dataset>
|
||||
{
|
||||
private Connection sourceDatabase;
|
||||
private DataStorer<T> dataStorer;
|
||||
private ResultSet resultSet;
|
||||
private String sql;
|
||||
|
||||
public Extractor(Connection sourceDatabase, DataStorer<T> dataStorer,
|
||||
String sql)
|
||||
{
|
||||
this.sourceDatabase = sourceDatabase;
|
||||
this.dataStorer = dataStorer;
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public List<T> doExtract()
|
||||
{
|
||||
try
|
||||
{
|
||||
var preparedStatement = this.sourceDatabase.prepareStatement(sql);
|
||||
this.resultSet = preparedStatement.executeQuery();
|
||||
this.sourceDatabase.close();
|
||||
return this.dataStorer.doStore(this.resultSet);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
44
src/main/java/etl/Loader.java
Normal file
44
src/main/java/etl/Loader.java
Normal file
@ -0,0 +1,44 @@
|
||||
package etl;
|
||||
|
||||
import data.Dataset;
|
||||
import utils.StatementPreparer;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class Loader<T extends Dataset>
|
||||
{
|
||||
private Connection targetDatabase;
|
||||
private StatementPreparer<T> statementPreparer;
|
||||
private List<T> transformedData;
|
||||
private String sql;
|
||||
|
||||
public Loader(Connection targetDatabase, StatementPreparer<T> statementPreparer, List<T> transformedData,
|
||||
String sql)
|
||||
{
|
||||
this.targetDatabase = targetDatabase;
|
||||
this.statementPreparer = statementPreparer;
|
||||
this.transformedData = transformedData;
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public void doLoad()
|
||||
{
|
||||
try
|
||||
{
|
||||
for (T transformedDatum : this.transformedData)
|
||||
{
|
||||
var preparedStatement = this.targetDatabase.prepareStatement(this.sql);
|
||||
this.statementPreparer.doPrepare(preparedStatement, transformedDatum);
|
||||
preparedStatement.executeUpdate();
|
||||
}
|
||||
|
||||
this.targetDatabase.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
30
src/main/java/etl/Transformer.java
Normal file
30
src/main/java/etl/Transformer.java
Normal file
@ -0,0 +1,30 @@
|
||||
package etl;
|
||||
|
||||
import data.Dataset;
|
||||
import utils.DataTransformer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Transformer<T extends Dataset, E extends Dataset>
|
||||
{
|
||||
|
||||
private DataTransformer<T, E> transformer;
|
||||
private List<T> datasets;
|
||||
|
||||
public Transformer(DataTransformer<T, E> transformer, List<T> datasets)
|
||||
{
|
||||
this.transformer = transformer;
|
||||
this.datasets = datasets;
|
||||
}
|
||||
|
||||
public List<E> doTransform()
|
||||
{
|
||||
var transformed = new ArrayList<E>();
|
||||
for (T dataset : this.datasets)
|
||||
{
|
||||
transformed.add(this.transformer.transform(dataset));
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
}
|
65
src/main/java/utils/ConnectionHelper.java
Normal file
65
src/main/java/utils/ConnectionHelper.java
Normal file
@ -0,0 +1,65 @@
|
||||
package utils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ConnectionHelper
|
||||
{
|
||||
private final DatabaseType databaseType;
|
||||
private final String user;
|
||||
private final String password;
|
||||
private URI uri;
|
||||
|
||||
public ConnectionHelper(final DatabaseType databaseType, final DatabaseInformation databaseInformation)
|
||||
{
|
||||
this.databaseType = databaseType;
|
||||
|
||||
try
|
||||
{
|
||||
this.uri = new URI(this.databaseType.getScheme(),
|
||||
null,
|
||||
databaseInformation.getHost(),
|
||||
databaseInformation.getPort(),
|
||||
String.format("/%s", databaseInformation.getDatabaseName()),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
catch (final URISyntaxException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.user = databaseInformation.getUser();
|
||||
this.password = databaseInformation.getPassword();
|
||||
}
|
||||
|
||||
public Connection createConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
Class.forName(this.databaseType.getDriver());
|
||||
}
|
||||
catch (final ClassNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Connection c = null;
|
||||
|
||||
try
|
||||
{
|
||||
c = DriverManager.getConnection(this.uri.toString(), this.user, this.password);
|
||||
}
|
||||
catch (final SQLException e)
|
||||
{
|
||||
System.out.println("SQLException: " + e.getMessage());
|
||||
System.out.println("SQLState: " + e.getSQLState());
|
||||
System.out.println("VendorError: " + e.getErrorCode());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
12
src/main/java/utils/DataStorer.java
Normal file
12
src/main/java/utils/DataStorer.java
Normal file
@ -0,0 +1,12 @@
|
||||
package utils;
|
||||
|
||||
import data.Dataset;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public interface DataStorer<T extends Dataset>
|
||||
{
|
||||
List<T> doStore(ResultSet resultSet) throws SQLException;
|
||||
}
|
10
src/main/java/utils/DataTransformer.java
Normal file
10
src/main/java/utils/DataTransformer.java
Normal file
@ -0,0 +1,10 @@
|
||||
package utils;
|
||||
|
||||
import data.Dataset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DataTransformer<T extends Dataset, E extends Dataset>
|
||||
{
|
||||
E transform(T dataset);
|
||||
}
|
5
src/main/java/utils/DatabaseHelper.java
Normal file
5
src/main/java/utils/DatabaseHelper.java
Normal file
@ -0,0 +1,5 @@
|
||||
package utils;
|
||||
|
||||
public class DatabaseHelper
|
||||
{
|
||||
}
|
51
src/main/java/utils/DatabaseInformation.java
Normal file
51
src/main/java/utils/DatabaseInformation.java
Normal file
@ -0,0 +1,51 @@
|
||||
package utils;
|
||||
|
||||
import com.mysql.cj.exceptions.NumberOutOfRange;
|
||||
|
||||
public class DatabaseInformation
|
||||
{
|
||||
private final String host;
|
||||
private final String databaseName;
|
||||
private final String user;
|
||||
private final String password;
|
||||
|
||||
private int port;
|
||||
|
||||
public DatabaseInformation(final String host, final String databaseName, final String user, final String password, final int port)
|
||||
{
|
||||
this.host = host;
|
||||
this.databaseName = databaseName;
|
||||
this.user = user;
|
||||
this.password = password;
|
||||
|
||||
if (port < 0 || port > 65535)
|
||||
throw new NumberOutOfRange("A port must be between 0 and 65535");
|
||||
else
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getHost()
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getDatabaseName()
|
||||
{
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
public String getUser()
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public int getPort()
|
||||
{
|
||||
return port;
|
||||
}
|
||||
}
|
27
src/main/java/utils/DatabaseType.java
Normal file
27
src/main/java/utils/DatabaseType.java
Normal file
@ -0,0 +1,27 @@
|
||||
package utils;
|
||||
|
||||
public enum DatabaseType
|
||||
{
|
||||
MARIADB("org.mariadb.jdbc.Driver", "jdbc:mariadb"),
|
||||
MYSQL("com.mysql.cj.jdbc.Driver", "jdbc:mysql"),
|
||||
POSTGRESQL("org.postgresql.Driver", "jdbc:postgresql");
|
||||
|
||||
private final String driver;
|
||||
private final String scheme;
|
||||
|
||||
DatabaseType(final String driver, final String scheme)
|
||||
{
|
||||
this.driver = driver;
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public String getDriver()
|
||||
{
|
||||
return driver;
|
||||
}
|
||||
|
||||
public String getScheme()
|
||||
{
|
||||
return scheme;
|
||||
}
|
||||
}
|
11
src/main/java/utils/StatementPreparer.java
Normal file
11
src/main/java/utils/StatementPreparer.java
Normal file
@ -0,0 +1,11 @@
|
||||
package utils;
|
||||
|
||||
import data.Dataset;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface StatementPreparer<T extends Dataset>
|
||||
{
|
||||
void doPrepare(PreparedStatement preparedStatement, T data) throws SQLException;
|
||||
}
|
Loading…
Reference in New Issue
Block a user