Skip to content

Commit

Permalink
Merge pull request #18 from AzisabaNetwork/feat/hikaricp-support
Browse files Browse the repository at this point in the history
Use hikariCP for connect to database
  • Loading branch information
sysnote8main authored Oct 20, 2024
2 parents 299f77a + a2459f3 commit 2e636fb
Show file tree
Hide file tree
Showing 10 changed files with 507 additions and 32 deletions.
79 changes: 79 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>${project.name}</finalName>
<resources>
Expand All @@ -36,6 +48,51 @@
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>module-info.class</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.MF</exclude>
</excludes>
</filter>
</filters>
<artifactSet>
<excludes>
<exclude>org.spigotmc:1.12.2-R0.1-SNAPSHOT</exclude>
<exclude>org.junit.jupiter:junit-jupiter</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

Expand All @@ -55,6 +112,7 @@
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
Expand All @@ -66,5 +124,26 @@
<artifactId>jsonmessage</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
31 changes: 22 additions & 9 deletions src/main/java/jp/azisaba/lgw/kdstatus/KDStatusReloaded.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package jp.azisaba.lgw.kdstatus;

import java.io.File;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;

import jp.azisaba.lgw.kdstatus.sql.*;
import jp.azisaba.lgw.kdstatus.task.DBConnectionCheckTask;
Expand Down Expand Up @@ -31,7 +33,7 @@ public class KDStatusReloaded extends JavaPlugin {

private SQLHandler sqlHandler = null;

public MySQLHandler sql;
public HikariMySQLDatabase sql;

private PlayerDataMySQLController kdData;

Expand All @@ -55,22 +57,33 @@ public void onEnable() {
sqlHandler = new SQLHandler(new File(getDataFolder(), "playerData.db"));
kdDataContainer = new KillDeathDataContainer(new PlayerDataSQLController(sqlHandler).init());

sql = new MySQLHandler();

this.kdData = new PlayerDataMySQLController(this);

try {
sql.connect();
} catch (SQLException throwables) {
throwables.printStackTrace();
getLogger().warning("Failed to connect SQLDatabase.");
}
DBAuthConfig.loadAuthConfig();
sql = DBAuthConfig.getDatabase(getLogger(), 10);

sql.connect();

if(sql.isConnected()){
getLogger().info("SQL Testing...");
try(PreparedStatement pstmt = sql.getConnection().prepareStatement("SELECT 1")) {
if(pstmt.executeQuery().next()) {
getLogger().info("SQL Test was success!");
} else {
getLogger().warning("Failed to test SQL Connection");
}
} catch (SQLException e) {
getLogger().log(Level.SEVERE, "Error on SQL Testing", e);
}
getLogger().info("SQL Test is finished!");

getLogger().info("Connected SQLDatabase!");

//ここでテーブル作るぞ
this.kdData.createTable();

getLogger().info("Table was created!");

}

saveTask = new SavePlayerDataTask(this);
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/jp/azisaba/lgw/kdstatus/sql/DBAuthConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package jp.azisaba.lgw.kdstatus.sql;

import jp.azisaba.lgw.kdstatus.KDStatusReloaded;
import lombok.AccessLevel;
import lombok.Getter;

import java.util.logging.Logger;

/**
* Safe auth config loader
*/
public class DBAuthConfig {
@Getter(AccessLevel.PROTECTED)
private static String host;
@Getter(AccessLevel.PROTECTED)
private static String port;
@Getter(AccessLevel.PROTECTED)
private static String database;
@Getter(AccessLevel.PROTECTED)
private static String user;
@Getter(AccessLevel.PROTECTED)
private static String password;

public static void loadAuthConfig() {
host = getConfigAsString("host");
port = getConfigAsString("port");
database = getConfigAsString("database");
user = getConfigAsString("username");
password = getConfigAsString("password");
}

public static HikariMySQLDatabase getDatabase(Logger logger, int maxPoolSize) {
return new HikariMySQLDatabase(
logger,
maxPoolSize,
host,
port,
database,
user,
password
);
}

private static String getConfigAsString(String path) {
return KDStatusReloaded.getPlugin().getConfig().getString(path);
}
}
167 changes: 167 additions & 0 deletions src/main/java/jp/azisaba/lgw/kdstatus/sql/HikariMySQLDatabase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package jp.azisaba.lgw.kdstatus.sql;


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Wrapper class of HikariDataSource for MySQL
*/
@RequiredArgsConstructor
public class HikariMySQLDatabase {
private final Logger logger;
private final int maxPoolSize;
private final String host, port, databaseName, user, password;

@Getter
private boolean initialized;
private HikariDataSource hikari;

public boolean isConnected() {
if(hikari == null) return false;
return hikari.isRunning();
}

/**
* connect to database.
*/
public void connect() {
if (initialized) {
logger.warning("Database is already initialized!");
return;
}
String jdbcUrl = String.format(
"jdbc:mysql://%s:%s/%s?useSSL=false",
host,
port,
databaseName
);

HikariConfig config = new HikariConfig();
config.setUsername(user);
config.setPassword(password);
config.setJdbcUrl(jdbcUrl);
config.setMaximumPoolSize(maxPoolSize);
// config.setConnectionInitSql("SELECT 1");
config.setAutoCommit(true);
config.setConnectionTimeout(1500); // TODO change this
hikari = new HikariDataSource(config);
}

/**
* close database connection
*/
public void close() {
hikari.close();
initialized = false;
}

/**
* reconnect database
*/
public void reconnect() {
close();
connect();
}

/**
* CAUTION: this method throws {@link SQLException} so need to catch it
*
* @return a connection of database
* @throws SQLException from {@link HikariDataSource#getConnection()}
*/
public Connection getConnection() throws SQLException {
return hikari.getConnection();
}

/**
* get a connection (Safer than {@link #getConnection()})
*
* @return database connection. If failed, return null.
*/

public Connection getConnectionOrNull() {
try {
return hikari.getConnection();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to get connection", e);
return null;
}
}


public PreparedStatement preparedStatement(@NonNull String sql) {
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.log(Level.SEVERE, "Failed to create preparedStatement: connection is null");
return null;
}
try {
return conn.prepareStatement(sql);
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to create preparedStatement", e);
return null;
}
}

/**
* execute a SQL statement
*
* @param sql SQL statement
* @param pstmtConsumer to process PreparedStatement (ex. {@link PreparedStatement#setString(int, String)})
* @return result of execution. If failed, return null
*/

public ResultSet executeQuery(@NonNull String sql, Consumer<PreparedStatement> pstmtConsumer) {
// get a connection
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.warning("Failed to execute query: connection is null");
return null;
}

// execute query
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
if (pstmtConsumer != null) {
pstmtConsumer.accept(pstmt);
}
return pstmt.executeQuery();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to execute query", e);
return null;
}
}

/**
* @param sql SQL statement
* @return is succeeded
*/
public boolean executeUpdate(String sql) {
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.severe("Failed to execute update: connection is null");
return false;
}

try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
return true;
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to execute update", e);
return false;
}
}
}
Loading

0 comments on commit 2e636fb

Please sign in to comment.