Skip to content

Commit be581e8

Browse files
committed
Server:新增 SQL Server 的表和字段属性 系统表;新增判断数据库类型的方法;优化各种数据库的配置和判断
1 parent 64e31d6 commit be581e8

File tree

12 files changed

+281
-110
lines changed

12 files changed

+281
-110
lines changed

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

Lines changed: 65 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ public class DemoSQLConfig extends AbstractSQLConfig {
3838

3939

4040
static {
41-
//TODO 默认模式名,改成你自己的
42-
DEFAULT_SCHEMA = "sys";
41+
DEFAULT_DATABASE = DATABASE_MYSQL; //TODO 默认数据库类型,改成你自己的
42+
DEFAULT_SCHEMA = "sys"; //TODO 默认模式名,改成你自己的
4343

4444
// 由 DemoVerifier.init 方法读取数据库 Access 表来替代手动输入配置
4545
// //表名映射,隐藏真实表名,对安全要求很高的表可以这么做
@@ -70,75 +70,97 @@ public String getUserIdKey(String database, String schema, String table) {
7070
};
7171
}
7272

73-
//取消注释后,默认的数据库类型会由 MySQL 改为 PostgreSQL
74-
// @Override
75-
// public String getDatabase() {
76-
// String db = super.getDatabase();
77-
// return db == null ? DATABASE_POSTGRESQL : db;
78-
// }
79-
8073
@Override
8174
public String getDBVersion() {
82-
return "5.7.22"; //"8.0.11"; //TODO 改成你自己的 MySQL 或 PostgreSQL 数据库版本号 //MYSQL 8 和 7 使用的 JDBC 配置不一样
75+
if (isMySQL()) {
76+
return "5.7.22"; //"8.0.11"; //TODO 改成你自己的 MySQL 或 PostgreSQL 数据库版本号 //MYSQL 8 和 7 使用的 JDBC 配置不一样
77+
}
78+
if (isPostgreSQL()) {
79+
return "9.6.15"; //TODO 改成你自己的
80+
}
81+
if (isSQLServer()) {
82+
return "2016"; //TODO 改成你自己的
83+
}
84+
if (isOracle()) {
85+
return "18c"; //TODO 改成你自己的
86+
}
87+
return null;
8388
}
84-
8589
@Override
8690
public String getDBUri() {
87-
String db = getDatabase();
88-
if (db == null) {
89-
db = "";
91+
if (isMySQL()) {
92+
return "jdbc:mysql://localhost:3306"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000
9093
}
91-
switch (db) {
92-
case DATABASE_POSTGRESQL:
94+
if (isPostgreSQL()) {
9395
return "jdbc:postgresql://localhost:5432/postgres"; //TODO 改成你自己的
94-
case DATABASE_SQLSERVER:
96+
}
97+
if (isSQLServer()) {
9598
return "jdbc:jtds:sqlserver://localhost:1433/pubs;instance=SQLEXPRESS"; //TODO 改成你自己的
96-
case DATABASE_ORACLE:
99+
}
100+
if (isOracle()) {
97101
return "jdbc:oracle:thin:@localhost:1521:orcl"; //TODO 改成你自己的
98-
case DATABASE_MYSQL:
99-
default:
100-
return "jdbc:mysql://localhost:3306"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000
101102
}
103+
return null;
102104
}
103-
104-
105105
@Override
106106
public String getDBAccount() {
107-
String db = getDatabase();
108-
if (db == null) {
109-
db = "";
107+
if (isMySQL()) {
108+
return "root"; //TODO 改成你自己的
110109
}
111-
switch (db) {
112-
case DATABASE_POSTGRESQL:
110+
if (isPostgreSQL()) {
113111
return "postgres"; //TODO 改成你自己的
114-
case DATABASE_SQLSERVER:
112+
}
113+
if (isSQLServer()) {
115114
return "sa"; //TODO 改成你自己的
116-
case DATABASE_ORACLE:
115+
}
116+
if (isOracle()) {
117117
return "scott"; //TODO 改成你自己的
118-
case DATABASE_MYSQL:
119-
default:
120-
return "root"; //TODO 改成你自己的
121118
}
119+
return null;
122120
}
123121
@Override
124122
public String getDBPassword() {
125-
String db = getDatabase();
126-
if (db == null) {
127-
db = "";
123+
if (isMySQL()) {
124+
return "apijson"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用, 默认密码为空字符串 ""
128125
}
129-
switch (db) {
130-
case DATABASE_POSTGRESQL:
126+
if (isPostgreSQL()) {
131127
return null; //TODO 改成你自己的
132-
case DATABASE_SQLSERVER:
128+
}
129+
if (isSQLServer()) {
133130
return "apijson@123"; //TODO 改成你自己的
134-
case DATABASE_ORACLE:
131+
}
132+
if (isOracle()) {
135133
return "tiger"; //TODO 改成你自己的
136-
case DATABASE_MYSQL:
137-
default:
138-
return "apijson"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用, 默认密码为空字符串 ""
139134
}
135+
return null;
140136
}
141137

138+
//取消注释后,默认的数据库类型会由 MySQL 改为 PostgreSQL
139+
// @Override
140+
// public String getDatabase() {
141+
// String db = super.getDatabase();
142+
// return db == null ? DATABASE_POSTGRESQL : db;
143+
// }
144+
145+
//如果确定只用一种数据库,可以重写方法,这种数据库直接 return true,其它数据库直接 return false,来减少判断,提高性能
146+
// @Override
147+
// public boolean isMySQL() {
148+
// return true;
149+
// }
150+
// @Override
151+
// public boolean isPostgreSQL() {
152+
// return false;
153+
// }
154+
// @Override
155+
// public boolean isSQLServer() {
156+
// return false;
157+
// }
158+
// @Override
159+
// public boolean isOracle() {
160+
// return false;
161+
// }
162+
163+
142164

143165
@Override
144166
public String getIdKey() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public class DemoSQLExecutor extends AbstractSQLExecutor {
9696

9797
@Override
9898
public PreparedStatement setArgument(@NotNull SQLConfig config, @NotNull PreparedStatement statement, int index, Object value) throws SQLException {
99-
if (SQLConfig.DATABASE_POSTGRESQL.equals(config.getDatabase()) && JSON.isBooleanOrNumberOrString(value) == false) {
99+
if (config.isPostgreSQL() && JSON.isBooleanOrNumberOrString(value) == false) {
100100
PGobject o = new PGobject();
101101
o.setType("jsonb");
102102
o.setValue(value == null ? null : value.toString());

APIJSON-Java-Server/APIJSONORM/src/main/java/zuo/biao/apijson/server/AbstractSQLConfig.java

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,11 @@
6363
import zuo.biao.apijson.StringUtil;
6464
import zuo.biao.apijson.server.exception.NotExistException;
6565
import zuo.biao.apijson.server.model.Column;
66+
import zuo.biao.apijson.server.model.ExtendedProperty;
6667
import zuo.biao.apijson.server.model.PgAttribute;
6768
import zuo.biao.apijson.server.model.PgClass;
69+
import zuo.biao.apijson.server.model.SysColumn;
70+
import zuo.biao.apijson.server.model.SysTable;
6871
import zuo.biao.apijson.server.model.Table;
6972

7073
/**config sql for JSON Request
@@ -73,6 +76,7 @@
7376
public abstract class AbstractSQLConfig implements SQLConfig {
7477
private static final String TAG = "AbstractSQLConfig";
7578

79+
public static String DEFAULT_DATABASE = DATABASE_MYSQL;
7680
public static String DEFAULT_SCHEMA = "sys";
7781
public static String PREFFIX_DISTINCT = "DISTINCT ";
7882

@@ -85,16 +89,20 @@ public abstract class AbstractSQLConfig implements SQLConfig {
8589
TABLE_KEY_MAP = new HashMap<String, String>();
8690
TABLE_KEY_MAP.put(Table.class.getSimpleName(), Table.TABLE_NAME);
8791
TABLE_KEY_MAP.put(Column.class.getSimpleName(), Column.TABLE_NAME);
88-
TABLE_KEY_MAP.put(PgAttribute.class.getSimpleName(), PgAttribute.TABLE_NAME);
8992
TABLE_KEY_MAP.put(PgClass.class.getSimpleName(), PgClass.TABLE_NAME);
93+
TABLE_KEY_MAP.put(PgAttribute.class.getSimpleName(), PgAttribute.TABLE_NAME);
94+
TABLE_KEY_MAP.put(SysTable.class.getSimpleName(), SysTable.TABLE_NAME);
95+
TABLE_KEY_MAP.put(SysColumn.class.getSimpleName(), SysColumn.TABLE_NAME);
96+
TABLE_KEY_MAP.put(ExtendedProperty.class.getSimpleName(), ExtendedProperty.TABLE_NAME);
9097

9198
DATABASE_LIST = new ArrayList<>();
9299
DATABASE_LIST.add(DATABASE_MYSQL);
93100
DATABASE_LIST.add(DATABASE_POSTGRESQL);
94101
DATABASE_LIST.add(DATABASE_SQLSERVER);
95102
DATABASE_LIST.add(DATABASE_ORACLE);
96103
}
97-
104+
105+
98106
@NotNull
99107
@Override
100108
public String getIdKey() {
@@ -243,30 +251,75 @@ public SQLConfig setDatabase(String database) {
243251
this.database = database;
244252
return this;
245253
}
246-
254+
/**
255+
* @return db == null ? DEFAULT_DATABASE : db
256+
*/
257+
@NotNull
258+
public String getSQLDatabase() {
259+
String db = getDatabase();
260+
return db == null ? DEFAULT_DATABASE : db; // "" 表示已设置,不需要用全局默认的 StringUtil.isEmpty(db, false)) {
261+
}
262+
263+
@Override
264+
public boolean isMySQL() {
265+
return isMySQL(getSQLDatabase());
266+
}
267+
public static boolean isMySQL(String db) {
268+
return DATABASE_MYSQL.equals(db);
269+
}
270+
@Override
271+
public boolean isPostgreSQL() {
272+
return isPostgreSQL(getSQLDatabase());
273+
}
274+
public static boolean isPostgreSQL(String db) {
275+
return DATABASE_POSTGRESQL.equals(db);
276+
}
277+
@Override
278+
public boolean isSQLServer() {
279+
return isSQLServer(getSQLDatabase());
280+
}
281+
public static boolean isSQLServer(String db) {
282+
return DATABASE_SQLSERVER.equals(db);
283+
}
284+
@Override
285+
public boolean isOracle() {
286+
return isOracle(getSQLDatabase());
287+
}
288+
public static boolean isOracle(String db) {
289+
return DATABASE_ORACLE.equals(db);
290+
}
291+
247292
@Override
248293
public String getQuote() {
249-
String db = getDatabase();
250-
return StringUtil.isEmpty(db, true) || DATABASE_MYSQL.equals(db) ? "`" : "\"";
294+
return isMySQL() ? "`" : "\"";
251295
}
252296

253297
@Override
254298
public String getSchema() {
255299
return schema;
256300
}
257-
public String getSQLSchema(String sqlTable) {
258-
//强制,避免因为全局默认的 @schema 自动填充进来,导致这几个类的 schema 为 sys 等其它值
259-
if ((Table.TABLE_NAME.equals(sqlTable) || Column.TABLE_NAME.equals(sqlTable)) ) {
260-
return SCHEMA_INFORMATION;
261-
}
262-
if ((PgAttribute.TABLE_NAME.equals(sqlTable) || PgClass.TABLE_NAME.equals(sqlTable)) ) {
263-
return "";
264-
}
265-
301+
/**
302+
* @param sqlTable
303+
* @return
304+
*/
305+
@NotNull
306+
public String getSQLSchema(String table) {
266307
String sch = getSchema();
267308
if (sch == null) { //PostgreSQL 的 pg_class 和 pg_attribute 表好像不属于任何 Schema StringUtil.isEmpty(sch, true)) {
268-
sch = DEFAULT_SCHEMA;
309+
//不能强制,SQL Server 在 information_schema 和 sys 中都有 tables 和 columns //强制,避免因为全局默认的 @schema 自动填充进来,导致这几个类的 schema 为 sys 等其它值
310+
if (Table.TAG.equals(table) || Column.TAG.equals(table)) {
311+
return SCHEMA_INFORMATION; //MySQL, PostgreSQL, SQL Server 都有的
312+
}
313+
if (SysTable.TAG.equals(table) || SysColumn.TAG.equals(table)) {
314+
return SCHEMA_SYS; //SQL Server 在 sys 中的属性比 information_schema 中的要全,能拿到注释
315+
}
316+
if ((PgAttribute.TAG.equals(table) || PgClass.TAG.equals(table)) ) {
317+
return ""; //PostgreSQL 的 pg_class 和 pg_attribute 表好像不属于任何 Schema
318+
}
319+
320+
return DEFAULT_SCHEMA;
269321
}
322+
270323
return sch;
271324
}
272325
@Override
@@ -549,15 +602,14 @@ public String getOrderString(boolean hasPrefix) {
549602

550603

551604
String order = StringUtil.getTrimedString(getOrder());
552-
String db = getDatabase();
553605

554-
if (DATABASE_ORACLE.equals(db) || DATABASE_SQLSERVER.equals(db)) { // Oracle 和 SQL Server 的 OFFSET 必须加 ORDER BY
606+
if (isOracle() || isSQLServer()) { // Oracle 和 SQL Server 的 OFFSET 必须加 ORDER BY
555607

556608
// String[] ss = StringUtil.split(order);
557609
if (StringUtil.isEmpty(order, true)) {
558610
String idKey = getIdKey();
559611
if (StringUtil.isEmpty(idKey, true)) {
560-
idKey = "id";
612+
idKey = "id"; //ORDER BY NULL 不行,SQL Server 会报错,必须要有排序,才能使用 OFFSET FETCH,如果没有 idKey,请求中指定 @order 即可
561613
}
562614
order = idKey; //让数据库调控默认升序还是降序 + "+";
563615
}
@@ -1052,16 +1104,16 @@ public String getLimitString() {
10521104
if (count <= 0 || RequestMethod.isHeadMethod(getMethod(), true)) {
10531105
return "";
10541106
}
1055-
return getLimitString(getPage(), getCount(), getDatabase());
1107+
return getLimitString(getPage(), getCount(), isOracle() || isSQLServer());
10561108
}
10571109
/**获取限制数量
10581110
* @param limit
10591111
* @return
10601112
*/
1061-
public static String getLimitString(int page, int count, String db) {
1113+
public static String getLimitString(int page, int count, boolean isTSQL) {
10621114
int offset = getOffset(page, count);
10631115

1064-
if (DATABASE_ORACLE.equals(db) || DATABASE_SQLSERVER.equals(db)) {
1116+
if (isTSQL) {
10651117
return " OFFSET " + offset + " ROWS FETCH FIRST " + count + " ROWS ONLY";
10661118
}
10671119

@@ -1605,7 +1657,7 @@ public String getRegExpString(String key, Object[] values, int type, boolean ign
16051657
*/
16061658
@JSONField(serialize = false)
16071659
public String getRegExpString(String key, String value, boolean ignoreCase) {
1608-
if (DATABASE_POSTGRESQL.equals(getDatabase())) {
1660+
if (isPostgreSQL()) {
16091661
return getKey(key) + " ~" + (ignoreCase ? "* " : " ") + getValue(value);
16101662
}
16111663
return getKey(key) + " REGEXP " + (ignoreCase ? "" : "BINARY ") + getValue(value);
@@ -1840,7 +1892,7 @@ public String getContainString(String key, Object[] childs, int type) throws Ill
18401892
throw new IllegalArgumentException(key + "<>:value 中value类型不能为JSON!");
18411893
}
18421894

1843-
if (DATABASE_POSTGRESQL.equals(getDatabase())) {
1895+
if (isPostgreSQL()) {
18441896
condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR))
18451897
+ getKey(key) + " @> " + getValue(newJSONArray(childs[i])); //operator does not exist: jsonb @> character varying "[" + childs[i] + "]");
18461898
} else {

APIJSON-Java-Server/APIJSONORM/src/main/java/zuo/biao/apijson/server/AbstractSQLExecutor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws
176176
Log.d(TAG, "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
177177
+ "\n已生成 " + generatedSQLCount + " 条 SQL"
178178
+ "\nselect startTime = " + startTime
179-
+ "\nsql = \n" + sql
179+
+ "\n database = " + StringUtil.getString(config.getDatabase())
180+
+ "; schema = " + StringUtil.getString(config.getSchema())
181+
+ "; sql = \n" + sql
180182
+ "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
181183

182184
ResultSet rs = null;
@@ -633,7 +635,7 @@ public Connection getConnection(@NotNull SQLConfig config) throws Exception {
633635
if (connection == null || connection.isClosed()) {
634636
Log.i(TAG, "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
635637

636-
if (SQLConfig.DATABASE_MYSQL.equals(config.getDatabase())) {
638+
if (config.isMySQL()) {
637639
int v;
638640
try {
639641
String[] vs = config.getDBVersion().split("[.]");
@@ -656,6 +658,7 @@ public Connection getConnection(@NotNull SQLConfig config) throws Exception {
656658
else { //PostgreSQL 不允许 cross-database
657659
connection = DriverManager.getConnection(config.getDBUri(), config.getDBAccount(), config.getDBPassword());
658660
}
661+
659662
connectionMap.put(config.getDatabase(), connection);
660663
}
661664

0 commit comments

Comments
 (0)