From 2a8654485b6a319fafc221074487fe4a820987d5 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 15 Jan 2026 09:08:00 +0000
Subject: [PATCH] Optimize GemExecutor addGems with single SQL query
---
modules/Gem/pom.xml | 32 ++++++++-
.../main/java/com/mcatk/gem/GemExecutor.java | 11 +--
.../java/com/mcatk/gem/sql/MySQLManager.java | 16 +++++
.../java/com/mcatk/gem/GemExecutorTest.java | 69 +++++++++++++++++++
.../com/mcatk/gem/sql/MySQLManagerTest.java | 57 +++++++++++++++
5 files changed, 173 insertions(+), 12 deletions(-)
create mode 100644 modules/Gem/src/test/java/com/mcatk/gem/GemExecutorTest.java
create mode 100644 modules/Gem/src/test/java/com/mcatk/gem/sql/MySQLManagerTest.java
diff --git a/modules/Gem/pom.xml b/modules/Gem/pom.xml
index 6476837..e718cfc 100644
--- a/modules/Gem/pom.xml
+++ b/modules/Gem/pom.xml
@@ -66,6 +66,10 @@
placeholderapi
https://repo.extendedclip.com/content/repositories/placeholderapi/
+
+ jitpack.io
+ https://jitpack.io
+
@@ -76,10 +80,34 @@
provided
- me.clip
- placeholderapi
+ com.github.PlaceholderAPI
+ PlaceholderAPI
2.11.1
provided
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ org.mockito
+ mockito-inline
+ 5.2.0
+ test
+
+
+ net.bytebuddy
+ byte-buddy
+ 1.14.17
+ test
+
+
+ net.bytebuddy
+ byte-buddy-agent
+ 1.14.17
+ test
+
diff --git a/modules/Gem/src/main/java/com/mcatk/gem/GemExecutor.java b/modules/Gem/src/main/java/com/mcatk/gem/GemExecutor.java
index 0fe8194..aba655c 100644
--- a/modules/Gem/src/main/java/com/mcatk/gem/GemExecutor.java
+++ b/modules/Gem/src/main/java/com/mcatk/gem/GemExecutor.java
@@ -43,16 +43,7 @@ public Integer getTotalGems(String name) {
}
public void addGems(String name, int addGems) {
- Integer gems = MySQLManager.getInstance().getGems(name);
- if (MySQLManager.getInstance().getGems(name) == null) {
- MySQLManager.getInstance().insertData(name);
- gems = 0;
- }
- Integer total = MySQLManager.getInstance().getTotal(name);
- gems += addGems;
- total += addGems;
- MySQLManager.getInstance().setGems(name, gems);
- MySQLManager.getInstance().setTotal(name, total);
+ MySQLManager.getInstance().addGems(name, addGems);
Gem.getPlugin().log(name + "获得宝石" + addGems);
}
}
diff --git a/modules/Gem/src/main/java/com/mcatk/gem/sql/MySQLManager.java b/modules/Gem/src/main/java/com/mcatk/gem/sql/MySQLManager.java
index f10ab60..82de4ff 100644
--- a/modules/Gem/src/main/java/com/mcatk/gem/sql/MySQLManager.java
+++ b/modules/Gem/src/main/java/com/mcatk/gem/sql/MySQLManager.java
@@ -117,4 +117,20 @@ public void setTotal(String name, int num) {
}
}
+ public void addGems(String name, int amount) {
+ try (PreparedStatement ps = connection.prepareStatement(
+ "INSERT INTO `gem` (`username`, `gems`, `total`) VALUES (?, ?, ?) " +
+ "ON DUPLICATE KEY UPDATE `gems` = `gems` + ?, `total` = `total` + ?"
+ )) {
+ ps.setString(1, name);
+ ps.setInt(2, amount);
+ ps.setInt(3, amount);
+ ps.setInt(4, amount);
+ ps.setInt(5, amount);
+ ps.executeUpdate();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
}
diff --git a/modules/Gem/src/test/java/com/mcatk/gem/GemExecutorTest.java b/modules/Gem/src/test/java/com/mcatk/gem/GemExecutorTest.java
new file mode 100644
index 0000000..293fc67
--- /dev/null
+++ b/modules/Gem/src/test/java/com/mcatk/gem/GemExecutorTest.java
@@ -0,0 +1,69 @@
+package com.mcatk.gem;
+
+import com.mcatk.gem.sql.MySQLManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Field;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+
+public class GemExecutorTest {
+
+ @Mock
+ private Gem gemMock;
+ @Mock
+ private MySQLManager mysqlManagerMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.openMocks(this);
+
+ // Mock Gem.plugin
+ Field pluginField = Gem.class.getDeclaredField("plugin");
+ pluginField.setAccessible(true);
+ pluginField.set(null, gemMock);
+
+ // Mock MySQLManager.instance
+ Field instanceField = MySQLManager.class.getDeclaredField("instance");
+ instanceField.setAccessible(true);
+ instanceField.set(null, mysqlManagerMock);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Reset static fields
+ Field pluginField = Gem.class.getDeclaredField("plugin");
+ pluginField.setAccessible(true);
+ pluginField.set(null, null);
+
+ Field instanceField = MySQLManager.class.getDeclaredField("instance");
+ instanceField.setAccessible(true);
+ instanceField.set(null, null);
+ }
+
+ @Test
+ public void testAddGems_InteractionCount() {
+ GemExecutor executor = new GemExecutor();
+ String name = "testUser";
+ int amount = 10;
+
+ // Execute
+ executor.addGems(name, amount);
+
+ // Verify interactions for the optimized path
+ verify(mysqlManagerMock, times(1)).addGems(eq(name), eq(amount));
+
+ // Ensure other methods are NOT called
+ verify(mysqlManagerMock, never()).getGems(anyString());
+ verify(mysqlManagerMock, never()).getTotal(anyString());
+ verify(mysqlManagerMock, never()).insertData(anyString());
+ verify(mysqlManagerMock, never()).setGems(anyString(), anyInt());
+ verify(mysqlManagerMock, never()).setTotal(anyString(), anyInt());
+ }
+}
diff --git a/modules/Gem/src/test/java/com/mcatk/gem/sql/MySQLManagerTest.java b/modules/Gem/src/test/java/com/mcatk/gem/sql/MySQLManagerTest.java
new file mode 100644
index 0000000..dc64af8
--- /dev/null
+++ b/modules/Gem/src/test/java/com/mcatk/gem/sql/MySQLManagerTest.java
@@ -0,0 +1,57 @@
+package com.mcatk.gem.sql;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+public class MySQLManagerTest {
+
+ @Mock
+ private Connection connectionMock;
+ @Mock
+ private PreparedStatement preparedStatementMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ public void testAddGems_SQL() throws Exception {
+ MySQLManager manager = new MySQLManager();
+
+ // Inject mock connection
+ Field connectionField = MySQLManager.class.getDeclaredField("connection");
+ connectionField.setAccessible(true);
+ connectionField.set(manager, connectionMock);
+
+ when(connectionMock.prepareStatement(anyString())).thenReturn(preparedStatementMock);
+
+ String name = "user1";
+ int amount = 50;
+
+ manager.addGems(name, amount);
+
+ // Verify the SQL statement
+ String expectedSQL = "INSERT INTO `gem` (`username`, `gems`, `total`) VALUES (?, ?, ?) " +
+ "ON DUPLICATE KEY UPDATE `gems` = `gems` + ?, `total` = `total` + ?";
+ verify(connectionMock).prepareStatement(expectedSQL);
+
+ // Verify parameters
+ verify(preparedStatementMock).setString(1, name);
+ verify(preparedStatementMock).setInt(2, amount); // gems value
+ verify(preparedStatementMock).setInt(3, amount); // total value
+ verify(preparedStatementMock).setInt(4, amount); // increment gems
+ verify(preparedStatementMock).setInt(5, amount); // increment total
+
+ verify(preparedStatementMock).executeUpdate();
+ }
+}