Skip to content

Commit e698b5f

Browse files
committed
Java:MultiDataSource 实现应用层与数据库共用账号密码,可用于多租户、SQLAuto 等
1 parent 3d84f4f commit e698b5f

File tree

4 files changed

+120
-49
lines changed

4 files changed

+120
-49
lines changed

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -144,33 +144,34 @@ public void addCorsMappings(CorsRegistry registry) {
144144
// e.printStackTrace();
145145
// Log.e(TAG, "加载 DB2 驱动失败,请检查 pom.xml 中 com.ibm.db2 版本是否存在以及可用 !!!");
146146
// }
147-
try { //加载驱动程序
148-
Log.d(TAG, "尝试加载 Dameng 驱动 <<<<<<<<<<<<<<<<<<<<< ");
149-
Class.forName("dm.jdbc.driver.DmDriver");
150-
Log.d(TAG, "成功加载 Dameng 驱动!>>>>>>>>>>>>>>>>>>>>> ");
151-
}
152-
catch (ClassNotFoundException e) {
153-
e.printStackTrace();
154-
Log.e(TAG, "加载 Dameng 驱动失败,请检查 pom.xml 中 com.dameng 版本是否存在以及可用 !!!");
155-
}
156-
157-
// try { //加载驱动程序
158-
// Log.d(TAG, "尝试加载 TDengine 驱动 <<<<<<<<<<<<<<<<<<<<< ");
159-
// Class.forName("com.taosdata.jdbc.TSDBDriver");
160-
// Log.d(TAG, "成功加载 TDengine 驱动!>>>>>>>>>>>>>>>>>>>>> ");
161-
// } catch (ClassNotFoundException e) {
162-
// e.printStackTrace();
163-
// Log.e(TAG, "加载 TDengine 驱动失败,请检查 pom.xml 中 com.taosdata.jdbc 版本是否存在以及可用 !!!");
164-
// }
165-
//
166-
// try { //加载驱动程序
167-
// Log.d(TAG, "尝试加载 NebulaGraph 驱动 <<<<<<<<<<<<<<<<<<<<< ");
168-
// Class.forName("com.vesoft.nebula.jdbc.impl.NebulaDriver");
169-
// Log.d(TAG, "成功加载 NebulaGraph 驱动!>>>>>>>>>>>>>>>>>>>>> ");
170-
// } catch (ClassNotFoundException e) {
171-
// e.printStackTrace();
172-
// Log.e(TAG, "加载 NebulaGraph 驱动失败,请检查 pom.xml 中 org.nebula-contrib 版本是否存在以及可用 !!!");
173-
// }
147+
148+
try { //加载驱动程序
149+
Log.d(TAG, "尝试加载 Dameng 驱动 <<<<<<<<<<<<<<<<<<<<< ");
150+
Class.forName("dm.jdbc.driver.DmDriver");
151+
Log.d(TAG, "成功加载 Dameng 驱动!>>>>>>>>>>>>>>>>>>>>> ");
152+
}
153+
catch (ClassNotFoundException e) {
154+
e.printStackTrace();
155+
Log.e(TAG, "加载 Dameng 驱动失败,请检查 pom.xml 中 com.dameng 版本是否存在以及可用 !!!");
156+
}
157+
158+
// try { //加载驱动程序
159+
// Log.d(TAG, "尝试加载 TDengine 驱动 <<<<<<<<<<<<<<<<<<<<< ");
160+
// Class.forName("com.taosdata.jdbc.TSDBDriver");
161+
// Log.d(TAG, "成功加载 TDengine 驱动!>>>>>>>>>>>>>>>>>>>>> ");
162+
// } catch (ClassNotFoundException e) {
163+
// e.printStackTrace();
164+
// Log.e(TAG, "加载 TDengine 驱动失败,请检查 pom.xml 中 com.taosdata.jdbc 版本是否存在以及可用 !!!");
165+
// }
166+
//
167+
// try { //加载驱动程序
168+
// Log.d(TAG, "尝试加载 NebulaGraph 驱动 <<<<<<<<<<<<<<<<<<<<< ");
169+
// Class.forName("com.vesoft.nebula.jdbc.impl.NebulaDriver");
170+
// Log.d(TAG, "成功加载 NebulaGraph 驱动!>>>>>>>>>>>>>>>>>>>>> ");
171+
// } catch (ClassNotFoundException e) {
172+
// e.printStackTrace();
173+
// Log.e(TAG, "加载 NebulaGraph 驱动失败,请检查 pom.xml 中 org.nebula-contrib 版本是否存在以及可用 !!!");
174+
// }
174175

175176
// APIJSON 配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
176177

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoController.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import apijson.Log;
7676
import apijson.RequestMethod;
7777
import apijson.StringUtil;
78+
import apijson.demo.CompareUtil;
7879
import apijson.demo.DemoFunctionParser;
7980
import apijson.demo.DemoParser;
8081
import apijson.demo.DemoSQLConfig;
@@ -89,6 +90,7 @@
8990
import apijson.orm.exception.ConflictException;
9091
import apijson.orm.exception.NotExistException;
9192
import apijson.orm.exception.OutOfRangeException;
93+
import apijson.orm.model.TestRecord;
9294
import apijson.router.APIJSONRouterController;
9395

9496
import static apijson.RequestMethod.DELETE;
@@ -104,6 +106,7 @@
104106
import static apijson.framework.APIJSONConstant.FUNCTION_;
105107
import static apijson.framework.APIJSONConstant.ID;
106108
import static apijson.framework.APIJSONConstant.REQUEST_;
109+
import static apijson.framework.APIJSONConstant.TEST_RECORD_;
107110
import static apijson.framework.APIJSONConstant.USER_ID;
108111
import static apijson.framework.APIJSONConstant.VERSION;
109112
import static org.springframework.http.HttpHeaders.COOKIE;
@@ -643,6 +646,7 @@ private apijson.JSONRequest newVerifyRequest(int type, String phone, String veri
643646

644647

645648
public static final String LOGIN = "login";
649+
public static final String AS_DB_ACCOUNT = "asDBAccount";
646650
public static final String REMEMBER = "remember";
647651
public static final String DEFAULTS = "defaults";
648652

@@ -653,12 +657,12 @@ private apijson.JSONRequest newVerifyRequest(int type, String phone, String veri
653657
* @return
654658
* @see
655659
* <pre>
656-
{
657-
"type": 0, //登录方式,非必须 0-密码 1-验证码
658-
"phone": "13000082001",
659-
"password": "1234567",
660-
"version": 1 //全局版本号,非必须
661-
}
660+
{
661+
"type": 0, //登录方式,非必须 0-密码 1-验证码
662+
"phone": "13000082001",
663+
"password": "1234567",
664+
"version": 1 //全局版本号,非必须
665+
}
662666
* </pre>
663667
*/
664668
@PostMapping(LOGIN) //TODO 改 SQLConfig 里的 dbAccount, dbPassword,直接用数据库鉴权
@@ -670,6 +674,7 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
670674
int version;
671675
Boolean format;
672676
boolean remember;
677+
Boolean asDBAccount;
673678
JSONObject defaults;
674679
try {
675680
requestObject = DemoParser.parseRequest(request);
@@ -695,6 +700,7 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
695700
version = requestObject.getIntValue(VERSION);
696701
format = requestObject.getBoolean(FORMAT);
697702
remember = requestObject.getBooleanValue(REMEMBER);
703+
asDBAccount = requestObject.getBoolean(AS_DB_ACCOUNT);
698704
defaults = requestObject.getJSONObject(DEFAULTS); //默认加到每个请求最外层的字段
699705
requestObject.remove(VERSION);
700706
requestObject.remove(FORMAT);
@@ -705,7 +711,6 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
705711
}
706712

707713

708-
709714
//手机号是否已注册
710715
JSONObject phoneResponse = new DemoParser(HEADS, false).parseResponse(
711716
new JSONRequest(
@@ -735,7 +740,7 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
735740
}
736741

737742
//校验凭证
738-
if (isPassword) {//password密码登录
743+
if (isPassword) { //password 密码登录
739744
response = new JSONResponse(
740745
new DemoParser(HEADS, false).parseResponse(
741746
new JSONRequest(new Privacy(userId).setPassword(password))
@@ -774,6 +779,7 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
774779
session.setAttribute(USER_, user); //用户
775780
session.setAttribute(PRIVACY_, privacy); //用户隐私信息
776781
session.setAttribute(REMEMBER, remember); //是否记住登录
782+
session.setAttribute(AS_DB_ACCOUNT, asDBAccount); //是否作为数据库账号密码
777783
session.setMaxInactiveInterval(60*60*24*(remember ? 7 : 1)); //设置session过期时间
778784

779785
response.put(REMEMBER, remember);
@@ -790,7 +796,7 @@ public JSONObject login(@RequestBody String request, HttpSession session) {
790796
public JSONObject logout(HttpSession session) {
791797
SESSION_MAP.remove(session.getId());
792798

793-
long userId;
799+
Long userId;
794800
try {
795801
userId = DemoVerifier.getVisitorId(session);//必须在session.invalidate();前!
796802
Log.d(TAG, "logout userId = " + userId + "; session.getId() = " + (session == null ? null : session.getId()));
@@ -1366,17 +1372,19 @@ public String execute(@RequestBody String request, HttpSession session) {
13661372
JSONObject req = JSON.parseObject(request);
13671373
String database = req.getString("database");
13681374
String uri = req.getString("uri");
1375+
String account = req.getString("account");
1376+
String password = req.getString("password");
13691377
String sql = StringUtil.getTrimedString(req.getString("sql"));
13701378
JSONArray arg = req.getJSONArray("arg");
13711379
List<Object> valueList = arg;
13721380

13731381
DemoSQLExecutor executor = new DemoSQLExecutor();
13741382
DemoSQLConfig config = new DemoSQLConfig();
13751383

1376-
if (StringUtil.isNotEmpty(uri)) {
1377-
config.setDBUri(uri);
1378-
}
13791384
config.setDatabase(database); // "NEBULA"); //
1385+
config.setDBUri(uri);
1386+
config.setDBAccount(account);
1387+
config.setDBPassword(password);
13801388
config.setPrepared(true);
13811389
config.setPreparedValueList(valueList);
13821390

@@ -1417,16 +1425,16 @@ public String execute(@RequestBody String request, HttpSession session) {
14171425
long executeDuration = System.currentTimeMillis() - executeStartTime;
14181426

14191427
ResultSet rs = statement.getResultSet();
1420-
ResultSetMetaData rsmd = rs.getMetaData();
1421-
int length = rsmd.getColumnCount();
1428+
ResultSetMetaData rsmd = rs == null ? null : rs.getMetaData();
1429+
int length = rsmd == null ? 0 : rsmd.getColumnCount();
14221430

14231431
JSONArray arr = new JSONArray();
14241432

14251433
long cursorDuration = 0;
14261434
long rsDuration = 0;
14271435

14281436
long cursorStartTime = System.currentTimeMillis();
1429-
while (rs.next()) {
1437+
while (rs != null && rs.next()) {
14301438
cursorDuration += System.currentTimeMillis() - cursorStartTime;
14311439

14321440
JSONObject obj = new JSONObject(true);

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@
1616

1717
import com.alibaba.fastjson.JSONObject;
1818

19+
import javax.servlet.http.HttpSession;
20+
1921
import apijson.RequestMethod;
22+
import apijson.StringUtil;
23+
import apijson.boot.DemoController;
24+
import apijson.demo.model.Privacy;
25+
import apijson.demo.model.User;
2026
import apijson.framework.APIJSONObjectParser;
2127
import apijson.framework.APIJSONParser;
28+
import apijson.framework.APIJSONVerifier;
2229
import apijson.orm.SQLConfig;
2330

2431

@@ -51,4 +58,40 @@ public APIJSONObjectParser createObjectParser(JSONObject request, String parentP
5158
return new DemoObjectParser(getSession(), request, parentPath, arrayConfig
5259
, isSubquery, isTable, isArrayMainTable).setMethod(getMethod()).setParser(this);
5360
}
61+
62+
// 实现应用层与数据库共用账号密码,可用于多租户、SQLAuto 等 <<<<<<<<<<<<<<<<
63+
private boolean asDBAccount;
64+
private String dbAccount;
65+
private String dbPassword;
66+
@Override
67+
public APIJSONParser<Long> setSession(HttpSession session) {
68+
Boolean asDBAccount = (Boolean) session.getAttribute(DemoController.AS_DB_ACCOUNT);
69+
this.asDBAccount = asDBAccount != null && asDBAccount;
70+
if (this.asDBAccount) {
71+
//User user = (User) session.getAttribute(DemoController.USER_);
72+
//this.dbAccount = user.getName();
73+
Privacy privacy = (Privacy) session.getAttribute(DemoController.PRIVACY_);
74+
this.dbAccount = privacy.getPhone();
75+
this.dbPassword = privacy.get__password();
76+
}
77+
78+
return super.setSession(session);
79+
}
80+
81+
@Override
82+
public JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exception {
83+
if (asDBAccount && config instanceof DemoSQLConfig) {
84+
DemoSQLConfig cfg = (DemoSQLConfig) config;
85+
if (StringUtil.isEmpty(cfg.getDBAccount())) {
86+
cfg.setDBAccount(dbAccount);
87+
}
88+
if (StringUtil.isEmpty(cfg.getDBPassword())) {
89+
cfg.setDBPassword(dbPassword);
90+
}
91+
}
92+
return super.executeSQL(config, isSubquery);
93+
}
94+
95+
// 实现应用层与数据库共用账号密码,可用于多租户、SQLAuto 等 >>>>>>>>>>>>>>>
96+
5497
}

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,17 @@ public String getDBVersion() {
166166
return null;
167167
}
168168

169-
private String dbUri;
170-
public void setDBUri(String dbUri) {
171-
this.dbUri = dbUri;
172-
}
169+
private String dbUri;
170+
public DemoSQLConfig setDBUri(String dbUri) {
171+
this.dbUri = dbUri;
172+
return this;
173+
}
173174
@JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加
174175
@Override
175176
public String getDBUri() {
176-
if (StringUtil.isNotEmpty(dbUri)) {
177-
return dbUri;
178-
}
177+
if (StringUtil.isNotEmpty(dbUri)) {
178+
return dbUri;
179+
}
179180

180181
if (isMySQL()) {
181182
// 这个是 MySQL 8.0 及以上,要加 userSSL=false return "jdbc:mysql://localhost:3306?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8";
@@ -204,9 +205,18 @@ public String getDBUri() {
204205
return "";
205206
}
206207

208+
private String dbAccount;
209+
public DemoSQLConfig setDBAccount(String dbAccount) {
210+
this.dbAccount = dbAccount;
211+
return this;
212+
}
207213
@JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加
208214
@Override
209215
public String getDBAccount() {
216+
if (StringUtil.isNotEmpty(dbAccount)) {
217+
return dbAccount;
218+
}
219+
210220
if (isMySQL()) {
211221
return "root"; //TODO 改成你自己的
212222
}
@@ -231,9 +241,18 @@ public String getDBAccount() {
231241
return "";
232242
}
233243

244+
private String dbPassword;
245+
public DemoSQLConfig setDBPassword(String dbPassword) {
246+
this.dbPassword = dbPassword;
247+
return this;
248+
}
234249
@JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加
235250
@Override
236251
public String getDBPassword() {
252+
if (StringUtil.isNotEmpty(dbPassword)) {
253+
return dbPassword;
254+
}
255+
237256
if (isMySQL()) {
238257
return "apijson"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用, 默认密码为空字符串 ""
239258
}

0 commit comments

Comments
 (0)