diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml new file mode 100644 index 0000000..b49a3d6 --- /dev/null +++ b/.github/workflows/javadoc.yml @@ -0,0 +1,73 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Javadoc + +on: + # 支持手动触发构建 + workflow_dispatch: + release: + # 创建release的时候触发 + types: [ published ] + +jobs: + api-website: + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v2 + + - name: Set up the Java JDK + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + - name: Generate docs + run: mvn javadoc:javadoc + + - name: Copy to Location + run: | + rm -rf docs + mkdir -vp docs + cp -vrf easysql-api/target/site/apidocs/* docs/ + cp -vrf JAVADOC-README.md docs/README.md + + - name: Generate the sitemap + id: sitemap + uses: cicirello/generate-sitemap@v1 + with: + base-url-path: https://carmjos.github.io/userprefix + path-to-root: docs + + - name: Output stats + run: | + echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}" + echo "url-count = ${{ steps.sitemap.outputs.url-count }}" + echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}" + + - name: Configure Git + env: + DEPLOY_PRI: ${{secrets.DEPLOY_PRI}} + run: | + sudo timedatectl set-timezone "Asia/Shanghai" + mkdir -p ~/.ssh/ + echo "$DEPLOY_PRI" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan github.com >> ~/.ssh/known_hosts + git config --global user.name 'CarmJos' + git config --global user.email 'carm@carm.cc' + + - name: Commit documentation changes + run: | + cd docs + git init + git remote add origin git@github.com:CarmJos/UserPrefix.git + git checkout -b gh-pages + git add -A + git commit -m "API Document generated." + - name: Push javadocs + run: | + cd docs + git push origin HEAD:gh-pages --force + diff --git a/easysql-api/pom.xml b/easysql-api/pom.xml index 5f97a6c..ec0dc72 100644 --- a/easysql-api/pom.xml +++ b/easysql-api/pom.xml @@ -5,14 +5,14 @@ cc.carm.lib easysql-parent - 1.0.0 + v0.0.1 4.0.0 easysql-api jar - EasySQL-API + 00-EasySQL-API EasySQL的接口部分。用于打包到公共项目的API中,避免项目过大。 https://github.com/CarmJos/${project.parent.name} @@ -57,10 +57,6 @@ org.apache.maven.plugins maven-shade-plugin - - org.apache.maven.plugins - maven-surefire-plugin - diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLAction.java new file mode 100644 index 0000000..f7965a8 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLAction.java @@ -0,0 +1,60 @@ +package cc.carm.lib.easysql.api; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.SQLException; +import java.util.UUID; +import java.util.function.Consumer; + +public interface SQLAction { + + @NotNull UUID getActionUUID(); + + @NotNull String getShortID(); + + long getCreateTime(); + + @NotNull String getSQLContent(); + + @NotNull SQLManager getManager(); + + @NotNull T execute() throws SQLException; + + @Nullable + default T execute(@Nullable Consumer exceptionHandler) { + if (exceptionHandler == null) exceptionHandler = defaultExceptionHandler(); + T value = null; + try { + value = execute(); + } catch (SQLException exception) { + exceptionHandler.accept(exception); + } + return value; + } + + default void executeAsync() { + executeAsync(null); + } + + default void executeAsync(Consumer success) { + executeAsync(success, null); + } + + void executeAsync(Consumer success, Consumer failure); + + SQLAction handleException(Consumer failure); + + @NotNull Consumer getExceptionHandler(); + + default Consumer defaultExceptionHandler() { + return Throwable::printStackTrace; + } + + default Consumer defaultResultHandler() { + return t -> { + }; + } + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLBuilder.java new file mode 100644 index 0000000..90690e8 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLBuilder.java @@ -0,0 +1,9 @@ +package cc.carm.lib.easysql.api; + +import org.jetbrains.annotations.NotNull; + +public interface SQLBuilder { + + @NotNull SQLManager getManager(); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLManager.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLManager.java index b9b71c8..0d14b84 100644 --- a/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLManager.java +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLManager.java @@ -1,7 +1,94 @@ package cc.carm.lib.easysql.api; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction; +import cc.carm.lib.easysql.api.builder.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.UUID; + public interface SQLManager { + boolean isDebugMode(); + void setDebugMode(boolean enable); + + /** + * 得到连接池源 + * + * @return DataSource + */ + @NotNull DataSource getDataSource(); + + /** + * 得到一个数据库连接实例 + * + * @return Connection + */ + @NotNull Connection getConnection() throws SQLException; + + /** + * 得到正使用的查询。 + * + * @return 查询列表 + */ + @NotNull Map getActiveQuery(); + + /** + * 执行一条不需要返回结果的SQL语句(多用于UPDATE、REPLACE、DELETE方法) + * + * @param sql SQL语句内容 + * @return 更新的行数 + */ + @Nullable Integer executeSQL(String sql); + + /** + * 执行一条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE) + * + * @param sql SQL语句内容 + * @return 更新的行数 + */ + @Nullable Integer executeSQL(String sql, Object[] params); + + /** + * 执行多条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE) + * + * @param sql SQL语句内容 + * @return 对应参数返回的行数 + */ + @Nullable List executeSQLBatch(String sql, Iterable paramsBatch); + + + /** + * 执行多条不需要返回结果的SQL。 + * + * @param sql SQL语句内容 + * @return 对应参数返回的行数 + */ + @Nullable List executeSQLBatch(@NotNull String sql, String... moreSQL); + + @Nullable List executeSQLBatch(@NotNull Iterable sqlBatch); + + TableCreateBuilder createTable(@NotNull String tableName); + + QueryBuilder createQuery(); + + InsertBuilder createInsertBatch(@NotNull String tableName); + + InsertBuilder createInsert(@NotNull String tableName); + + ReplaceBuilder createReplaceBatch(@NotNull String tableName); + + ReplaceBuilder createReplace(@NotNull String tableName); + + UpdateBuilder createUpdate(@NotNull String tableName); + + DeleteBuilder createDelete(@NotNull String tableName); } diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLQuery.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLQuery.java new file mode 100644 index 0000000..0af3e08 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/SQLQuery.java @@ -0,0 +1,40 @@ +package cc.carm.lib.easysql.api; + +import cc.carm.lib.easysql.api.action.query.QueryAction; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + +public interface SQLQuery extends AutoCloseable { + + /** + * 获取该查询创建的时间 + * + * @return 创建时间 + */ + long getExecuteTime(); + + SQLManager getManager(); + + QueryAction getAction(); + + ResultSet getResultSet(); + + /** + * 得到设定的SQL语句 + * + * @return SQL语句 + */ + String getSQLContent(); + + /** + * 关闭所有内容 + */ + void close(); + + Statement getStatement(); + + Connection getConnection(); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateAction.java new file mode 100644 index 0000000..aed83ce --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateAction.java @@ -0,0 +1,7 @@ +package cc.carm.lib.easysql.api.action; + +public interface PreparedSQLUpdateAction extends SQLUpdateAction { + + PreparedSQLUpdateAction setParams(Object... params); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateBatchAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateBatchAction.java new file mode 100644 index 0000000..ebea465 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/PreparedSQLUpdateBatchAction.java @@ -0,0 +1,19 @@ +package cc.carm.lib.easysql.api.action; + +import cc.carm.lib.easysql.api.SQLAction; + +import java.util.List; + +public interface PreparedSQLUpdateBatchAction extends SQLAction> { + + PreparedSQLUpdateBatchAction setAllParams(Iterable allParams); + + PreparedSQLUpdateBatchAction addParamsBatch(Object... params); + + PreparedSQLUpdateBatchAction setKeyIndex(int keyColumnIndex); + + default PreparedSQLUpdateBatchAction defaultKeyIndex() { + return setKeyIndex(-1); // will return changed lines number + } + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateAction.java new file mode 100644 index 0000000..c74382a --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateAction.java @@ -0,0 +1,13 @@ +package cc.carm.lib.easysql.api.action; + +import cc.carm.lib.easysql.api.SQLAction; + +public interface SQLUpdateAction extends SQLAction { + + SQLUpdateAction setKeyIndex(int keyColumnIndex); + + default SQLUpdateAction defaultKeyIndex() { + return setKeyIndex(-1); // will return changed lines number + } + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateBatchAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateBatchAction.java new file mode 100644 index 0000000..48f5dcb --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/SQLUpdateBatchAction.java @@ -0,0 +1,12 @@ +package cc.carm.lib.easysql.api.action; + +import cc.carm.lib.easysql.api.SQLAction; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface SQLUpdateBatchAction extends SQLAction> { + + SQLUpdateBatchAction addBatch(@NotNull String sql); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/PreparedQueryAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/PreparedQueryAction.java new file mode 100644 index 0000000..9bbb5c2 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/PreparedQueryAction.java @@ -0,0 +1,16 @@ +package cc.carm.lib.easysql.api.action.query; + +import org.jetbrains.annotations.Nullable; + +import java.sql.PreparedStatement; +import java.util.function.Consumer; + +public interface PreparedQueryAction extends QueryAction { + + PreparedQueryAction setParams(@Nullable Object... params); + + PreparedQueryAction setParams(@Nullable Iterable params); + + PreparedQueryAction handleStatement(@Nullable Consumer statement); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/QueryAction.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/QueryAction.java new file mode 100644 index 0000000..db51224 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/action/query/QueryAction.java @@ -0,0 +1,8 @@ +package cc.carm.lib.easysql.api.action.query; + +import cc.carm.lib.easysql.api.SQLAction; +import cc.carm.lib.easysql.api.SQLQuery; + +public interface QueryAction extends SQLAction { + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ConditionalBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ConditionalBuilder.java new file mode 100644 index 0000000..da34835 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ConditionalBuilder.java @@ -0,0 +1,42 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.SQLBuilder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Date; +import java.util.LinkedHashMap; + +public interface ConditionalBuilder extends SQLBuilder { + + T build(); + + ConditionalBuilder setLimit(int limit); + + ConditionalBuilder setConditions(@Nullable String condition); + + ConditionalBuilder setConditions(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs); + + ConditionalBuilder addCondition(@Nullable String condition); + + ConditionalBuilder addNotNullCondition(@NotNull String queryName); + + ConditionalBuilder addCondition(@NotNull String queryName, @NotNull String operator, @Nullable Object queryValue); + + default ConditionalBuilder addCondition(@NotNull String queryName, @Nullable Object queryValue) { + return addCondition(queryName, "=", queryValue); + } + + ConditionalBuilder addCondition(@NotNull String[] queryNames, @Nullable Object[] queryValues); + + default ConditionalBuilder addTimeCondition(@NotNull String queryName, long startMillis, long endMillis) { + return addTimeCondition(queryName, + startMillis > 0 ? new Date(startMillis) : null, + endMillis > 0 ? new Date(endMillis) : null + ); + } + + ConditionalBuilder addTimeCondition(@NotNull String queryName, @Nullable java.util.Date startDate, @Nullable java.util.Date endDate); + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/DeleteBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/DeleteBuilder.java new file mode 100644 index 0000000..c107f8f --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/DeleteBuilder.java @@ -0,0 +1,9 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; + +public interface DeleteBuilder extends ConditionalBuilder { + + String getTableName(); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/InsertBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/InsertBuilder.java new file mode 100644 index 0000000..61de664 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/InsertBuilder.java @@ -0,0 +1,19 @@ +package cc.carm.lib.easysql.api.builder; + +import java.util.Arrays; +import java.util.List; + +public interface InsertBuilder { + + String getTableName(); + + InsertBuilder setTableName(String tableName); + + T setColumnNames(List columnNames); + + default T setColumnNames(String... columnNames) { + return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames)); + } + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/QueryBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/QueryBuilder.java new file mode 100644 index 0000000..8809256 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/QueryBuilder.java @@ -0,0 +1,16 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.SQLBuilder; +import cc.carm.lib.easysql.api.action.query.PreparedQueryAction; +import cc.carm.lib.easysql.api.action.query.QueryAction; +import org.jetbrains.annotations.NotNull; + +public interface QueryBuilder extends SQLBuilder { + + QueryAction withSQL(@NotNull String sql); + + PreparedQueryAction withPreparedSQL(@NotNull String sql); + + TableQueryBuilder inTable(@NotNull String tableName); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ReplaceBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ReplaceBuilder.java new file mode 100644 index 0000000..3e3d8d2 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/ReplaceBuilder.java @@ -0,0 +1,19 @@ +package cc.carm.lib.easysql.api.builder; + +import java.util.Arrays; +import java.util.List; + +public interface ReplaceBuilder { + + String getTableName(); + + ReplaceBuilder setTableName(String tableName); + + T setColumnNames(List columnNames); + + default T setColumnNames(String... columnNames) { + return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames)); + } + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableCreateBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableCreateBuilder.java new file mode 100644 index 0000000..d630f54 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableCreateBuilder.java @@ -0,0 +1,32 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.SQLBuilder; +import cc.carm.lib.easysql.api.action.SQLUpdateAction; +import org.jetbrains.annotations.NotNull; + +public interface TableCreateBuilder extends SQLBuilder { + + @NotNull String getTableName(); + + TableCreateBuilder setTableName(@NotNull String tableName); + + @NotNull String getTableSettings(); + + TableCreateBuilder setTableSettings(@NotNull String settings); + + SQLUpdateAction build(); + + default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) { + return addColumn("`" + columnName + "` " + settings); + } + + TableCreateBuilder addColumn(@NotNull String column); + + TableCreateBuilder setColumns(@NotNull String... columns); + + default TableCreateBuilder defaultTablesSettings() { + return setTableSettings("ENGINE=InnoDB DEFAULT CHARSET=utf8"); + } + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableQueryBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableQueryBuilder.java new file mode 100644 index 0000000..2a75c50 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/TableQueryBuilder.java @@ -0,0 +1,12 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.action.query.PreparedQueryAction; +import org.jetbrains.annotations.NotNull; + +public interface TableQueryBuilder extends ConditionalBuilder { + + @NotNull String getTableName(); + + TableQueryBuilder selectColumns(@NotNull String... columnNames); + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/UpdateBuilder.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/UpdateBuilder.java new file mode 100644 index 0000000..d9a8242 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/builder/UpdateBuilder.java @@ -0,0 +1,20 @@ +package cc.carm.lib.easysql.api.builder; + +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; + +import java.util.LinkedHashMap; + +public interface UpdateBuilder extends ConditionalBuilder { + + String getTableName(); + + UpdateBuilder setColumnValues(LinkedHashMap columnData); + + UpdateBuilder setColumnValues(String[] columnNames, Object[] columnValues); + + default UpdateBuilder setColumnValues(String columnName, Object columnValue) { + return setColumnValues(new String[]{columnName}, new Object[]{columnValue}); + } + + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/enums/ReturnedType.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/enums/ReturnedType.java new file mode 100644 index 0000000..ded64f3 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/enums/ReturnedType.java @@ -0,0 +1,9 @@ +package cc.carm.lib.easysql.api.enums; + +public enum ReturnedType { + + AUTO_INCREASE_KEY, + + CHANGED_LINES + +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/TimeDateUtils.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/TimeDateUtils.java new file mode 100644 index 0000000..f5a628d --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/TimeDateUtils.java @@ -0,0 +1,72 @@ +package cc.carm.lib.easysql.api.util; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class TimeDateUtils { + public static DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public TimeDateUtils() { + } + + public static String getCurrentTime() { + return getFormat().format(new Date()); + } + + public static String getTimeString(long timeMillis) { + return getFormat().format(new Date(timeMillis)); + } + + public static String getTimeString(Date time) { + return getFormat().format(time); + } + + public static long getTimeMillis(String timeString) { + if (timeString == null) { + return -1L; + } else { + try { + return format.parse(timeString).getTime(); + } catch (ParseException var2) { + return -1L; + } + } + } + + public static Date getTimeDate(String timeString) { + if (timeString == null) { + return null; + } else { + try { + return format.parse(timeString); + } catch (ParseException var2) { + return null; + } + } + } + + public static String toDHMSStyle(long allSeconds) { + long days = allSeconds / 86400L; + long hours = allSeconds % 86400L / 3600L; + long minutes = allSeconds % 3600L / 60L; + long seconds = allSeconds % 60L; + String DateTimes; + if (days > 0L) { + DateTimes = days + "天" + (hours > 0L ? hours + "小时" : "") + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "秒" : ""); + } else if (hours > 0L) { + DateTimes = hours + "小时" + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "秒" : ""); + } else if (minutes > 0L) { + DateTimes = minutes + "分钟" + (seconds > 0L ? seconds + "秒" : ""); + } else { + DateTimes = seconds + "秒"; + } + + return DateTimes; + } + + public static DateFormat getFormat() { + return format; + } +} diff --git a/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/UUIDUtil.java b/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/UUIDUtil.java new file mode 100644 index 0000000..63b8241 --- /dev/null +++ b/easysql-api/src/main/java/cc/carm/lib/easysql/api/util/UUIDUtil.java @@ -0,0 +1,15 @@ +package cc.carm.lib.easysql.api.util; + +import java.util.UUID; + +public class UUIDUtil { + + public static UUID toUUID(String s) { + if (s.length() == 36) { + return UUID.fromString(s); + } else { + return UUID.fromString(s.substring(0, 8) + '-' + s.substring(8, 12) + '-' + s.substring(12, 16) + '-' + s.substring(16, 20) + '-' + s.substring(20)); + } + } + +} diff --git a/easysql-beecp/pom.xml b/easysql-beecp/pom.xml new file mode 100644 index 0000000..864b45c --- /dev/null +++ b/easysql-beecp/pom.xml @@ -0,0 +1,78 @@ + + + + easysql-parent + cc.carm.lib + v0.0.1 + + 4.0.0 + + easysql-beecp + jar + + 10-EasySQL-BeeCP + EasySQL的应用部分。此为BeeCP版本。 + https://github.com/CarmJos/${project.parent.name} + + + + CarmJos + Carm Jos + carm@carm.cc + https://www.carm.cc + + Main Developer + + + + + + 8 + 8 + UTF-8 + UTF-8 + + + + + + ${project.parent.groupId} + easysql-impl + ${project.parent.version} + compile + + + + + com.github.chris2018998 + beecp + 3.3.0 + compile + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-shade-plugin + + + + + \ No newline at end of file diff --git a/easysql-beecp/src/main/java/cc/carm/lib/easysql/EasySQL.java b/easysql-beecp/src/main/java/cc/carm/lib/easysql/EasySQL.java new file mode 100644 index 0000000..166c102 --- /dev/null +++ b/easysql-beecp/src/main/java/cc/carm/lib/easysql/EasySQL.java @@ -0,0 +1,21 @@ +package cc.carm.lib.easysql; + +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import cn.beecp.BeeDataSource; +import cn.beecp.BeeDataSourceConfig; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class EasySQL { + + public static SQLManagerImpl createManager( + @NotNull String driver, @NotNull String url, + @NotNull String username, @Nullable String password) { + return createManager(new BeeDataSourceConfig(driver, url, username, password)); + } + + public static SQLManagerImpl createManager(@NotNull BeeDataSourceConfig config) { + return new SQLManagerImpl(new BeeDataSource(config)); + } + +} diff --git a/easysql-hikaricp/pom.xml b/easysql-hikaricp/pom.xml new file mode 100644 index 0000000..9c7d2b0 --- /dev/null +++ b/easysql-hikaricp/pom.xml @@ -0,0 +1,77 @@ + + + + easysql-parent + cc.carm.lib + v0.0.1 + + 4.0.0 + + easysql-hikaricp + + 11-EasySQL-HikariCP + EasySQL的应用部分。此为HikariCP版本。 + https://github.com/CarmJos/${project.parent.name} + + + + CarmJos + Carm Jos + carm@carm.cc + https://www.carm.cc + + Main Developer + + + + + + 8 + 8 + UTF-8 + UTF-8 + + + + + + ${project.parent.groupId} + easysql-impl + ${project.parent.version} + compile + + + + + com.zaxxer + HikariCP + 4.0.3 + compile + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-shade-plugin + + + + + \ No newline at end of file diff --git a/easysql-hikaricp/src/main/java/easysql/EasySQL.java b/easysql-hikaricp/src/main/java/easysql/EasySQL.java new file mode 100644 index 0000000..7a592ab --- /dev/null +++ b/easysql-hikaricp/src/main/java/easysql/EasySQL.java @@ -0,0 +1,32 @@ +package easysql; + +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Properties; + +public class EasySQL { + + public static SQLManagerImpl createManager( + @NotNull String driver, @NotNull String url, + @NotNull String username, @Nullable String password) { + HikariConfig config = new HikariConfig(); + config.setDriverClassName(driver); + config.setJdbcUrl(url); + config.setUsername(username); + config.setPassword(password); + return createManager(config); + } + + public static SQLManagerImpl createManager(@NotNull Properties properties) { + return createManager(new HikariConfig(properties)); + } + + public static SQLManagerImpl createManager(@NotNull HikariConfig config) { + return new SQLManagerImpl(new HikariDataSource(config)); + } + +} diff --git a/easysql-impl/pom.xml b/easysql-impl/pom.xml index 098f962..59d95e0 100644 --- a/easysql-impl/pom.xml +++ b/easysql-impl/pom.xml @@ -5,14 +5,14 @@ easysql-parent cc.carm.lib - 1.0.0 + v0.0.1 4.0.0 easysql-impl jar - EasySQL-Impl + 01-EasySQL-Impl EasySQL的实现部分。 https://github.com/CarmJos/${project.parent.name} @@ -44,38 +44,10 @@ compile - - - com.alibaba - fastjson - 1.2.78 - compile - - - - net.sf.json-lib - json-lib - 2.4 - jdk15 - compile - - - - - com.github.chris2018998 - beecp - 3.3.0 - compile - - - - org.apache.maven.plugins - maven-javadoc-plugin - org.apache.maven.plugins maven-compiler-plugin @@ -92,10 +64,6 @@ org.apache.maven.plugins maven-shade-plugin - - org.apache.maven.plugins - maven-surefire-plugin - diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/EasySQL.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/EasySQL.java deleted file mode 100644 index 86323bf..0000000 --- a/easysql-impl/src/main/java/cc/carm/lib/easysql/EasySQL.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.carm.lib.easysql; - -public class EasySQL { - - - -} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/AbstractSQLAction.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/AbstractSQLAction.java new file mode 100644 index 0000000..aee312b --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/AbstractSQLAction.java @@ -0,0 +1,82 @@ +package cc.carm.lib.easysql.action; + +import cc.carm.lib.easysql.api.SQLAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.sql.SQLException; +import java.util.UUID; +import java.util.function.Consumer; + +public abstract class AbstractSQLAction implements SQLAction { + + private final @NotNull SQLManagerImpl sqlManager; + + private final @NotNull UUID uuid; + private final long createTime; + + protected @NotNull String sqlContent; + + protected @NotNull Consumer exceptionHandler = defaultExceptionHandler(); + + public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql) { + this(manager, sql, System.currentTimeMillis()); + } + + public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, @NotNull UUID uuid) { + this(manager, sql, uuid, System.currentTimeMillis()); + } + + public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, long createTime) { + this(manager, sql, UUID.randomUUID(), createTime); + } + + public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, + @NotNull UUID uuid, long createTime) { + this.sqlManager = manager; + this.sqlContent = sql; + this.uuid = uuid; + this.createTime = createTime; + } + + + @Override + public @NotNull UUID getActionUUID() { + return this.uuid; + } + + @Override + public @NotNull String getShortID() { + return getActionUUID().toString().substring(0, 8); + } + + @Override + public long getCreateTime() { + return this.createTime; + } + + @Override + public @NotNull String getSQLContent() { + return this.sqlContent.trim(); + } + + @Override + public @NotNull SQLManagerImpl getManager() { + return this.sqlManager; + } + + protected void outputDebugMessage() { + getManager().debug("#" + getShortID() + " ->" + getSQLContent()); + } + + @Override + public SQLAction handleException(Consumer handler) { + this.exceptionHandler = handler; + return this; + } + + @NotNull + public Consumer getExceptionHandler() { + return exceptionHandler; + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLBatchUpdateActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLBatchUpdateActionImpl.java new file mode 100644 index 0000000..fd8c136 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLBatchUpdateActionImpl.java @@ -0,0 +1,79 @@ +package cc.carm.lib.easysql.action; + +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import cc.carm.lib.easysql.util.StatementUtil; +import org.jetbrains.annotations.NotNull; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +public class PreparedSQLBatchUpdateActionImpl extends SQLUpdateBatchActionImpl implements PreparedSQLUpdateBatchAction { + + int keyIndex = -1; + List allParams; + + public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + super(manager, sql); + this.allParams = new ArrayList<>(); + } + + @Override + public PreparedSQLUpdateBatchAction setAllParams(Iterable allParams) { + List paramsList = new ArrayList<>(); + allParams.forEach(paramsList::add); + this.allParams = paramsList; + return this; + } + + @Override + public PreparedSQLUpdateBatchAction addParamsBatch(Object[] params) { + this.allParams.add(params); + return this; + } + + @Override + public PreparedSQLUpdateBatchAction setKeyIndex(int keyColumnIndex) { + this.keyIndex = keyColumnIndex; + return this; + } + + @Override + public @NotNull List execute() throws SQLException { + List returnedValues; + Connection connection = getManager().getConnection(); + PreparedStatement statement = StatementUtil.createPrepareStatementBatch( + connection, getSQLContent(), allParams, keyIndex > 0 + ); + outputDebugMessage(); + if (keyIndex > 0) { + List generatedKeys = new ArrayList<>(); + ResultSet resultSet = statement.getGeneratedKeys(); + if (resultSet != null) { + while (resultSet.next()) generatedKeys.add(resultSet.getInt(keyIndex)); + resultSet.close(); + } + returnedValues = generatedKeys; + } else { + int[] executed = statement.executeBatch(); + returnedValues = Arrays.stream(executed).boxed().collect(Collectors.toList()); + } + + statement.close(); + connection.close(); + + return returnedValues; + } + + @Override + public void executeAsync(Consumer> success, Consumer failure) { + + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLUpdateActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLUpdateActionImpl.java new file mode 100644 index 0000000..5b83ce4 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/PreparedSQLUpdateActionImpl.java @@ -0,0 +1,71 @@ +package cc.carm.lib.easysql.action; + +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import cc.carm.lib.easysql.util.StatementUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.function.Consumer; + +public class PreparedSQLUpdateActionImpl extends SQLUpdateActionImpl implements PreparedSQLUpdateAction { + + Object[] params; + + public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + this(manager, sql, (Object[]) null); + } + + public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql, + @Nullable List params) { + this(manager, sql, params == null ? null : params.toArray()); + } + + public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql, + @Nullable Object[] params) { + super(manager, sql); + this.params = params; + } + + @Override + public PreparedSQLUpdateActionImpl setParams(Object[] params) { + this.params = params; + return this; + } + + @Override + public @NotNull Integer execute() throws SQLException { + int value = -1; + + Connection connection = getManager().getConnection(); + PreparedStatement statement = StatementUtil.createPrepareStatement( + connection, getSQLContent(), params, keyIndex > 0 + ); + outputDebugMessage(); + if (keyIndex > 0) { + ResultSet resultSet = statement.getGeneratedKeys(); + if (resultSet != null) { + if (resultSet.next()) value = resultSet.getInt(keyIndex); + resultSet.close(); + } + } else { + value = statement.executeUpdate(getSQLContent()); + } + + statement.close(); + connection.close(); + + return value; + } + + @Override + public void executeAsync(Consumer success, Consumer failure) { + + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateActionImpl.java new file mode 100644 index 0000000..a15f7f0 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateActionImpl.java @@ -0,0 +1,57 @@ +package cc.carm.lib.easysql.action; + +import cc.carm.lib.easysql.api.action.SQLUpdateAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.function.Consumer; + +public class SQLUpdateActionImpl extends AbstractSQLAction implements SQLUpdateAction { + + int keyIndex = -1; + + public SQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + super(manager, sql); + } + + @Override + public @NotNull Integer execute() throws SQLException { + int returnedValue = -1; + Connection connection = getManager().getConnection(); + Statement statement = connection.createStatement(); + outputDebugMessage(); + if (keyIndex > 0) { + statement.executeUpdate(getSQLContent(), Statement.RETURN_GENERATED_KEYS); + ResultSet resultSet = statement.getGeneratedKeys(); + if (resultSet != null) { + if (resultSet.next()) { + returnedValue = resultSet.getInt(keyIndex); + } + resultSet.close(); + } + } else { + returnedValue = statement.executeUpdate(getSQLContent()); + } + + statement.close(); + connection.close(); + + return returnedValue; + } + + @Override + public void executeAsync(Consumer success, Consumer failure) { + + } + + @Override + public SQLUpdateActionImpl setKeyIndex(int keyIndex) { + this.keyIndex = keyIndex; + return this; + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateBatchActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateBatchActionImpl.java new file mode 100644 index 0000000..5b9ff9f --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/SQLUpdateBatchActionImpl.java @@ -0,0 +1,61 @@ +package cc.carm.lib.easysql.action; + +import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +public class SQLUpdateBatchActionImpl extends AbstractSQLAction> implements SQLUpdateBatchAction { + + List sqlContents = new ArrayList<>(); + + public SQLUpdateBatchActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + super(manager, sql); + this.sqlContents.add(sql); + } + + @Override + public @NotNull String getSQLContent() { + return this.sqlContents.stream() + .map(content -> "[" + content + "]" + " ") + .collect(Collectors.joining()); + } + + @Override + public SQLUpdateBatchAction addBatch(@NotNull String sql) { + this.sqlContents.add(sql); + return this; + } + + @Override + public @NotNull List execute() throws SQLException { + Connection connection = getManager().getConnection(); + Statement statement = connection.createStatement(); + outputDebugMessage(); + for (String content : this.sqlContents) { + statement.addBatch(content); + } + int[] executed = statement.executeBatch(); + List returnedValues = Arrays.stream(executed).boxed().collect(Collectors.toList()); + + statement.close(); + connection.close(); + + return returnedValues; + } + + @Override + public void executeAsync(Consumer> success, Consumer failure) { + + } + + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/PreparedQueryActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/PreparedQueryActionImpl.java new file mode 100644 index 0000000..0b6a721 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/PreparedQueryActionImpl.java @@ -0,0 +1,76 @@ +package cc.carm.lib.easysql.action.query; + +import cc.carm.lib.easysql.api.SQLQuery; +import cc.carm.lib.easysql.api.action.query.PreparedQueryAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import cc.carm.lib.easysql.query.SQLQueryImpl; +import cc.carm.lib.easysql.util.StatementUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class PreparedQueryActionImpl extends QueryActionImpl implements PreparedQueryAction { + + Consumer handler; + Object[] params; + + public PreparedQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + super(manager, sql); + } + + @Override + public PreparedQueryActionImpl setParams(@Nullable Object[] params) { + this.params = params; + return this; + } + + @Override + public PreparedQueryActionImpl setParams(@Nullable Iterable params) { + if (params == null) { + return setParams((Object[]) null); + } else { + List paramsList = new ArrayList<>(); + for (Object param : params) { + paramsList.add(param); + } + return setParams(paramsList.toArray()); + } + } + + @Override + public PreparedQueryActionImpl handleStatement(@Nullable Consumer statement) { + this.handler = statement; + return this; + } + + + @Override + public @NotNull SQLQueryImpl execute() throws SQLException { + Connection connection = getManager().getConnection(); + getManager().debug("#" + getShortID() + " ->" + getSQLContent()); + PreparedStatement preparedStatement; + if (handler == null) { + preparedStatement = StatementUtil.createPrepareStatement(connection, getSQLContent(), this.params); + } else { + preparedStatement = connection.prepareStatement(getSQLContent()); + handler.accept(preparedStatement); + } + + ResultSet resultSet = preparedStatement.executeQuery(); + + return new SQLQueryImpl(getManager(), this, connection, preparedStatement, resultSet); + } + + @Override + public void executeAsync(Consumer success, Consumer failure) { + + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/QueryActionImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/QueryActionImpl.java new file mode 100644 index 0000000..a85c389 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/action/query/QueryActionImpl.java @@ -0,0 +1,40 @@ +package cc.carm.lib.easysql.action.query; + +import cc.carm.lib.easysql.action.AbstractSQLAction; +import cc.carm.lib.easysql.api.SQLQuery; +import cc.carm.lib.easysql.api.action.query.QueryAction; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import cc.carm.lib.easysql.query.SQLQueryImpl; +import org.jetbrains.annotations.NotNull; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.function.Consumer; + +public class QueryActionImpl extends AbstractSQLAction implements QueryAction { + + public QueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) { + super(manager, sql); + } + + @Override + public @NotNull SQLQuery execute() throws SQLException { + Connection connection = getManager().getConnection(); + Statement statement = connection.createStatement(); + + outputDebugMessage(); + + ResultSet resultSet = statement.executeQuery(getSQLContent()); + SQLQueryImpl query = new SQLQueryImpl(getManager(), this, connection, statement, resultSet); + getManager().getActiveQuery().put(getActionUUID(), query); + + return query; + } + + @Override + public void executeAsync(Consumer success, Consumer failure) { + + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/AbstractSQLBuilder.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/AbstractSQLBuilder.java new file mode 100644 index 0000000..7d069b1 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/AbstractSQLBuilder.java @@ -0,0 +1,19 @@ +package cc.carm.lib.easysql.builder; + +import cc.carm.lib.easysql.api.SQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractSQLBuilder implements SQLBuilder { + + @NotNull SQLManagerImpl sqlManager; + + public AbstractSQLBuilder(@NotNull SQLManagerImpl manager) { + this.sqlManager = manager; + } + + @Override + public @NotNull SQLManagerImpl getManager() { + return this.sqlManager; + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/AbstractConditionalBuilder.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/AbstractConditionalBuilder.java new file mode 100644 index 0000000..3f8f030 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/AbstractConditionalBuilder.java @@ -0,0 +1,139 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.api.builder.ConditionalBuilder; +import cc.carm.lib.easysql.builder.AbstractSQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.Time; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; + +public abstract class AbstractConditionalBuilder extends AbstractSQLBuilder implements ConditionalBuilder { + + ArrayList conditionSQLs = new ArrayList<>(); + ArrayList conditionParams = new ArrayList<>(); + int limit = -1; + + public AbstractConditionalBuilder(@NotNull SQLManagerImpl manager) { + super(manager); + } + + @Override + public AbstractConditionalBuilder setConditions(@Nullable String condition) { + this.conditionSQLs = new ArrayList<>(); + this.conditionParams = new ArrayList<>(); + if (condition != null) this.conditionSQLs.add(condition); + return this; + } + + @Override + public AbstractConditionalBuilder addCondition(@Nullable String condition) { + this.conditionSQLs.add(condition); + return this; + } + + @Override + public AbstractConditionalBuilder addNotNullCondition(@NotNull String queryName) { + return addCondition("`" + queryName + "` IS NOT NULL"); + } + + + @Override + public AbstractConditionalBuilder addCondition( + @NotNull String queryName, @NotNull String operator, @Nullable Object queryValue + ) { + addCondition("`" + queryName + "` " + operator + " ?"); + this.conditionParams.add(queryValue); + return this; + } + + @Override + public AbstractConditionalBuilder addCondition( + @NotNull String[] queryNames, @Nullable Object[] queryValues + ) { + if (queryNames.length != queryValues.length) { + throw new RuntimeException("queryNames are not match with queryValues"); + } + for (int i = 0; i < queryNames.length; i++) { + addCondition(queryNames[i], queryValues[i]); + } + return this; + } + + @Override + public AbstractConditionalBuilder addTimeCondition( + @NotNull String queryName, @Nullable Date startDate, @Nullable Date endDate + ) { + if (startDate == null && endDate == null) return this; // 都不限定时间,不用判断了 + if (startDate != null) { + addCondition("`" + queryName + "` BETWEEN ? AND ?"); + this.conditionParams.add(startDate); + if (endDate != null) { + this.conditionParams.add(endDate); + } else { + if (startDate instanceof java.sql.Date) { + this.conditionParams.add(new java.sql.Date(System.currentTimeMillis())); + } else if (startDate instanceof Time) { + this.conditionParams.add(new Time(System.currentTimeMillis())); + } else { + this.conditionParams.add(new Timestamp(System.currentTimeMillis())); + } + } + } else { + addCondition(queryName, "<=", endDate); + } + return this; + } + + @Override + public AbstractConditionalBuilder setConditions( + LinkedHashMap<@NotNull String, @Nullable Object> conditions + ) { + conditions.forEach(this::addCondition); + return this; + } + + @Override + public AbstractConditionalBuilder setLimit(int limit) { + this.limit = limit; + return this; + } + + protected String buildConditionSQL() { + + if (!conditionSQLs.isEmpty()) { + StringBuilder conditionBuilder = new StringBuilder(); + conditionBuilder.append("WHERE").append(" "); + Iterator iterator = conditionSQLs.iterator(); + while (iterator.hasNext()) { + conditionBuilder.append(iterator.next()); + if (iterator.hasNext()) conditionBuilder.append(" "); + } + return conditionBuilder.toString(); + } else { + return null; + } + + } + + protected String buildLimitSQL() { + return limit > 0 ? "LIMIT " + limit : ""; + } + + protected ArrayList getConditionParams() { + return conditionParams; + } + + protected boolean hasConditions() { + return this.conditionSQLs != null && !this.conditionSQLs.isEmpty(); + } + + protected boolean hasConditionParams() { + return hasConditions() && getConditionParams() != null && !getConditionParams().isEmpty(); + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/DeleteBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/DeleteBuilderImpl.java new file mode 100644 index 0000000..760aa5b --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/DeleteBuilderImpl.java @@ -0,0 +1,42 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.api.builder.DeleteBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +public class DeleteBuilderImpl + extends AbstractConditionalBuilder + implements DeleteBuilder { + + String tableName; + + public DeleteBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) { + super(manager); + this.tableName = tableName; + } + + @Override + public PreparedSQLUpdateAction build() { + + StringBuilder sqlBuilder = new StringBuilder(); + + sqlBuilder.append("DELETE FROM `").append(getTableName()).append("`"); + + if (hasConditions()) sqlBuilder.append(" ").append(buildConditionSQL()); + if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL()); + + return new PreparedSQLUpdateActionImpl( + getManager(), sqlBuilder.toString(), + hasConditionParams() ? getConditionParams() : null + ); + } + + @Override + public String getTableName() { + return tableName; + } + + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/InsertBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/InsertBuilderImpl.java new file mode 100644 index 0000000..80f3aa6 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/InsertBuilderImpl.java @@ -0,0 +1,51 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.api.builder.InsertBuilder; +import cc.carm.lib.easysql.builder.AbstractSQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.List; + +public abstract class InsertBuilderImpl extends AbstractSQLBuilder implements InsertBuilder { + + String tableName; + + public InsertBuilderImpl(@NotNull SQLManagerImpl manager, String tableName) { + super(manager); + this.tableName = tableName; + } + + protected static String buildSQL(String tableName, List columnNames) { + int valueLength = columnNames.size(); + StringBuilder sqlBuilder = new StringBuilder(); + + sqlBuilder.append("INSERT IGNORE INTO `").append(tableName).append("`("); + Iterator iterator = columnNames.iterator(); + while (iterator.hasNext()) { + sqlBuilder.append("`").append(iterator.next()).append("`"); + if (iterator.hasNext()) sqlBuilder.append(", "); + } + + sqlBuilder.append(") VALUES ("); + + for (int i = 0; i < valueLength; i++) { + sqlBuilder.append("?"); + if (i != valueLength - 1) { + sqlBuilder.append(", "); + } + } + sqlBuilder.append(")"); + return sqlBuilder.toString(); + } + + public String getTableName() { + return tableName; + } + + public InsertBuilderImpl setTableName(String tableName) { + this.tableName = tableName; + return this; + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/QueryBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/QueryBuilderImpl.java new file mode 100644 index 0000000..9e6b394 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/QueryBuilderImpl.java @@ -0,0 +1,33 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.action.query.PreparedQueryActionImpl; +import cc.carm.lib.easysql.action.query.QueryActionImpl; +import cc.carm.lib.easysql.api.action.query.PreparedQueryAction; +import cc.carm.lib.easysql.api.action.query.QueryAction; +import cc.carm.lib.easysql.api.builder.QueryBuilder; +import cc.carm.lib.easysql.api.builder.TableQueryBuilder; +import cc.carm.lib.easysql.builder.AbstractSQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +public class QueryBuilderImpl extends AbstractSQLBuilder implements QueryBuilder { + public QueryBuilderImpl(@NotNull SQLManagerImpl manager) { + super(manager); + } + + @Override + public QueryAction withSQL(@NotNull String sql) { + return new QueryActionImpl(getManager(), sql); + } + + @Override + public PreparedQueryAction withPreparedSQL(@NotNull String sql) { + return new PreparedQueryActionImpl(getManager(), sql); + } + + @Override + public TableQueryBuilder inTable(@NotNull String tableName) { + return new TableQueryBuilderImpl(getManager(), tableName); + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/ReplaceBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/ReplaceBuilderImpl.java new file mode 100644 index 0000000..91a7eb8 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/ReplaceBuilderImpl.java @@ -0,0 +1,51 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.api.builder.ReplaceBuilder; +import cc.carm.lib.easysql.builder.AbstractSQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.List; + +public abstract class ReplaceBuilderImpl extends AbstractSQLBuilder implements ReplaceBuilder { + + String tableName; + + public ReplaceBuilderImpl(@NotNull SQLManagerImpl manager, String tableName) { + super(manager); + this.tableName = tableName; + } + + protected static String buildSQL(String tableName, List columnNames) { + int valueLength = columnNames.size(); + StringBuilder sqlBuilder = new StringBuilder(); + + sqlBuilder.append("REPLACE INTO `").append(tableName).append("`("); + Iterator iterator = columnNames.iterator(); + while (iterator.hasNext()) { + sqlBuilder.append("`").append(iterator.next()).append("`"); + if (iterator.hasNext()) sqlBuilder.append(", "); + } + + sqlBuilder.append(") VALUES ("); + + for (int i = 0; i < valueLength; i++) { + sqlBuilder.append("?"); + if (i != valueLength - 1) { + sqlBuilder.append(", "); + } + } + sqlBuilder.append(")"); + return sqlBuilder.toString(); + } + + public String getTableName() { + return tableName; + } + + public ReplaceBuilderImpl setTableName(String tableName) { + this.tableName = tableName; + return this; + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableCreateBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableCreateBuilderImpl.java new file mode 100644 index 0000000..a1b0c99 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableCreateBuilderImpl.java @@ -0,0 +1,77 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.action.SQLUpdateActionImpl; +import cc.carm.lib.easysql.api.action.SQLUpdateAction; +import cc.carm.lib.easysql.api.builder.TableCreateBuilder; +import cc.carm.lib.easysql.builder.AbstractSQLBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TableCreateBuilderImpl extends AbstractSQLBuilder implements TableCreateBuilder { + + String tableName; + + List columns; + + String tableSettings; + + public TableCreateBuilderImpl(SQLManagerImpl manager, String tableName) { + super(manager); + this.tableName = tableName; + this.columns = new ArrayList<>(); + defaultTablesSettings(); + } + + @Override + public @NotNull String getTableName() { + return this.tableName; + } + + @Override + public @NotNull String getTableSettings() { + return this.tableSettings; + } + + @Override + public SQLUpdateAction build() { + StringBuilder createSQL = new StringBuilder(); + createSQL.append("CREATE TABLE IF NOT EXISTS `").append(tableName).append("`"); + createSQL.append("("); + for (int i = 0; i < columns.size(); i++) { + createSQL.append(columns.get(i)); + if (i != columns.size() - 1) createSQL.append(", "); + } + createSQL.append(") ").append(tableSettings); + + return new SQLUpdateActionImpl(getManager(), createSQL.toString()); + } + + @Override + public TableCreateBuilder setTableName(@NotNull String tableName) { + this.tableName = tableName; + return this; + } + + @Override + public TableCreateBuilder addColumn(@NotNull String column) { + this.columns.add(column); + return this; + } + + @Override + public TableCreateBuilder setColumns(@NotNull String[] columns) { + this.columns = Arrays.asList(columns); + return this; + } + + @Override + public TableCreateBuilder setTableSettings(@NotNull String settings) { + this.tableSettings = settings; + return this; + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableQueryBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableQueryBuilderImpl.java new file mode 100644 index 0000000..6080d62 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/TableQueryBuilderImpl.java @@ -0,0 +1,62 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.action.query.PreparedQueryActionImpl; +import cc.carm.lib.easysql.api.action.query.PreparedQueryAction; +import cc.carm.lib.easysql.api.builder.TableQueryBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +public class TableQueryBuilderImpl + extends AbstractConditionalBuilder + implements TableQueryBuilder { + + @NotNull String tableName; + + ArrayList params = new ArrayList<>(); + String[] columns; + + public TableQueryBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) { + super(manager); + this.tableName = tableName; + } + + @Override + public PreparedQueryActionImpl build() { + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("SELECT").append(" "); + if (columns == null || columns.length < 1) { + sqlBuilder.append("*"); + } else { + for (int i = 0; i < columns.length; i++) { + String name = columns[i]; + sqlBuilder.append("`").append(name).append("`"); + if (i != columns.length - 1) { + sqlBuilder.append(","); + } + } + } + + sqlBuilder.append(" ").append("FROM").append(" "); + sqlBuilder.append("`").append(tableName).append("`"); + + if (hasConditions()) sqlBuilder.append(" ").append(buildConditionSQL()); + if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL()); + + return new PreparedQueryActionImpl(getManager(), sqlBuilder.toString()) + .setParams(hasConditionParams() ? params : null); + } + + @Override + public @NotNull String getTableName() { + return tableName; + } + + @Override + public TableQueryBuilderImpl selectColumns(@NotNull String[] columnNames) { + this.columns = columnNames; + return this; + } + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/UpdateBuilderImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/UpdateBuilderImpl.java new file mode 100644 index 0000000..d9fdb61 --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/builder/impl/UpdateBuilderImpl.java @@ -0,0 +1,76 @@ +package cc.carm.lib.easysql.builder.impl; + +import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.api.builder.UpdateBuilder; +import cc.carm.lib.easysql.manager.SQLManagerImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class UpdateBuilderImpl + extends AbstractConditionalBuilder + implements UpdateBuilder { + + String tableName; + + List columnNames; + List columnValues; + + public UpdateBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) { + super(manager); + this.tableName = tableName; + } + + @Override + public PreparedSQLUpdateAction build() { + + StringBuilder sqlBuilder = new StringBuilder(); + + sqlBuilder.append("UPDATE `").append(getTableName()).append("` SET "); + + Iterator iterator = this.columnNames.iterator(); + while (iterator.hasNext()) { + sqlBuilder.append("`").append(iterator.next()).append("` = ?"); + if (iterator.hasNext()) sqlBuilder.append(" , "); + } + List allParams = new ArrayList<>(this.columnValues); + + if (hasConditions()) { + sqlBuilder.append(" ").append(buildConditionSQL()); + allParams.addAll(getConditionParams()); + } + + if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL()); + + return new PreparedSQLUpdateActionImpl(getManager(), sqlBuilder.toString(), allParams); + } + + @Override + public String getTableName() { + return tableName; + } + + @Override + public UpdateBuilder setColumnValues(LinkedHashMap columnData) { + this.columnNames = new ArrayList<>(); + this.columnValues = new ArrayList<>(); + columnData.forEach((name, value) -> { + this.columnNames.add(name); + this.columnValues.add(value); + }); + return this; + } + + @Override + public UpdateBuilder setColumnValues(String[] columnNames, Object[] columnValues) { + if (columnNames.length != columnValues.length) { + throw new RuntimeException("columnNames are not match with columnValues"); + } + this.columnNames = Arrays.asList(columnNames); + this.columnValues = Arrays.asList(columnValues); + return this; + } + + +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/manager/SQLManagerImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/manager/SQLManagerImpl.java new file mode 100644 index 0000000..28e05aa --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/manager/SQLManagerImpl.java @@ -0,0 +1,176 @@ +package cc.carm.lib.easysql.manager; + +import cc.carm.lib.easysql.action.PreparedSQLBatchUpdateActionImpl; +import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl; +import cc.carm.lib.easysql.action.SQLUpdateActionImpl; +import cc.carm.lib.easysql.action.SQLUpdateBatchActionImpl; +import cc.carm.lib.easysql.api.SQLManager; +import cc.carm.lib.easysql.api.SQLQuery; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction; +import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction; +import cc.carm.lib.easysql.api.builder.*; +import cc.carm.lib.easysql.builder.impl.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +public class SQLManagerImpl implements SQLManager { + + private final Logger LOGGER; + private final DataSource dataSource; + ConcurrentHashMap activeQuery = new ConcurrentHashMap<>(); + + boolean debug = false; + + public SQLManagerImpl(@NotNull DataSource dataSource) { + this(dataSource, null); + } + + public SQLManagerImpl(@NotNull DataSource dataSource, @Nullable String name) { + this.LOGGER = Logger.getLogger("SQLManager" + (name != null ? "#" + name : "")); + this.dataSource = dataSource; + } + + @Override + public boolean isDebugMode() { + return this.debug; + } + + @Override + public void setDebugMode(boolean enable) { + this.debug = enable; + } + + public void debug(String msg) { + if (isDebugMode()) getLogger().info("[DEBUG] " + msg); + } + + public Logger getLogger() { + return LOGGER; + } + + + @Override + public @NotNull DataSource getDataSource() { + return this.dataSource; + } + + @Override + public @NotNull Connection getConnection() throws SQLException { + return getDataSource().getConnection(); + } + + @Override + public @NotNull Map getActiveQuery() { + return this.activeQuery; + } + + @Override + public Integer executeSQL(String sql) { + return new SQLUpdateActionImpl(this, sql).execute(null); + } + + @Override + public Integer executeSQL(String sql, Object[] params) { + return new PreparedSQLUpdateActionImpl(this, sql, params).execute(null); + } + + @Override + public List executeSQLBatch(String sql, Iterable paramsBatch) { + return new PreparedSQLBatchUpdateActionImpl(this, sql) + .setAllParams(paramsBatch) + .execute(null); + } + + @Override + public List executeSQLBatch(@NotNull String sql, String[] moreSQL) { + SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, sql); + if (moreSQL != null && moreSQL.length > 0) { + Arrays.stream(moreSQL).forEach(action::addBatch); + } + return action.execute(null); + } + + @Override + public @Nullable List executeSQLBatch(@NotNull Iterable sqlBatch) { + Iterator iterator = sqlBatch.iterator(); + if (!iterator.hasNext()) return null; // PLEASE GIVE IT SOMETHING + + SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, iterator.next()); + while (iterator.hasNext()) { + action.addBatch(iterator.next()); + } + + return action.execute(null); + } + + @Override + public TableCreateBuilder createTable(@NotNull String tableName) { + return new TableCreateBuilderImpl(this, tableName); + } + + @Override + public QueryBuilder createQuery() { + return new QueryBuilderImpl(this); + } + + @Override + public InsertBuilder createInsertBatch(@NotNull String tableName) { + return new InsertBuilderImpl(this, tableName) { + @Override + public PreparedSQLUpdateBatchAction setColumnNames(List columnNames) { + return new PreparedSQLBatchUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames)); + } + }; + } + + @Override + public InsertBuilder createInsert(@NotNull String tableName) { + return new InsertBuilderImpl(this, tableName) { + @Override + public PreparedSQLUpdateAction setColumnNames(List columnNames) { + return new PreparedSQLUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames)); + } + }; + } + + @Override + public ReplaceBuilder createReplaceBatch(@NotNull String tableName) { + return new ReplaceBuilderImpl(this, tableName) { + @Override + public PreparedSQLUpdateBatchAction setColumnNames(List columnNames) { + return new PreparedSQLBatchUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames)); + } + }; + } + + @Override + public ReplaceBuilder createReplace(@NotNull String tableName) { + return new ReplaceBuilderImpl(this, tableName) { + @Override + public PreparedSQLUpdateAction setColumnNames(List columnNames) { + return new PreparedSQLUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames)); + } + }; + } + + @Override + public UpdateBuilder createUpdate(@NotNull String tableName) { + return new UpdateBuilderImpl(this, tableName); + } + + @Override + public DeleteBuilder createDelete(@NotNull String tableName) { + return new DeleteBuilderImpl(this, tableName); + } + + +} + diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/query/SQLQueryImpl.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/query/SQLQueryImpl.java new file mode 100644 index 0000000..d74736c --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/query/SQLQueryImpl.java @@ -0,0 +1,87 @@ +package cc.carm.lib.easysql.query; + +import cc.carm.lib.easysql.action.query.QueryActionImpl; +import cc.carm.lib.easysql.api.SQLQuery; +import cc.carm.lib.easysql.manager.SQLManagerImpl; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class SQLQueryImpl implements SQLQuery { + + protected final long executeTime; + + protected SQLManagerImpl sqlManager; + protected QueryActionImpl queryAction; + + Connection connection; + Statement statement; + + ResultSet resultSet; + + public SQLQueryImpl( + SQLManagerImpl sqlManager, QueryActionImpl queryAction, + Connection connection, Statement statement, ResultSet resultSet + ) { + this.executeTime = System.currentTimeMillis(); + this.sqlManager = sqlManager; + this.queryAction = queryAction; + this.connection = connection; + this.statement = statement; + this.resultSet = resultSet; + } + + @Override + public long getExecuteTime() { + return this.executeTime; + } + + @Override + public SQLManagerImpl getManager() { + return this.sqlManager; + } + + @Override + public QueryActionImpl getAction() { + return this.queryAction; + } + + @Override + public ResultSet getResultSet() { + return this.resultSet; + } + + @Override + public String getSQLContent() { + return getAction().getSQLContent(); + } + + @Override + public void close() { + try { + if (getResultSet() != null) getResultSet().close(); + if (getStatement() != null) getStatement().close(); + if (getConnection() != null) getConnection().close(); + + getManager().debug("#" + getAction().getShortID() + + " -> finished after " + (System.currentTimeMillis() - getExecuteTime()) + " ms." + ); + getManager().getActiveQuery().remove(getAction().getActionUUID()); + } catch (SQLException e) { + getAction().getExceptionHandler().accept(e); + } + this.queryAction = null; + } + + @Override + public Statement getStatement() { + return this.statement; + } + + @Override + public Connection getConnection() { + return this.connection; + } +} diff --git a/easysql-impl/src/main/java/cc/carm/lib/easysql/util/StatementUtil.java b/easysql-impl/src/main/java/cc/carm/lib/easysql/util/StatementUtil.java new file mode 100644 index 0000000..ab9452d --- /dev/null +++ b/easysql-impl/src/main/java/cc/carm/lib/easysql/util/StatementUtil.java @@ -0,0 +1,205 @@ +package cc.carm.lib.easysql.util; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class StatementUtil { + + /** + * 创建一个 {@link PreparedStatement} 。 + * + * @param connection 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 + * @param params "?"所代表的对应参数列表 + * @return 完成参数填充的 {@link PreparedStatement} + */ + public static PreparedStatement createPrepareStatement( + Connection connection, String sql, Object[] params + ) throws SQLException { + return createPrepareStatement(connection, sql, params, false); + } + + /** + * 创建一个 {@link PreparedStatement} 。 + * + * @param connection 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 + * @param params "?"所代表的对应参数列表 + * @param returnGeneratedKey 是否会返回自增主键 + * @return 完成参数填充的 {@link PreparedStatement} + */ + public static PreparedStatement createPrepareStatement( + Connection connection, String sql, Object[] params, boolean returnGeneratedKey + ) throws SQLException { + sql = sql.trim(); + PreparedStatement statement = connection.prepareStatement(sql, returnGeneratedKey ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS); + final Map nullTypeMap = new HashMap<>(); + if (params != null) { + fillParams(statement, Arrays.asList(params), nullTypeMap); + } + return statement; + } + + /** + * 创建批量操作的一个 {@link PreparedStatement} 。 + * + * @param connection 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 + * @param paramsBatch "?"所代表的对应参数列表 + * @return 完成参数填充的 {@link PreparedStatement} + */ + public static PreparedStatement createPrepareStatementBatch( + Connection connection, String sql, Iterable paramsBatch + ) throws SQLException { + return createPrepareStatementBatch(connection, sql, paramsBatch, false); + } + + /** + * 创建批量操作的一个 {@link PreparedStatement} 。 + * + * @param connection 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 + * @param paramsBatch "?"所代表的对应参数列表 + * @param returnGeneratedKey 是否会返回自增主键 + * @return 完成参数填充的 {@link PreparedStatement} + */ + public static PreparedStatement createPrepareStatementBatch( + Connection connection, String sql, Iterable paramsBatch, boolean returnGeneratedKey + ) throws SQLException { + + sql = sql.trim(); + PreparedStatement statement = connection.prepareStatement(sql, returnGeneratedKey ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS); + final Map nullTypeMap = new HashMap<>(); + for (Object[] params : paramsBatch) { + fillParams(statement, Arrays.asList(params), nullTypeMap); + statement.addBatch(); + } + + return statement; + } + + + /** + * 填充PreparedStatement的参数。 + * + * @param statement PreparedStatement + * @param params SQL参数 + * @return {@link PreparedStatement} 填充参数后的PreparedStatement + * @throws SQLException SQL执行异常 + */ + public static PreparedStatement fillParams( + PreparedStatement statement, Iterable params + ) throws SQLException { + return fillParams(statement, params, null); + } + + /** + * 填充PreparedStatement的参数。 + * + * @param statement PreparedStatement + * @param params SQL参数 + * @param nullCache null参数的类型缓存,避免循环中重复获取类型 + * @return 完成参数填充的 {@link PreparedStatement} + */ + public static PreparedStatement fillParams( + PreparedStatement statement, Iterable params, Map nullCache + ) throws SQLException { + if (null == params) { + return statement;// 无参数 + } + + int paramIndex = 1;//第一个参数从1计数 + for (Object param : params) { + setParam(statement, paramIndex++, param, nullCache); + } + return statement; + } + + /** + * 获取null字段对应位置的数据类型 + * 如果类型获取失败将使用默认的 {@link Types#VARCHAR} + * + * @param statement {@link PreparedStatement} + * @param paramIndex 参数序列,第一位从1开始 + * @return 数据类型,默认为 {@link Types#VARCHAR} + */ + public static int getNullType(PreparedStatement statement, int paramIndex) { + int sqlType = Types.VARCHAR; + + final ParameterMetaData pmd; + try { + pmd = statement.getParameterMetaData(); + sqlType = pmd.getParameterType(paramIndex); + } catch (SQLException ignore) { + } + + return sqlType; + } + + /** + * 为 {@link PreparedStatement} 设置单个参数 + * + * @param preparedStatement {@link PreparedStatement} + * @param paramIndex 参数序列,从1开始 + * @param param 参数,不能为{@code null} + * @param nullCache 用于缓存参数为null位置的类型,避免重复获取 + */ + private static void setParam( + PreparedStatement preparedStatement, int paramIndex, Object param, + Map nullCache + ) throws SQLException { + + if (param == null) { + Integer type = (null == nullCache) ? null : nullCache.get(paramIndex); + if (null == type) { + type = getNullType(preparedStatement, paramIndex); + if (null != nullCache) { + nullCache.put(paramIndex, type); + } + } + preparedStatement.setNull(paramIndex, type); + } + + // 针对UUID特殊处理,避免元数据直接插入 + if (param instanceof UUID) { + preparedStatement.setString(paramIndex, param.toString()); + return; + } + + // 日期特殊处理,默认按照时间戳传入,避免毫秒丢失 + if (param instanceof java.util.Date) { + if (param instanceof Date) { + preparedStatement.setDate(paramIndex, (Date) param); + } else if (param instanceof Time) { + preparedStatement.setTime(paramIndex, (Time) param); + } else { + preparedStatement.setTimestamp(paramIndex, new Timestamp(((java.util.Date) param).getTime())); + } + return; + } + + // 针对大数字类型的特殊处理 + if (param instanceof Number) { + if (param instanceof BigDecimal) { + // BigDecimal的转换交给JDBC驱动处理 + preparedStatement.setBigDecimal(paramIndex, (BigDecimal) param); + return; + } + if (param instanceof BigInteger) { + // BigInteger转为BigDecimal + preparedStatement.setBigDecimal(paramIndex, new BigDecimal((BigInteger) param)); + return; + } + // 忽略其它数字类型,按照默认类型传入 + } + + // 其它参数类型直接插入 + preparedStatement.setObject(paramIndex, param); + } + +} diff --git a/pom.xml b/pom.xml index b156628..9003b63 100644 --- a/pom.xml +++ b/pom.xml @@ -7,15 +7,19 @@ cc.carm.lib easysql-parent pom - 1.0.0 + v0.0.1 easysql-api easysql-impl + + easysql-beecp + easysql-hikaricp + EasySQL - 简单便捷的数据库操作工具,采用 BeeCP 连接池。 + 简单便捷的数据库操作工具,可自选连接池。 https://github.com/CarmJos/${name} @@ -110,10 +114,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.1 - - false - @@ -219,7 +219,7 @@ true - +