Skip to content

Commit 5810ecf

Browse files
committed
Server: 新增事务处理;DEBUG 模式下禁用 @Explain;废弃 @Correct;优化代码;
1 parent 5e8e516 commit 5810ecf

12 files changed

Lines changed: 455 additions & 224 deletions

File tree

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/APIJSONApplication.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public static void main(String[] args) throws Exception {
4545
System.out.println("开始测试:远程函数 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
4646
try {
4747
DemoFunction.test();
48-
} catch (Exception e) {
48+
}
49+
catch (Exception e) {
4950
e.printStackTrace();
5051
}
5152
System.out.println("\n完成测试:远程函数 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
@@ -54,7 +55,8 @@ public static void main(String[] args) throws Exception {
5455
System.out.println("\n\n\n开始测试:请求校验 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
5556
try {
5657
StructureUtil.test();
57-
} catch (Exception e) {
58+
}
59+
catch (Exception e) {
5860
e.printStackTrace();
5961
}
6062
System.out.println("\n完成测试:请求校验 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
@@ -63,23 +65,26 @@ public static void main(String[] args) throws Exception {
6365
System.out.println("\n\n\n开始初始化:远程函数配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
6466
try {
6567
DemoFunction.init(true);
66-
} catch (Exception e) {
68+
}
69+
catch (Exception e) {
6770
e.printStackTrace();
6871
}
6972
System.out.println("\n完成初始化:远程函数配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
7073

7174
System.out.println("\n\n\n开始初始化:请求校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
7275
try {
7376
StructureUtil.init(true);
74-
} catch (Exception e) {
77+
}
78+
catch (Exception e) {
7579
e.printStackTrace();
7680
}
7781
System.out.println("\n完成初始化:请求校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
7882

7983
System.out.println("\n\n\n开始初始化:权限校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
8084
try {
8185
DemoVerifier.init(true);
82-
} catch (Exception e) {
86+
}
87+
catch (Exception e) {
8388
e.printStackTrace();
8489
}
8590
System.out.println("\n完成初始化:权限校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoObjectParser.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package apijson.demo.server;
1616

17+
import java.util.List;
18+
1719
import javax.servlet.http.HttpSession;
1820
import javax.validation.constraints.NotNull;
1921

@@ -22,14 +24,15 @@
2224
import zuo.biao.apijson.RequestMethod;
2325
import zuo.biao.apijson.StringUtil;
2426
import zuo.biao.apijson.server.AbstractObjectParser;
27+
import zuo.biao.apijson.server.Join;
2528
import zuo.biao.apijson.server.Parser;
2629
import zuo.biao.apijson.server.SQLConfig;
2730

2831

2932
/**简化Parser,getObject和getArray(getArrayConfig)都能用
3033
* @author Lemon
3134
*/
32-
public abstract class DemoObjectParser extends AbstractObjectParser {
35+
public class DemoObjectParser extends AbstractObjectParser {
3336

3437
static {
3538
COMPILE_MAP.put("phone", StringUtil.PATTERN_PHONE);
@@ -38,7 +41,7 @@ public abstract class DemoObjectParser extends AbstractObjectParser {
3841
}
3942

4043

41-
44+
4245
/**for single object
4346
* @param parentPath
4447
* @param request
@@ -48,7 +51,7 @@ public abstract class DemoObjectParser extends AbstractObjectParser {
4851
public DemoObjectParser(HttpSession session, @NotNull JSONObject request, String parentPath, String name, SQLConfig arrayConfig, boolean isSubquery) throws Exception {
4952
super(request, parentPath, name, arrayConfig, isSubquery);
5053
}
51-
54+
5255
@Override
5356
public DemoObjectParser setMethod(RequestMethod method) {
5457
super.setMethod(method);
@@ -61,9 +64,10 @@ public DemoObjectParser setParser(Parser<?> parser) {
6164
return this;
6265
}
6366

67+
6468
@Override
65-
public SQLConfig newSQLConfig(boolean isProcedure) throws Exception {
66-
return DemoSQLConfig.newSQLConfig(method, table, alias, sqlRequest, joinList, isProcedure);
69+
public SQLConfig newSQLConfig(RequestMethod method, String table, String alias, JSONObject request, List<Join> joinList, boolean isProcedure) throws Exception {
70+
return DemoSQLConfig.newSQLConfig(method, table, alias, request, joinList, isProcedure);
6771
}
6872

6973

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoParser.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package apijson.demo.server;
1616

17+
import java.util.List;
1718
import java.util.Map;
1819
import java.util.Set;
1920

@@ -24,7 +25,10 @@
2425
import zuo.biao.apijson.RequestMethod;
2526
import zuo.biao.apijson.server.AbstractParser;
2627
import zuo.biao.apijson.server.JSONRequest;
28+
import zuo.biao.apijson.server.Join;
2729
import zuo.biao.apijson.server.SQLConfig;
30+
import zuo.biao.apijson.server.SQLExecutor;
31+
import zuo.biao.apijson.server.exception.NotExistException;
2832

2933

3034
/**请求解析器
@@ -106,15 +110,7 @@ public DemoObjectParser createObjectParser(JSONObject request, String parentPath
106110
return new DemoObjectParser(session, request, parentPath, name, arrayConfig, isSubquery) {
107111

108112
//TODO 删除,onPUTArrayParse改用MySQL函数JSON_ADD, JSON_REMOVE等
109-
@Override
110-
public JSONObject parseResponse(JSONRequest request) throws Exception {
111-
DemoParser demoParser = new DemoParser(RequestMethod.GET);
112-
demoParser.setSession(session);
113-
// parser.setNoVerifyRequest(noVerifyRequest)
114-
demoParser.setNoVerifyLogin(noVerifyLogin);
115-
demoParser.setNoVerifyRole(noVerifyRole);
116-
return demoParser.parseResponse(request);
117-
}
113+
118114

119115

120116
// @Override

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLExecutor.java

Lines changed: 18 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,10 @@
1414

1515
package apijson.demo.server;
1616

17-
import java.io.BufferedReader;
18-
import java.sql.Blob;
19-
import java.sql.Clob;
20-
import java.sql.Connection;
21-
import java.sql.DriverManager;
2217
import java.sql.PreparedStatement;
2318
import java.sql.ResultSet;
2419
import java.sql.ResultSetMetaData;
2520
import java.sql.SQLException;
26-
import java.util.Collection;
27-
import java.util.HashMap;
28-
import java.util.List;
2921
import java.util.Map;
3022

3123
import javax.validation.constraints.NotNull;
@@ -52,15 +44,17 @@ public class DemoSQLExecutor extends AbstractSQLExecutor {
5244
Log.d(TAG, "尝试加载 MySQL 8 驱动 <<<<<<<<<<<<<<<<<<<<< ");
5345
Class.forName("com.mysql.cj.jdbc.Driver");
5446
Log.d(TAG, "成功加载 MySQL 8 驱动!>>>>>>>>>>>>>>>>>>>>>");
55-
} catch (ClassNotFoundException e) {
47+
}
48+
catch (ClassNotFoundException e) {
5649
Log.e(TAG, "加载 MySQL 8 驱动失败,请检查 pom.xml 中 mysql-connector-java 版本是否存在以及可用 !!!");
5750
e.printStackTrace();
5851

5952
try { //加载驱动程序
6053
Log.d(TAG, "尝试加载 MySQL 7 及以下版本的 驱动 <<<<<<<<<<<<<<<<<<<<< ");
6154
Class.forName("com.mysql.jdbc.Driver");
6255
Log.d(TAG, "成功加载 MySQL 7 及以下版本的 驱动!>>>>>>>>>>>>>>>>>>>>> ");
63-
} catch (ClassNotFoundException e2) {
56+
}
57+
catch (ClassNotFoundException e2) {
6458
Log.e(TAG, "加载 MySQL 7 及以下版本的 驱动失败,请检查 pom.xml 中 mysql-connector-java 版本是否存在以及可用 !!!");
6559
e2.printStackTrace();
6660
}
@@ -70,149 +64,36 @@ public class DemoSQLExecutor extends AbstractSQLExecutor {
7064
Log.d(TAG, "尝试加载 PostgresSQL 驱动 <<<<<<<<<<<<<<<<<<<<< ");
7165
Class.forName("org.postgresql.Driver");
7266
Log.d(TAG, "成功加载 PostgresSQL 驱动!>>>>>>>>>>>>>>>>>>>>> ");
73-
} catch (ClassNotFoundException e) {
67+
}
68+
catch (ClassNotFoundException e) {
7469
e.printStackTrace();
7570
Log.e(TAG, "加载 PostgresSQL 驱动失败,请检查 libs 目录中 postgresql.jar 版本是否存在以及可用 !!!");
7671
}
7772
}
7873

7974

80-
81-
8275
@Override
83-
public ResultSet executeQuery(@NotNull SQLConfig config) throws Exception {
84-
return getStatement(config).executeQuery(); //PreparedStatement 不用传 SQL
85-
}
86-
87-
@Override
88-
public int executeUpdate(@NotNull SQLConfig config) throws Exception {
89-
return getStatement(config).executeUpdate(); //PreparedStatement 不用传 SQL
90-
}
91-
92-
93-
//TODO String 改为 enum Database 解决大小写不一致(MySQL, mysql等)导致创建多余的 Connection
94-
private Map<String, Connection> connectionMap = new HashMap<>();
95-
/**
96-
* @param config
97-
* @return
98-
* @throws Exception
99-
*/
100-
@SuppressWarnings("resource")
101-
@Override
102-
public PreparedStatement getStatement(@NotNull SQLConfig config) throws Exception {
103-
Connection connection = connectionMap.get(config.getDatabase());
104-
if (connection == null || connection.isClosed()) {
105-
Log.i(TAG, "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
106-
107-
if (DemoSQLConfig.DATABASE_POSTGRESQL.equals(config.getDatabase())) { //PostgreSQL 不允许 cross-database
108-
connection = DriverManager.getConnection(config.getDBUri(), config.getDBAccount(), config.getDBPassword());
109-
}
110-
else {
111-
int v;
112-
try {
113-
String[] vs = config.getDBVersion().split("[.]");
114-
v = Integer.parseInt(vs[0]);
115-
} catch (Exception e) {
116-
v = 1;
117-
Log.e(TAG, "getStatement try { String[] vs = config.getDBVersion().split([.]); ... >> } catch (Exception e) {\n" + e.getMessage());
118-
}
119-
120-
if (v >= 8) {
121-
connection = DriverManager.getConnection(config.getDBUri() + "?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&user="
122-
+ config.getDBAccount() + "&password=" + config.getDBPassword());
123-
}
124-
else {
125-
connection = DriverManager.getConnection(config.getDBUri() + "?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&user="
126-
+ config.getDBAccount() + "&password=" + config.getDBPassword());
127-
}
128-
}
129-
connectionMap.put(config.getDatabase(), connection);
130-
}
131-
132-
PreparedStatement statement = connection.prepareStatement(config.getSQL(config.isPrepared())); //创建Statement对象
133-
List<Object> valueList = config.isPrepared() ? config.getPreparedValueList() : null;
134-
135-
if (valueList != null && valueList.isEmpty() == false) {
136-
137-
Object v;
138-
for (int i = 0; i < valueList.size(); i++) {
139-
v = valueList.get(i); //JSON.isBooleanOrNumberOrString(v) 解决 PostgreSQL: Can't infer the SQL type to use for an instance of com.alibaba.fastjson.JSONArray
140-
141-
if (JSON.isBooleanOrNumberOrString(v)) {
142-
statement.setObject(i + 1, v); //PostgreSQL JDBC 不支持隐式类型转换 tinyint = varchar 报错
143-
}
144-
else {
145-
if (DemoSQLConfig.DATABASE_POSTGRESQL.equals(config.getDatabase())) {
146-
147-
PGobject o = new PGobject();
148-
o.setType("jsonb");
149-
o.setValue(v == null ? null : v.toString());
150-
statement.setObject(i + 1, o); //PostgreSQL 除了基本类型,其它的必须通过 PGobject 设置进去,否则 jsonb = varchar 等报错
151-
}
152-
else {
153-
statement.setString(i + 1, v == null ? null : v.toString()); //MySQL setObject 不支持 JSON 类型
154-
}
155-
}
156-
157-
}
76+
public PreparedStatement setArgument(@NotNull SQLConfig config, @NotNull PreparedStatement statement, int index, Object value) throws SQLException {
77+
if (SQLConfig.DATABASE_POSTGRESQL.equals(config.getDatabase()) && JSON.isBooleanOrNumberOrString(value) == false) {
78+
PGobject o = new PGobject();
79+
o.setType("jsonb");
80+
o.setValue(value == null ? null : value.toString());
81+
statement.setObject(index + 1, o); //PostgreSQL 除了基本类型,其它的必须通过 PGobject 设置进去,否则 jsonb = varchar 等报错
82+
return statement;
15883
}
159-
// statement.close();
160-
161-
return statement;
84+
85+
return super.setArgument(config, statement, index, value);
16286
}
16387

88+
16489
@Override
16590
protected Object getValue(SQLConfig config, ResultSet rs, ResultSetMetaData rsmd, int tablePosition,
16691
JSONObject table, int columnIndex, Map<String, JSONObject> childMap) throws Exception {
92+
16793
Object value = super.getValue(config, rs, rsmd, tablePosition, table, columnIndex, childMap);
16894

169-
if (value instanceof Blob) { //FIXME 存的是 abcde,取出来直接就是 [97, 98, 99, 100, 101] 这种 byte[] 类型,没有经过以下处理,但最终序列化后又变成了字符串 YWJjZGU=
170-
value = new String(((Blob) value).getBytes(1, (int) ((Blob) value).length()), "UTF-8");
171-
}
172-
else if (value instanceof Clob) {
173-
174-
StringBuffer sb = new StringBuffer();
175-
BufferedReader br = new BufferedReader(((Clob) value).getCharacterStream());
176-
String s = br.readLine();
177-
while (s != null) {
178-
sb.append(s);
179-
s = br.readLine();
180-
}
181-
value = sb.toString();
182-
}
183-
else if (value instanceof PGobject) {
184-
value = JSON.parse(((PGobject) value).getValue());
185-
}
186-
187-
return value;
95+
return value instanceof PGobject ? JSON.parse(((PGobject) value).getValue()) : value;
18896
}
18997

190-
/**关闭连接,释放资源
191-
*/
192-
@Override
193-
public void close() {
194-
super.close();
195-
196-
if (connectionMap == null) {
197-
return;
198-
}
199-
200-
Collection<Connection> connections = connectionMap.values();
201-
202-
if (connections != null) {
203-
for (Connection connection : connections) {
204-
try {
205-
if (connection != null && connection.isClosed() == false) {
206-
connection.close();
207-
}
208-
} catch (SQLException e) {
209-
e.printStackTrace();
210-
}
211-
}
212-
}
213-
214-
connectionMap.clear();
215-
connectionMap = null;
216-
}
21798

21899
}

0 commit comments

Comments
 (0)