Browse Source

db support remarks etc propertis

Looly 5 years ago
parent
commit
9c434da9fb

+ 3 - 1
CHANGELOG.md

@@ -3,7 +3,7 @@
 
 -------------------------------------------------------------------------------------------------------------
 
-## 5.3.8 (2020-06-15)
+## 5.3.8 (2020-06-16)
 
 ### 新特性
 * 【core   】     增加ISO8601日期格式(issue#904@Github)
@@ -12,6 +12,8 @@
 * 【core   】     复制创建一个Bean对象, 并忽略某些属性(pr#130@Gitee)
 * 【core   】     DateUtil.parse支持更多日期格式(issue#I1KHTB@Gitee)
 * 【crypto 】     增加获取密钥空指针的检查(issue#925@Github)
+* 【core   】     增加StrUtil.removeAny方法(issue#923@Github)
+* 【db     】     增加部分Connection参数支持(issue#924@Github)
 
 ### Bug修复
 * 【json   】     修复append方法导致的JSONConfig传递失效问题(issue#906@Github)

+ 19 - 0
hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java

@@ -966,6 +966,25 @@ public class StrUtil {
 	}
 
 	/**
+	 * 移除字符串中所有给定字符串,当某个字符串出现多次,则全部移除<br>
+	 * 例:removeAny("aa-bb-cc-dd", "a", "b") =》 --cc-dd
+	 *
+	 * @param str         字符串
+	 * @param strsToRemove 被移除的字符串
+	 * @return 移除后的字符串
+	 * @since 5.3.8
+	 */
+	public static String removeAny(CharSequence str, CharSequence... strsToRemove) {
+		String result = str(str);
+		if (isNotEmpty(str)) {
+			for (CharSequence strToRemove : strsToRemove) {
+				result = removeAll(str, strToRemove);
+			}
+		}
+		return result;
+	}
+
+	/**
 	 * 去除字符串中指定的多个字符,如有多个则全部去除
 	 *
 	 * @param str   字符串

+ 7 - 5
hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java

@@ -1,10 +1,5 @@
 package cn.hutool.db.ds;
 
-import java.io.Closeable;
-import java.io.Serializable;
-
-import javax.sql.DataSource;
-
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.c3p0.C3p0DSFactory;
 import cn.hutool.db.ds.dbcp.DbcpDSFactory;
@@ -16,6 +11,10 @@ import cn.hutool.log.Log;
 import cn.hutool.log.LogFactory;
 import cn.hutool.setting.Setting;
 
+import javax.sql.DataSource;
+import java.io.Closeable;
+import java.io.Serializable;
+
 /**
  * 抽象数据源工厂类<br>
  * 通过实现{@link #getDataSource(String)} 方法实现数据源的获取<br>
@@ -29,6 +28,9 @@ public abstract class DSFactory implements Closeable, Serializable{
 
 	private static final Log log = LogFactory.get();
 
+	/** 某些数据库需要的特殊配置项需要的配置项 */
+	public static final String[] KEY_CONN_PROPS = {"remarks", "useInformationSchema"};
+
 	/** 别名字段名:URL */
 	public static final String[] KEY_ALIAS_URL = { "url", "jdbcUrl" };
 	/** 别名字段名:驱动名 */

+ 21 - 8
hutool-db/src/main/java/cn/hutool/db/ds/c3p0/C3p0DSFactory.java

@@ -1,14 +1,14 @@
 package cn.hutool.db.ds.c3p0;
 
-import java.beans.PropertyVetoException;
-
-import javax.sql.DataSource;
-
-import com.mchange.v2.c3p0.ComboPooledDataSource;
-
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.DbRuntimeException;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
+import cn.hutool.setting.dialect.Props;
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+
+import javax.sql.DataSource;
+import java.beans.PropertyVetoException;
 
 /**
  * Druid数据源工厂类
@@ -48,8 +48,21 @@ public class C3p0DSFactory extends AbstractDSFactory {
 		}
 		ds.setUser(user);
 		ds.setPassword(pass);
-		poolSetting.toBean(ds);// 注入属性
-		
+
+		// remarks等特殊配置,since 5.3.8
+		final Props connProps = new Props();
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.getAndRemoveStr(key);
+			if(StrUtil.isNotBlank(connValue)){
+				connProps.setProperty(key, connValue);
+			}
+		}
+		ds.setProperties(connProps);
+
+		// 注入属性
+		poolSetting.toBean(ds);
+
 		return ds;
 	}
 }

+ 17 - 6
hutool-db/src/main/java/cn/hutool/db/ds/dbcp/DbcpDSFactory.java

@@ -1,11 +1,11 @@
 package cn.hutool.db.ds.dbcp;
 
-import javax.sql.DataSource;
-
-import org.apache.commons.dbcp2.BasicDataSource;
-
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
+import org.apache.commons.dbcp2.BasicDataSource;
+
+import javax.sql.DataSource;
 
 /**
  * DBCP2数据源工厂类
@@ -34,8 +34,19 @@ public class DbcpDSFactory extends AbstractDSFactory {
 		ds.setDriverClassName(driver);
 		ds.setUsername(user);
 		ds.setPassword(pass);
-		poolSetting.toBean(ds);// 注入属性
-		
+
+		// remarks等特殊配置,since 5.3.8
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.getAndRemoveStr(key);
+			if(StrUtil.isNotBlank(connValue)){
+				ds.addConnectionProperty(key, connValue);
+			}
+		}
+
+		// 注入属性
+		poolSetting.toBean(ds);
+
 		return ds;
 	}
 }

+ 16 - 14
hutool-db/src/main/java/cn/hutool/db/ds/druid/DruidDSFactory.java

@@ -1,15 +1,12 @@
 package cn.hutool.db.ds.druid;
 
-import java.util.Map.Entry;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-
-import com.alibaba.druid.pool.DruidDataSource;
-
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
+import cn.hutool.setting.dialect.Props;
+import com.alibaba.druid.pool.DruidDataSource;
+
+import javax.sql.DataSource;
 
 /**
  * Druid数据源工厂类
@@ -42,19 +39,24 @@ public class DruidDSFactory extends AbstractDSFactory {
 	protected DataSource createDataSource(String jdbcUrl, String driver, String user, String pass, Setting poolSetting) {
 		final DruidDataSource ds = new DruidDataSource();
 
+		// 基本信息
 		ds.setUrl(jdbcUrl);
 		ds.setDriverClassName(driver);
 		ds.setUsername(user);
 		ds.setPassword(pass);
 
-		// 规范化属性名
-		Properties druidProps = new Properties();
-		String keyStr;
-		for (Entry<String, String> entry : poolSetting.entrySet()) {
-			keyStr = StrUtil.addPrefixIfNot(entry.getKey(), "druid.");
-			druidProps.put(keyStr, entry.getValue());
+		// remarks等特殊配置,since 5.3.8
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.getAndRemoveStr(key);
+			if(StrUtil.isNotBlank(connValue)){
+				ds.addConnectionProperty(key, connValue);
+			}
 		}
-		// 连接池信息
+
+		// Druid连接池配置信息,规范化属性名
+		final Props druidProps = new Props();
+		poolSetting.forEach((key, value)-> druidProps.put(StrUtil.addPrefixIfNot(key, "druid."), value));
 		ds.configFromPropety(druidProps);
 
 		// 检查关联配置,在用户未设置某项配置时,

+ 20 - 6
hutool-db/src/main/java/cn/hutool/db/ds/hikari/HikariDSFactory.java

@@ -1,13 +1,14 @@
 package cn.hutool.db.ds.hikari;
 
-import javax.sql.DataSource;
-
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
 import cn.hutool.setting.dialect.Props;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+import javax.sql.DataSource;
 
 /**
  * HikariCP数据源工厂类
@@ -30,6 +31,16 @@ public class HikariDSFactory extends AbstractDSFactory {
 
 	@Override
 	protected DataSource createDataSource(String jdbcUrl, String driver, String user, String pass, Setting poolSetting) {
+		// remarks等特殊配置,since 5.3.8
+		final Props connProps = new Props();
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.getAndRemoveStr(key);
+			if(StrUtil.isNotBlank(connValue)){
+				connProps.setProperty(key, connValue);
+			}
+		}
+
 		final Props config = new Props();
 		config.putAll(poolSetting);
 
@@ -44,6 +55,9 @@ public class HikariDSFactory extends AbstractDSFactory {
 			config.put("password", pass);
 		}
 
-		return new HikariDataSource(new HikariConfig(config));
+		final HikariConfig hikariConfig = new HikariConfig(config);
+		hikariConfig.setDataSourceProperties(connProps);
+
+		return new HikariDataSource(hikariConfig);
 	}
 }

+ 54 - 18
hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbConfig.java

@@ -3,32 +3,38 @@ package cn.hutool.db.ds.pooled;
 import cn.hutool.db.DbRuntimeException;
 import cn.hutool.db.dialect.DriverUtil;
 
+import java.util.Properties;
+
 /**
  * 数据库配置
- * @author Looly
  *
+ * @author Looly
  */
 public class DbConfig {
-	
+
 	//-------------------------------------------------------------------- Fields start
-	private String driver;		//数据库驱动
-	private String url;			//jdbc url
-	private String user;			//用户名
-	private String pass;			//密码
-	
-	private int initialSize;		//初始连接数
-	private int minIdle;			//最小闲置连接数
-	private int maxActive;		//最大活跃连接数
-	private long maxWait;		//获取连接的超时等待
+	private String driver;        //数据库驱动
+	private String url;            //jdbc url
+	private String user;            //用户名
+	private String pass;            //密码
+
+	private int initialSize;        //初始连接数
+	private int minIdle;            //最小闲置连接数
+	private int maxActive;        //最大活跃连接数
+	private long maxWait;        //获取连接的超时等待
+
+	// 连接配置
+	private Properties connProps;
 	//-------------------------------------------------------------------- Fields end
-	
+
 	//-------------------------------------------------------------------- Constructor start
 	public DbConfig() {
 	}
-	
+
 	/**
 	 * 构造
-	 * @param url jdbc url
+	 *
+	 * @param url  jdbc url
 	 * @param user 用户名
 	 * @param pass 密码
 	 */
@@ -36,10 +42,11 @@ public class DbConfig {
 		init(url, user, pass);
 	}
 	//-------------------------------------------------------------------- Constructor end
-	
+
 	/**
 	 * 初始化
-	 * @param url jdbc url
+	 *
+	 * @param url  jdbc url
 	 * @param user 用户名
 	 * @param pass 密码
 	 */
@@ -54,56 +61,85 @@ public class DbConfig {
 			throw new DbRuntimeException(e, "Get jdbc driver from [{}] error!", url);
 		}
 	}
-	
+
 	//-------------------------------------------------------------------- Getters and Setters start
 	public String getDriver() {
 		return driver;
 	}
+
 	public void setDriver(String driver) {
 		this.driver = driver;
 	}
+
 	public String getUrl() {
 		return url;
 	}
+
 	public void setUrl(String url) {
 		this.url = url;
 	}
+
 	public String getUser() {
 		return user;
 	}
+
 	public void setUser(String user) {
 		this.user = user;
 	}
+
 	public String getPass() {
 		return pass;
 	}
+
 	public void setPass(String pass) {
 		this.pass = pass;
 	}
-	
+
 	public int getInitialSize() {
 		return initialSize;
 	}
+
 	public void setInitialSize(int initialSize) {
 		this.initialSize = initialSize;
 	}
+
 	public int getMinIdle() {
 		return minIdle;
 	}
+
 	public void setMinIdle(int minIdle) {
 		this.minIdle = minIdle;
 	}
+
 	public int getMaxActive() {
 		return maxActive;
 	}
+
 	public void setMaxActive(int maxActive) {
 		this.maxActive = maxActive;
 	}
+
 	public long getMaxWait() {
 		return maxWait;
 	}
+
 	public void setMaxWait(long maxWait) {
 		this.maxWait = maxWait;
 	}
+
+	public Properties getConnProps() {
+		return connProps;
+	}
+
+	public void setConnProps(Properties connProps) {
+		this.connProps = connProps;
+	}
+
+	public void addConnProps(String key, String value){
+		if(null == this.connProps){
+			this.connProps = new Properties();
+		}
+		this.connProps.setProperty(key, value);
+	}
 	//-------------------------------------------------------------------- Getters and Setters end
 }

+ 9 - 0
hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbSetting.java

@@ -71,6 +71,15 @@ public class DbSetting {
 		dbConfig.setMaxActive(setting.getInt("maxActive", group, 8));
 		dbConfig.setMaxWait(setting.getLong("maxWait", group, 6000L));
 
+		// remarks等特殊配置,since 5.3.8
+		String connValue;
+		for (String key : DSFactory.KEY_CONN_PROPS) {
+			connValue = config.get(key);
+			if(StrUtil.isNotBlank(connValue)){
+				dbConfig.addConnProps(key, connValue);
+			}
+		}
+
 		return dbConfig;
 	}
 }

+ 30 - 4
hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledConnection.java

@@ -1,10 +1,13 @@
 package cn.hutool.db.ds.pooled;
 
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.db.DbUtil;
+import cn.hutool.setting.dialect.Props;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.util.Properties;
 
 /**
  * 池化
@@ -15,11 +18,34 @@ public class PooledConnection extends ConnectionWraper{
 	
 	private final PooledDataSource ds;
 	private boolean isClosed;
-	
+
+	/**
+	 * 构造
+	 *
+	 * @param ds 数据源
+	 * @throws SQLException SQL异常
+	 */
 	public PooledConnection(PooledDataSource ds) throws SQLException {
 		this.ds = ds;
-		DbConfig config = ds.getConfig();
-		this.raw = DriverManager.getConnection(config.getUrl(), config.getUser(), config.getPass());
+		final DbConfig config = ds.getConfig();
+
+		final Props info = new Props();
+		final String user = config.getUser();
+		if (user != null) {
+			info.setProperty("user", user);
+		}
+		final String password = config.getPass();
+		if (password != null) {
+			info.setProperty("password", password);
+		}
+
+		// 其它参数
+		final Properties connProps = config.getConnProps();
+		if(MapUtil.isNotEmpty(connProps)){
+			info.putAll(connProps);
+		}
+
+		this.raw = DriverManager.getConnection(config.getUrl(), info);
 	}
 	
 	public PooledConnection(PooledDataSource ds, Connection conn) {
@@ -31,7 +57,7 @@ public class PooledConnection extends ConnectionWraper{
 	 * 重写关闭连接,实际操作是归还到连接池中
 	 */
 	@Override
-	public void close() throws SQLException {
+	public void close() {
 		this.ds.free(this);
 		this.isClosed = true;
 	}

+ 12 - 2
hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledDSFactory.java

@@ -1,10 +1,11 @@
 package cn.hutool.db.ds.pooled;
 
-import javax.sql.DataSource;
-
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
 
+import javax.sql.DataSource;
+
 /**
  * Hutool自身实现的池化数据源工厂类
  * 
@@ -38,6 +39,15 @@ public class PooledDSFactory extends AbstractDSFactory {
 		dbConfig.setMaxActive(poolSetting.getInt("maxActive", 8));
 		dbConfig.setMaxWait(poolSetting.getLong("maxWait", 6000L));
 
+		// remarks等特殊配置,since 5.3.8
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.get(key);
+			if(StrUtil.isNotBlank(connValue)){
+				dbConfig.addConnProps(key, connValue);
+			}
+		}
+
 		return new PooledDataSource(dbConfig);
 	}
 }

+ 5 - 4
hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDSFactory.java

@@ -1,10 +1,10 @@
 package cn.hutool.db.ds.simple;
 
-import javax.sql.DataSource;
-
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
 
+import javax.sql.DataSource;
+
 /**
  * 简单数据源工厂类
  * 
@@ -26,12 +26,13 @@ public class SimpleDSFactory extends AbstractDSFactory {
 
 	@Override
 	protected DataSource createDataSource(String jdbcUrl, String driver, String user, String pass, Setting poolSetting) {
-		return new SimpleDataSource(//
+		SimpleDataSource ds = new SimpleDataSource(//
 				jdbcUrl, //
 				user, //
 				pass, //
 				driver//
 		);
+		ds.setConnProps(poolSetting.getProps(Setting.DEFAULT_GROUP));
+		return ds;
 	}
-
 }

+ 44 - 7
hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDataSource.java

@@ -1,16 +1,18 @@
 package cn.hutool.db.ds.simple;
 
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.DbRuntimeException;
 import cn.hutool.db.dialect.DriverUtil;
 import cn.hutool.db.ds.DSFactory;
 import cn.hutool.setting.Setting;
+import cn.hutool.setting.dialect.Props;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
 
 /***
  * 简易数据源,没有使用连接池,仅供测试或打开关闭连接非常少的场合使用!
@@ -28,6 +30,9 @@ public class SimpleDataSource extends AbstractDataSource {
 	private String url; // jdbc url
 	private String user; // 用户名
 	private String pass; // 密码
+
+	// 连接配置
+	private Properties connProps;
 	// -------------------------------------------------------------------- Fields end
 
 	/**
@@ -87,6 +92,9 @@ public class SimpleDataSource extends AbstractDataSource {
 				config.getAndRemoveStr(DSFactory.KEY_ALIAS_PASSWORD), //
 				config.getAndRemoveStr(DSFactory.KEY_ALIAS_DRIVER)//
 		);
+
+		// 其它连接参数
+		this.connProps = config.getProps(Setting.DEFAULT_GROUP);
 	}
 
 	/**
@@ -178,11 +186,40 @@ public class SimpleDataSource extends AbstractDataSource {
 	public void setPass(String pass) {
 		this.pass = pass;
 	}
+
+	public Properties getConnProps() {
+		return connProps;
+	}
+
+	public void setConnProps(Properties connProps) {
+		this.connProps = connProps;
+	}
+
+	public void addConnProps(String key, String value){
+		if(null == this.connProps){
+			this.connProps = new Properties();
+		}
+		this.connProps.setProperty(key, value);
+	}
 	// -------------------------------------------------------------------- Getters and Setters end
 
 	@Override
 	public Connection getConnection() throws SQLException {
-		return DriverManager.getConnection(this.url, this.user, this.pass);
+		final Props info = new Props();
+		if (this.user != null) {
+			info.setProperty("user", this.user);
+		}
+		if (this.pass != null) {
+			info.setProperty("password", this.pass);
+		}
+
+		// 其它参数
+		final Properties connProps = this.connProps;
+		if(MapUtil.isNotEmpty(connProps)){
+			info.putAll(connProps);
+		}
+
+		return DriverManager.getConnection(this.url, info);
 	}
 
 	@Override
@@ -191,7 +228,7 @@ public class SimpleDataSource extends AbstractDataSource {
 	}
 
 	@Override
-	public void close() throws IOException {
+	public void close() {
 		// Not need to close;
 	}
 }

+ 18 - 3
hutool-db/src/main/java/cn/hutool/db/ds/tomcat/TomcatDSFactory.java

@@ -1,10 +1,11 @@
 package cn.hutool.db.ds.tomcat;
 
-import org.apache.tomcat.jdbc.pool.DataSource;
-import org.apache.tomcat.jdbc.pool.PoolProperties;
-
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.ds.AbstractDSFactory;
 import cn.hutool.setting.Setting;
+import cn.hutool.setting.dialect.Props;
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.apache.tomcat.jdbc.pool.PoolProperties;
 
 /**
  * Tomcat-Jdbc-Pool数据源工厂类
@@ -40,6 +41,20 @@ public class TomcatDSFactory extends AbstractDSFactory {
 		poolProps.setDriverClassName(driver);
 		poolProps.setUsername(user);
 		poolProps.setPassword(pass);
+
+		// remarks等特殊配置,since 5.3.8
+		final Props connProps = new Props();
+		String connValue;
+		for (String key : KEY_CONN_PROPS) {
+			connValue = poolSetting.getAndRemoveStr(key);
+			if(StrUtil.isNotBlank(connValue)){
+				connProps.setProperty(key, connValue);
+			}
+		}
+		poolProps.setDbProperties(connProps);
+
+		// 连接池相关参数
+		poolSetting.toBean(poolProps);
 		
 		return new DataSource(poolProps);
 	}

+ 7 - 0
hutool-db/src/main/java/cn/hutool/db/meta/MetaUtil.java

@@ -18,6 +18,13 @@ import java.util.List;
 /**
  * 数据库元数据信息工具类
  *
+ * <p>
+ * 需要注意的是,此工具类在某些数据库(比如Oracle)下无效,此时需要手动在数据库配置中增加:
+ * <pre>
+ *  remarks = true
+ *  useInformationSchema = true
+ * </pre>
+ *
  * @author looly
  */
 public class MetaUtil {

+ 10 - 1
hutool-db/src/test/resources/config/db.setting

@@ -18,45 +18,54 @@ sqlLevel = debug
 
 # 默认数据源
 url = jdbc:sqlite:test.db
+remarks = true
 
 
 # 测试数据源
 [test]
 url = jdbc:sqlite:test.db
+remarks = true
 
 # 测试用HSQLDB数据库
 [hsqldb]
 url = jdbc:hsqldb:mem:mem_hutool
 user = SA
 pass =
+remarks = true
 
 # 测试用HSQLDB数据库
 [h2]
 url = jdbc:h2:mem:h2_hutool
 user = sa
 pass =
+remarks = true
 
 # 测试用HSQLDB数据库
 [derby]
 url = jdbc:derby:.derby/test_db;create=true
+remarks = true
 
 # 测试用Oracle数据库
 [orcl]
 url = jdbc:oracle:thin:@//looly.centos:1521/XE
 user = looly
 pass = 123456
+remarks = true
 
 [mysql]
 url = jdbc:mysql://looly.centos8:3306/hutool_test?useSSL=false
 user = root
 pass = 123456
+remarks = true
 
 [postgre]
 url = jdbc:postgresql://looly.centos:5432/test_hutool
 user = postgres
 pass = 123456
+remarks = true
 
 [sqlserver]
 url = jdbc:sqlserver://looly.database.chinacloudapi.cn:1433;database=test;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.chinacloudapi.cn;loginTimeout=30;
 user = looly@looly
-pass = 123
+pass = 123
+remarks = true