diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 5588bcf..b1a2736 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,6 +1,5 @@
 name: 'Bug Report'
 description: 'Select if you want to report commons issue.'
-title: "[BUG] "
 labels: [ 'bug' ]
 body:
   - type: 'dropdown'
@@ -10,8 +9,9 @@ body:
       description: 'With what element do you have problems?'
       multiple: false
       options:
-        - 'Inject'
-        - 'Reflection'
+        - 'inject'
+        - 'reflection'
+        - 'sql'
     validations:
       required: true
   - type: 'input'
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 46820f6..e7f1d98 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -14,3 +14,4 @@ rootProject.name = "commons"
 
 module("inject")
 module("reflection")
+module("sql")
diff --git a/sql/build.gradle.kts b/sql/build.gradle.kts
new file mode 100644
index 0000000..4e0d66d
--- /dev/null
+++ b/sql/build.gradle.kts
@@ -0,0 +1,81 @@
+import com.palantir.gradle.gitversion.VersionDetails
+import groovy.lang.Closure
+import java.lang.System.getenv
+
+plugins {
+    id("java")
+    id("maven-publish")
+    id("com.palantir.git-version") version "3.1.0"
+}
+
+val versionDetails: Closure<VersionDetails> by extra
+
+project.group = project.parent?.group!!
+project.version = project.parent?.version!!
+
+java {
+    toolchain.languageVersion.set(JavaLanguageVersion.of(17))
+}
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+
+    /* HikariCP */
+    implementation("com.zaxxer:HikariCP:${project.property("hikaricp.version")}")
+
+    /* JetBrains Annotations */
+    compileOnly("org.jetbrains:annotations:${project.parent?.property("jetbrains.annotations.version")}")
+    annotationProcessor("org.jetbrains:annotations:${project.parent?.property("jetbrains.annotations.version")}")
+
+    /* JUnit */
+    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
+    testImplementation("org.junit.jupiter:junit-jupiter:${project.parent?.property("junit.version")}")
+
+}
+
+publishing {
+
+    publications {
+        create<MavenPublication>("publish") {
+            groupId = project.group as String
+            artifactId = project.name
+            version = project.version as String
+            from(components["java"])
+        }
+    }
+
+    repositories {
+        maven {
+            url = uri("https://repo.mrstudios.pl/public/")
+            credentials {
+                username = getenv("REPOSITORY_USER")
+                password = getenv("REPOSITORY_PASSWORD")
+            }
+        }
+    }
+
+}
+
+tasks {
+
+    withType<JavaCompile> {
+        options.encoding = "UTF-8"
+    }
+
+    test {
+        useJUnitPlatform()
+        testLogging {
+            events("passed")
+        }
+    }
+
+    build {
+        dependsOn(test)
+        if (versionDetails().branchName == "ver/latest")
+            finalizedBy(publish)
+    }
+
+}
\ No newline at end of file
diff --git a/sql/gradle.properties b/sql/gradle.properties
new file mode 100644
index 0000000..eb84ea2
--- /dev/null
+++ b/sql/gradle.properties
@@ -0,0 +1,2 @@
+# Dependency Properties
+hikaricp.version=5.1.0
\ No newline at end of file
diff --git a/sql/src/main/java/pl/mrstudios/commons/sql/SqlConnection.java b/sql/src/main/java/pl/mrstudios/commons/sql/SqlConnection.java
new file mode 100644
index 0000000..41f2f22
--- /dev/null
+++ b/sql/src/main/java/pl/mrstudios/commons/sql/SqlConnection.java
@@ -0,0 +1,97 @@
+package pl.mrstudios.commons.sql;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.jetbrains.annotations.NotNull;
+import pl.mrstudios.commons.sql.result.SqlEntry;
+import pl.mrstudios.commons.sql.result.SqlResult;
+import pl.mrstudios.commons.sql.statement.SqlStatement;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import static java.lang.Class.forName;
+
+public class SqlConnection {
+
+    private final HikariConfig config;
+    private HikariDataSource dataSource;
+
+    public SqlConnection(
+            @NotNull HikariConfig hikariConfig
+    ) {
+        this.config = hikariConfig;
+        this.dataSource = new HikariDataSource(this.config);
+    }
+
+    @SuppressWarnings("all")
+    public @NotNull Collection<SqlResult> fetch(
+            @NotNull SqlStatement statement
+    ) {
+
+        Collection<SqlResult> result = new LinkedList<>();
+
+        if (this.dataSource.isClosed())
+            this.dataSource = new HikariDataSource(this.config);
+
+        try (
+                Connection connection = this.dataSource.getConnection();
+                PreparedStatement preparedStatement = connection.prepareStatement(statement.query())
+        ) {
+
+            statement.prepare(preparedStatement);
+            try (ResultSet resultSet = preparedStatement.executeQuery()) {
+                while (resultSet.next())
+                    result.add(handleReceivedResultSet(resultSet));
+            }
+
+        } catch (@NotNull Exception exception) {
+            throw new RuntimeException("Unable to fetch entries from database due to exception.", exception);
+        }
+
+        return result;
+
+    }
+
+    @SuppressWarnings("all")
+    public void execute(
+            @NotNull SqlStatement statement
+    ) {
+
+        try (
+                Connection connection = this.dataSource.getConnection();
+                PreparedStatement preparedStatement = connection.prepareStatement(statement.query())
+        ) {
+            statement.prepare(preparedStatement);
+            preparedStatement.execute();
+        } catch (@NotNull Exception exception) {
+            throw new RuntimeException("Unable to execute statement due to exception.", exception);
+        }
+
+    }
+
+    protected static @NotNull SqlResult handleReceivedResultSet(
+            @NotNull ResultSet resultSet
+    ) {
+
+        try {
+
+            SqlResult result = new SqlResult();
+            ResultSetMetaData metaData = resultSet.getMetaData();
+
+            for (int i = 1; i <= metaData.getColumnCount(); i++)
+                result.add(new SqlEntry(metaData.getColumnName(i), forName(metaData.getColumnClassName(i)), resultSet.getObject(i)));
+
+            return result;
+
+        } catch (@NotNull Exception exception) {
+            throw new RuntimeException("Unable to handle received result due to exception.", exception);
+        }
+
+    }
+
+}
diff --git a/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlEntry.java b/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlEntry.java
new file mode 100644
index 0000000..85837ab
--- /dev/null
+++ b/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlEntry.java
@@ -0,0 +1,31 @@
+package pl.mrstudios.commons.sql.result;
+
+import org.jetbrains.annotations.NotNull;
+
+public record SqlEntry(
+        @NotNull String key,
+        @NotNull Class<?> type,
+        @NotNull Object object
+) {
+
+    public @NotNull Long asLong() {
+        return (Long) this.object;
+    }
+
+    public @NotNull String asString() {
+        return (String) this.object;
+    }
+
+    public @NotNull Integer asInteger() {
+        return (Integer) this.object;
+    }
+
+    public @NotNull Double asDouble() {
+        return (Double) this.object;
+    }
+
+    public @NotNull Object asObject() {
+        return this.object;
+    }
+
+}
diff --git a/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlResult.java b/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlResult.java
new file mode 100644
index 0000000..f3a7690
--- /dev/null
+++ b/sql/src/main/java/pl/mrstudios/commons/sql/result/SqlResult.java
@@ -0,0 +1,129 @@
+package pl.mrstudios.commons.sql.result;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import static java.util.List.copyOf;
+
+public class SqlResult implements Collection<SqlEntry> {
+
+    private final Collection<SqlEntry> entries; {
+        this.entries = new LinkedList<>();
+    }
+
+    public @NotNull SqlEntry entry(
+            @NotNull String key
+    ) {
+        return this.entries.stream()
+                .filter((entry) -> entry.key().equalsIgnoreCase(key))
+                .findFirst().orElseThrow();
+    }
+
+    public @NotNull Collection<SqlEntry> entries() {
+        return copyOf(this.entries);
+    }
+
+    @Override
+    public int size() {
+        return this.entries.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return this.entries.isEmpty();
+    }
+
+    @Override
+    public boolean contains(
+            @NotNull Object object
+    ) {
+        return this.entries.contains(object);
+    }
+
+    @Override
+    public @NotNull Iterator<SqlEntry> iterator() {
+        return this.entries.iterator();
+    }
+
+    @Override
+    public void forEach(
+            @NotNull Consumer<? super SqlEntry> action
+    ) {
+        this.entries.forEach(action);
+    }
+
+    @Override
+    public @NotNull Object[] toArray() {
+        return this.entries.toArray();
+    }
+
+    @Override
+    public @NotNull <T> T[] toArray(
+            @NotNull T[] array
+    ) {
+        return this.entries.toArray(array);
+    }
+
+    @Override
+    public boolean add(
+            @NotNull SqlEntry sqlEntry
+    ) {
+        return this.entries.add(sqlEntry);
+    }
+
+    @Override
+    public boolean remove(
+            @NotNull Object object
+    ) {
+        return this.entries.remove(object);
+    }
+
+    @Override
+    public boolean containsAll(
+            @NotNull Collection<?> collection
+    ) {
+        return this.entries.containsAll(collection);
+    }
+
+    @Override
+    public boolean addAll(
+            @NotNull Collection<? extends SqlEntry> collection
+    ) {
+        return this.entries.addAll(collection);
+    }
+
+    @Override
+    public boolean removeAll(
+            @NotNull Collection<?> collection
+    ) {
+        return this.entries.removeAll(collection);
+    }
+
+    @Override
+    public boolean retainAll(
+            @NotNull Collection<?> collection
+    ) {
+        return this.entries.retainAll(collection);
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException("Unable to clear entities due to limited access.");
+    }
+
+    @Override
+    public @NotNull Stream<SqlEntry> stream() {
+        return this.entries.stream();
+    }
+
+    @Override
+    public @NotNull Stream<SqlEntry> parallelStream() {
+        return this.entries.parallelStream();
+    }
+
+}
diff --git a/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatement.java b/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatement.java
new file mode 100644
index 0000000..f3b7e74
--- /dev/null
+++ b/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatement.java
@@ -0,0 +1,114 @@
+package pl.mrstudios.commons.sql.statement;
+
+import org.jetbrains.annotations.NotNull;
+import pl.mrstudios.commons.sql.SqlConnection;
+import pl.mrstudios.commons.sql.result.SqlResult;
+
+import java.sql.JDBCType;
+import java.sql.PreparedStatement;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.sql.JDBCType.*;
+
+public class SqlStatement {
+
+    private final String query;
+    private final Map<Integer, SqlStatementObject> elements;
+
+    protected SqlStatement(
+            @NotNull String query
+    ) {
+        this.query = query;
+        this.elements = new HashMap<>();
+    }
+
+    public @NotNull SqlStatement setString(
+            @NotNull Integer position,
+            @NotNull String value
+    ) {
+        return this.set(position, VARCHAR, value);
+    }
+
+    public @NotNull SqlStatement setLongString(
+            @NotNull Integer position,
+            @NotNull String value
+    ) {
+        return this.set(position, LONGVARCHAR, value);
+    }
+
+    public @NotNull SqlStatement setInteger(
+            @NotNull Integer position,
+            @NotNull Integer value
+    ) {
+        return this.set(position, INTEGER, value);
+    }
+
+    public @NotNull SqlStatement setDouble(
+            @NotNull Integer position,
+            @NotNull Double value
+    ) {
+        return this.set(position, DOUBLE, value);
+    }
+
+    public @NotNull SqlStatement setLong(
+            @NotNull Integer position,
+            @NotNull Long value
+    ) {
+        return this.set(position, BIGINT, value);
+    }
+
+    public @NotNull SqlStatement setFloat(
+            @NotNull Integer position,
+            @NotNull Float value
+    ) {
+        return this.set(position, FLOAT, value);
+    }
+
+    public @NotNull SqlStatement set(
+            @NotNull Integer position,
+            @NotNull JDBCType type,
+            @NotNull Object value
+    ) {
+        this.elements.put(position, new SqlStatementObject(position, type, value));
+        return this;
+    }
+
+    public @NotNull String query() {
+        return this.query;
+    }
+
+    public void prepare(
+            @NotNull PreparedStatement preparedStatement
+    ) {
+
+        this.elements.forEach((position, object) -> {
+            try {
+                preparedStatement.setObject(position, object.object(), object.type());
+            } catch (@NotNull Exception exception) {
+                throw new RuntimeException("Unable to prepare statement due to exception.", exception);
+            }
+        });
+
+    }
+
+    public void execute(
+            @NotNull SqlConnection sqlConnection
+    ) {
+        sqlConnection.execute(this);
+    }
+
+    public @NotNull Collection<SqlResult> fetch(
+            @NotNull SqlConnection sqlConnection
+    ) {
+        return sqlConnection.fetch(this);
+    }
+
+    public static @NotNull SqlStatement createStatement(
+            @NotNull String query
+    ) {
+        return new SqlStatement(query);
+    }
+
+}
diff --git a/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatementObject.java b/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatementObject.java
new file mode 100644
index 0000000..b6333c1
--- /dev/null
+++ b/sql/src/main/java/pl/mrstudios/commons/sql/statement/SqlStatementObject.java
@@ -0,0 +1,11 @@
+package pl.mrstudios.commons.sql.statement;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.SQLType;
+
+record SqlStatementObject(
+        @NotNull Integer position,
+        @NotNull SQLType type,
+        @NotNull Object object
+) {}