001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.db.datasource;
017
018import com.jfinal.plugin.activerecord.DbKit;
019import io.jboot.db.TableInfo;
020import io.jboot.db.driver.DriverClassNames;
021import io.jboot.utils.StrUtil;
022
023import java.util.ArrayList;
024import java.util.List;
025
026
027public class DataSourceConfig {
028    public static final String NAME_DEFAULT = DbKit.MAIN_CONFIG_NAME;
029
030    public static final String TYPE_MYSQL = "mysql";
031    public static final String TYPE_ORACLE = "oracle";
032    public static final String TYPE_SQLSERVER = "sqlserver";
033    public static final String TYPE_SQLITE = "sqlite";
034    public static final String TYPE_ANSISQL = "ansisql";
035    public static final String TYPE_POSTGRESQL = "postgresql";
036    public static final String TYPE_DM = "dm";
037    public static final String TYPE_CLICKHOUSE = "clickhouse";
038    public static final String TYPE_INFORMIX = "informix";
039
040
041    private String name;
042    private String type = TYPE_MYSQL;
043    private String url;
044    private String user;
045    private String password;
046    private String driverClassName;
047    private String connectionInitSql;
048    private String poolName;
049    private boolean cachePrepStmts = true;
050    private int prepStmtCacheSize = 500;
051    private int prepStmtCacheSqlLimit = 2048;
052    private int maximumPoolSize = 10;
053
054    private Long maxLifetime;
055    private Long idleTimeout;
056    private Integer minimumIdle = 0;
057
058    // 配置获取连接等待超时的时间
059    private long maxWait = -1;
060
061    // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
062    private long timeBetweenEvictionRunsMillis = 60 * 1000L;
063    // 配置连接在池中最小生存的时间
064    private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
065    // 配置发生错误时多久重连
066    private long timeBetweenConnectErrorMillis = 500;
067    private String validationQuery;
068    private boolean testWhileIdle = true;
069    private boolean testOnBorrow = false;
070    private boolean testOnReturn = false;
071
072    private String sqlTemplatePath;
073    private String sqlTemplate;
074    private String factory; //HikariDataSourceFactory.class.getName();
075
076    private String shardingConfigYaml;
077
078    private String dbProFactory;
079    private String containerFactory;
080    private Integer transactionLevel;
081
082    private String table; //此数据源包含哪些表
083    private String exTable; //该数据源排除哪些表
084    private String tablePrefix; //表前缀,假设 @Table(tableName="xxx"),那么实际表名为:tablePrefix + tableName
085
086    private String dialectClass;
087    private String activeRecordPluginClass;
088
089    /**
090     * HikariCP 连接探活间隔时间 4.0.1以上版本支持,建议设置为10分钟以内
091     */
092    private Long keepaliveTime;
093    /**
094     * 是否需要添加到映射
095     * 在一个表有多个数据源的情况下,应该只需要添加一个映射就可以了,
096     * 添加映射:默认为该model的数据源,
097     * 不添加映射:通过 model.use("xxx").save()这种方式去调用该数据源
098     */
099    private boolean needAddMapping = true;
100
101
102    public String getName() {
103        return name;
104    }
105
106    public void setName(String name) {
107        this.name = name;
108    }
109
110    public String getType() {
111        return type;
112    }
113
114    public void setType(String type) {
115        this.type = type;
116    }
117
118    public String getUrl() {
119        return url;
120    }
121
122    public void setUrl(String url) {
123        this.url = url;
124    }
125
126    public String getUser() {
127        return user;
128    }
129
130    public void setUser(String user) {
131        this.user = user;
132    }
133
134    public String getPassword() {
135        return password;
136    }
137
138    public void setPassword(String password) {
139        this.password = password;
140    }
141
142    public String getDriverClassName() {
143        if (StrUtil.isNotBlank(driverClassName)) {
144            return driverClassName;
145        }
146        return DriverClassNames.getDefaultDriverClass(getType());
147    }
148
149    public void setDriverClassName(String driverClassName) {
150        this.driverClassName = driverClassName;
151    }
152
153    public String getConnectionInitSql() {
154        return connectionInitSql;
155    }
156
157    public void setConnectionInitSql(String connectionInitSql) {
158        this.connectionInitSql = connectionInitSql;
159    }
160
161    public boolean isCachePrepStmts() {
162        return cachePrepStmts;
163    }
164
165    public void setCachePrepStmts(boolean cachePrepStmts) {
166        this.cachePrepStmts = cachePrepStmts;
167    }
168
169    public int getPrepStmtCacheSize() {
170        return prepStmtCacheSize;
171    }
172
173    public void setPrepStmtCacheSize(int prepStmtCacheSize) {
174        this.prepStmtCacheSize = prepStmtCacheSize;
175    }
176
177    public int getPrepStmtCacheSqlLimit() {
178        return prepStmtCacheSqlLimit;
179    }
180
181    public void setPrepStmtCacheSqlLimit(int prepStmtCacheSqlLimit) {
182        this.prepStmtCacheSqlLimit = prepStmtCacheSqlLimit;
183    }
184
185    public int getMaximumPoolSize() {
186        return maximumPoolSize;
187    }
188
189    public void setMaximumPoolSize(int maximumPoolSize) {
190        this.maximumPoolSize = maximumPoolSize;
191    }
192
193    public boolean isConfigOk() {
194        return StrUtil.isNotBlank(getUrl()) || StrUtil.isNotBlank(getShardingConfigYaml());
195    }
196
197
198    public boolean isMysqlType() {
199        return TYPE_MYSQL.equals(getType());
200    }
201
202    public boolean isOracleType() {
203        return TYPE_ORACLE.equals(getType());
204    }
205
206    public boolean isSqlServerType() {
207        return TYPE_SQLSERVER.equals(getType());
208    }
209
210    public boolean isSqliteType() {
211        return TYPE_SQLITE.equals(getType());
212    }
213
214    public boolean isAnsiSqlType() {
215        return TYPE_ANSISQL.equals(getType());
216    }
217
218    public String getSqlTemplatePath() {
219        return sqlTemplatePath;
220    }
221
222    public void setSqlTemplatePath(String sqlTemplatePath) {
223        this.sqlTemplatePath = sqlTemplatePath;
224    }
225
226    public String getSqlTemplate() {
227        return sqlTemplate;
228    }
229
230    public void setSqlTemplate(String sqlTemplate) {
231        this.sqlTemplate = sqlTemplate;
232    }
233
234    public String getFactory() {
235        return factory;
236    }
237
238    public void setFactory(String factory) {
239        this.factory = factory;
240    }
241
242    public String getPoolName() {
243        return poolName;
244    }
245
246    public void setPoolName(String poolName) {
247        this.poolName = poolName;
248    }
249
250    public boolean isNeedAddMapping() {
251        return needAddMapping;
252    }
253
254    public void setNeedAddMapping(boolean needAddMapping) {
255        this.needAddMapping = needAddMapping;
256    }
257
258    public String getShardingConfigYaml() {
259        return shardingConfigYaml;
260    }
261
262    public void setShardingConfigYaml(String shardingConfigYaml) {
263        this.shardingConfigYaml = shardingConfigYaml;
264    }
265
266    public String getDbProFactory() {
267        return dbProFactory;
268    }
269
270    public void setDbProFactory(String dbProFactory) {
271        this.dbProFactory = dbProFactory;
272    }
273
274    public String getContainerFactory() {
275        return containerFactory;
276    }
277
278    public void setContainerFactory(String containerFactory) {
279        this.containerFactory = containerFactory;
280    }
281
282    public Integer getTransactionLevel() {
283        return transactionLevel;
284    }
285
286    public void setTransactionLevel(Integer transactionLevel) {
287        this.transactionLevel = transactionLevel;
288    }
289
290    public String getTable() {
291        return table;
292    }
293
294    public void setTable(String table) {
295        this.table = table;
296    }
297
298    public String getExTable() {
299        return exTable;
300    }
301
302    public void setExTable(String exTable) {
303        this.exTable = exTable;
304    }
305
306    public String getTablePrefix() {
307        return tablePrefix;
308    }
309
310    public void setTablePrefix(String tablePrefix) {
311        this.tablePrefix = tablePrefix;
312    }
313
314    public Long getMaxLifetime() {
315        return maxLifetime;
316    }
317
318    public void setMaxLifetime(Long maxLifetime) {
319        this.maxLifetime = maxLifetime;
320    }
321
322    public Long getIdleTimeout() {
323        return idleTimeout;
324    }
325
326    public void setIdleTimeout(Long idleTimeout) {
327        this.idleTimeout = idleTimeout;
328    }
329
330    public Integer getMinimumIdle() {
331        return minimumIdle;
332    }
333
334    public void setMinimumIdle(Integer minimumIdle) {
335        this.minimumIdle = minimumIdle;
336    }
337
338    public String getDialectClass() {
339        return dialectClass;
340    }
341
342    public void setDialectClass(String dialectClass) {
343        this.dialectClass = dialectClass;
344    }
345
346    public String getActiveRecordPluginClass() {
347        return activeRecordPluginClass;
348    }
349
350    public void setActiveRecordPluginClass(String activeRecordPluginClass) {
351        this.activeRecordPluginClass = activeRecordPluginClass;
352    }
353
354    public long getMaxWait() {
355        return maxWait;
356    }
357
358    public void setMaxWait(long maxWait) {
359        this.maxWait = maxWait;
360    }
361
362    public long getTimeBetweenEvictionRunsMillis() {
363        return timeBetweenEvictionRunsMillis;
364    }
365
366    public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
367        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
368    }
369
370    public long getMinEvictableIdleTimeMillis() {
371        return minEvictableIdleTimeMillis;
372    }
373
374    public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
375        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
376    }
377
378    public long getTimeBetweenConnectErrorMillis() {
379        return timeBetweenConnectErrorMillis;
380    }
381
382    public void setTimeBetweenConnectErrorMillis(long timeBetweenConnectErrorMillis) {
383        this.timeBetweenConnectErrorMillis = timeBetweenConnectErrorMillis;
384    }
385
386    public String getValidationQuery() {
387        if (validationQuery != null) {
388            return validationQuery;
389        }
390        if (this.url == null) {
391            return null;
392        }
393        String url = this.url.toLowerCase();
394        if (url.startsWith("jdbc:oracle")) {
395            return "select 1 from dual";
396        } else if (url.startsWith("jdbc:db2")) {
397            return "select 1 from sysibm.sysdummy1";
398        } else if (url.startsWith("jdbc:hsqldb")) {
399            return "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS";
400        } else if (url.startsWith("jdbc:derby")) {
401            return "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS";
402        }
403        return "select 1";
404    }
405
406    public void setValidationQuery(String validationQuery) {
407        this.validationQuery = validationQuery;
408    }
409
410    public boolean isTestWhileIdle() {
411        return testWhileIdle;
412    }
413
414    public void setTestWhileIdle(boolean testWhileIdle) {
415        this.testWhileIdle = testWhileIdle;
416    }
417
418    public boolean isTestOnBorrow() {
419        return testOnBorrow;
420    }
421
422    public void setTestOnBorrow(boolean testOnBorrow) {
423        this.testOnBorrow = testOnBorrow;
424    }
425
426    public boolean isTestOnReturn() {
427        return testOnReturn;
428    }
429
430    public void setTestOnReturn(boolean testOnReturn) {
431        this.testOnReturn = testOnReturn;
432    }
433
434
435    private List<TableInfo> tableInfos;
436
437    /**
438     * 添加表信息
439     *
440     * @param tableInfo      表信息
441     * @param fromDesignated 是否是通过 jboot.datasource.table 或者 @table(datasource="xxx") 来指定的
442     */
443    public void addTableInfo(TableInfo tableInfo, boolean fromDesignated) {
444        if (tableInfos == null) {
445            tableInfos = new ArrayList<>();
446        }
447
448        if (!tableInfos.contains(tableInfo) && tableInfo.addAttachedDatasource(this, fromDesignated)) {
449            tableInfos.add(tableInfo);
450        }
451    }
452
453    public void removeTableInfo(TableInfo tableInfo) {
454        if (tableInfos != null) {
455            tableInfos.remove(tableInfo);
456        }
457    }
458
459
460    public List<TableInfo> getTableInfos() {
461        return tableInfos;
462    }
463
464    public Long getKeepaliveTime() {
465        return keepaliveTime;
466    }
467
468    public void setKeepaliveTime(Long keepaliveTime) {
469        this.keepaliveTime = keepaliveTime;
470    }
471}