u
This commit is contained in:
1 parent
c570ec514c
commit
a4827cb646
9 files changed
+479
-83
No files matched your search
@@ -1,5 +1,6 @@
|
||||
package cn.g3soft;
|
||||
|
||||
import cn.g3soft.utils.SnowflakeIdUtils;
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@@ -11,6 +12,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
})
|
||||
public class BaseApplication {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(SnowflakeIdUtils.nextId());
|
||||
SpringApplication.run(BaseApplication.class,args);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package cn.g3soft.common;
|
||||
|
||||
import cn.g3soft.enums.ResponseEnum;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Data
|
||||
public class Result<T> {
|
||||
private final Integer code;
|
||||
private final String message;
|
||||
@NonNull
|
||||
private final T data;
|
||||
private final Boolean showExceptionDetail;
|
||||
|
||||
private Result(Integer code, String message, T data, Boolean showExceptionDetail) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
this.showExceptionDetail = showExceptionDetail;
|
||||
}
|
||||
|
||||
// 默认showDetail为false的构造
|
||||
private Result(Integer code, String message, T data) {
|
||||
this(code, message, data, false);
|
||||
}
|
||||
|
||||
// ✅ 链式设置 showExceptionDetail:返回一个新对象
|
||||
public Result<T> withShowExceptionDetail(boolean showExceptionDetail) {
|
||||
return new Result<>(this.code, this.message, this.data, showExceptionDetail);
|
||||
}
|
||||
|
||||
// 成功响应(无数据)
|
||||
public static <T> Result<T> success() {
|
||||
return new Result<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMessage(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(String message) {
|
||||
return new Result<>(ResponseEnum.SUCCESS.getCode(), message, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(@NonNull T data) {
|
||||
return new Result<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMessage(), data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(@NonNull T data, String message) {
|
||||
return new Result<>(ResponseEnum.SUCCESS.getCode(), message, data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(ResponseEnum responseEnum) {
|
||||
return new Result<>(responseEnum.getCode(), responseEnum.getMessage(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(ResponseEnum responseEnum, @NonNull T data) {
|
||||
return new Result<>(responseEnum.getCode(), responseEnum.getMessage(), data);
|
||||
}
|
||||
|
||||
// 错误响应(默认不显示详细信息)
|
||||
public static <T> Result<T> error(ResponseEnum responseEnum) {
|
||||
return new Result<>(responseEnum.getCode(), responseEnum.getMessage(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(Integer code, String message) {
|
||||
return new Result<>(code, message, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String message) {
|
||||
return new Result<>(ResponseEnum.ERROR.getCode(), message, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(T data) {
|
||||
return new Result<>(ResponseEnum.ERROR.getCode(), ResponseEnum.ERROR.getMessage(), data);
|
||||
}
|
||||
public static <T> Result<T> error(T data,String message) {
|
||||
return new Result<>(ResponseEnum.ERROR.getCode(),message, data);
|
||||
}
|
||||
public static <T> Result<T> error() {
|
||||
return new Result<>(ResponseEnum.ERROR.getCode(), ResponseEnum.ERROR.getMessage(), null);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cn.g3soft.common.model;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@Data
|
||||
@Builder
|
||||
public class ExceptionEntity {
|
||||
/** 异常记录的唯一ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 异常发生时间 */
|
||||
private Date time;
|
||||
|
||||
/** 请求的URI地址 */
|
||||
private String uri;
|
||||
|
||||
/** HTTP请求方法,如GET、POST等 */
|
||||
private String httpMethod;
|
||||
|
||||
/** 抛出异常的类名 */
|
||||
private String className;
|
||||
|
||||
/** 抛出异常的方法名 */
|
||||
private String methodName;
|
||||
|
||||
/** 抛出异常的文件名 */
|
||||
private String fileName;
|
||||
|
||||
/** 抛出异常的代码行号 */
|
||||
private Integer lineNumber;
|
||||
|
||||
/** 异常的简短信息 */
|
||||
private String summary;
|
||||
|
||||
/** 异常的详细堆栈信息 */
|
||||
private String detailMessage;
|
||||
|
||||
/** 请求参数(可能为JSON字符串等) */
|
||||
private String params;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package cn.g3soft.common.model;
|
||||
|
||||
import cn.g3soft.enums.ResponseEnum;
|
||||
import lombok.NonNull;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder(toBuilder = true)
|
||||
public class Result<T> {
|
||||
private final Integer code;
|
||||
private final String message;
|
||||
private final T data;
|
||||
private final Boolean showExceptionDetail;
|
||||
|
||||
// 工厂方法建议保留,简化构造调用
|
||||
public static <T> Result<T> success() {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.SUCCESS.getCode())
|
||||
.message(ResponseEnum.SUCCESS.getMessage())
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(String message) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.SUCCESS.getCode())
|
||||
.message(message)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(@NonNull T data) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.SUCCESS.getCode())
|
||||
.message(ResponseEnum.SUCCESS.getMessage())
|
||||
.data(data)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(@NonNull T data, String message) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.SUCCESS.getCode())
|
||||
.message(message)
|
||||
.data(data)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(ResponseEnum responseEnum) {
|
||||
return Result.<T>builder()
|
||||
.code(responseEnum.getCode())
|
||||
.message(responseEnum.getMessage())
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(ResponseEnum responseEnum, @NonNull T data) {
|
||||
return Result.<T>builder()
|
||||
.code(responseEnum.getCode())
|
||||
.message(responseEnum.getMessage())
|
||||
.data(data)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error() {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.ERROR.getCode())
|
||||
.message(ResponseEnum.ERROR.getMessage())
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String message) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.ERROR.getCode())
|
||||
.message(message)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(Integer code, String message) {
|
||||
return Result.<T>builder()
|
||||
.code(code)
|
||||
.message(message)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(ResponseEnum responseEnum) {
|
||||
return Result.<T>builder()
|
||||
.code(responseEnum.getCode())
|
||||
.message(responseEnum.getMessage())
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(T data) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.ERROR.getCode())
|
||||
.message(ResponseEnum.ERROR.getMessage())
|
||||
.data(data)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(T data, String message) {
|
||||
return Result.<T>builder()
|
||||
.code(ResponseEnum.ERROR.getCode())
|
||||
.message(message)
|
||||
.data(data)
|
||||
.showExceptionDetail(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Result<T> withShowExceptionDetail(boolean show) {
|
||||
return this.toBuilder().showExceptionDetail(show).build();
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return ResponseEnum.SUCCESS.getCode().equals(this.code);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,12 +1,11 @@
|
||||
package cn.g3soft.exception;
|
||||
|
||||
import cn.g3soft.common.Result;
|
||||
import cn.g3soft.common.model.Result;
|
||||
import cn.g3soft.exception.auth.AuthException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import cn.g3soft.common.model.ExceptionEntity;
|
||||
import cn.g3soft.exception.BaseException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExceptionUtils {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 根据异常和请求信息,生成统一的异常信息对象 ExceptionDetailInfo
|
||||
* @param ex 异常对象
|
||||
* @param request HttpServletRequest,用来获取请求路径和方法等
|
||||
* @param projectBasePackage 项目基础包名,如 "com.error",用来定位业务代码异常栈帧
|
||||
* @return ExceptionDetailInfo 封装的异常信息
|
||||
*/
|
||||
public static ExceptionEntity extractExceptionInfo(Exception ex, HttpServletRequest request, String projectBasePackage) {
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
|
||||
StackTraceElement source = null;
|
||||
if (stackTrace != null) {
|
||||
for (StackTraceElement element : stackTrace) {
|
||||
if (element.getClassName().startsWith(projectBasePackage)) {
|
||||
source = element;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (source == null && stackTrace.length > 0) {
|
||||
source = stackTrace[0];
|
||||
}
|
||||
}
|
||||
|
||||
String briefMessage;
|
||||
|
||||
if (ex instanceof BaseException) {
|
||||
BaseException be = (BaseException) ex;
|
||||
briefMessage = be.getMessage();
|
||||
} else {
|
||||
if (ex.getMessage() != null) {
|
||||
String[] lines = ex.getMessage().split("\n");
|
||||
// 遍历每一行,找到第一行“非空、非符号”的有效信息
|
||||
String usefulLine = null;
|
||||
for (String line : lines) {
|
||||
String trimmed = line.trim();
|
||||
if (!trimmed.isEmpty()) {
|
||||
usefulLine = trimmed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 如果找到有效行,就用它;否则仅用异常类名
|
||||
if (usefulLine != null) {
|
||||
briefMessage = ex.getClass().getSimpleName() + ": " + usefulLine;
|
||||
} else {
|
||||
briefMessage = ex.getClass().getSimpleName();
|
||||
}
|
||||
} else {
|
||||
briefMessage = ex.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
String paramJson = null;
|
||||
if (request != null) {
|
||||
Map<String, String> paramMap = new HashMap<>();
|
||||
Enumeration<String> paramNames = request.getParameterNames();
|
||||
while (paramNames.hasMoreElements()) {
|
||||
String paramName = paramNames.nextElement();
|
||||
paramMap.put(paramName, request.getParameter(paramName));
|
||||
}
|
||||
try {
|
||||
paramJson = JsonUtils.toJson(paramMap);
|
||||
} catch (Exception e) {
|
||||
paramJson = "参数序列化失败: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return ExceptionEntity.builder()
|
||||
.id(SnowflakeIdUtils.nextId())
|
||||
.uri(request != null ? request.getRequestURI() : null)
|
||||
.httpMethod(request != null ? request.getMethod() : null)
|
||||
.className(source != null ? source.getClassName() : null)
|
||||
.methodName(source != null ? source.getMethodName() : null)
|
||||
.fileName(source != null ? source.getFileName() : null)
|
||||
.lineNumber(source != null ? source.getLineNumber() : null)
|
||||
.summary(briefMessage)
|
||||
.detailMessage(org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(ex))
|
||||
.time(new Date())
|
||||
.params(paramJson)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class JsonUtils {
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
// 判断字符串是否为有效的 JSON 格式
|
||||
public static boolean isTypeJSON(String msgText) {
|
||||
try {
|
||||
// 尝试将字符串解析为 JsonNode,如果能解析,说明是有效的 JSON
|
||||
JsonNode node = objectMapper.readTree(msgText);
|
||||
return node != null;
|
||||
} catch (Exception e) {
|
||||
return false; // 如果抛出异常,说明不是有效的 JSON
|
||||
}
|
||||
}
|
||||
|
||||
// 将 JSON 字符串转换为指定类型的 Java 对象
|
||||
public static <T> T toBean(String json, Class<T> clazz) {
|
||||
try {
|
||||
// 使用 ObjectMapper 将 JSON 字符串转换为指定类型的对象
|
||||
return objectMapper.readValue(json, clazz);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace(); // 打印异常信息
|
||||
return null; // 如果转换失败,返回 null
|
||||
}
|
||||
}
|
||||
|
||||
// 将对象转换为 JSON 字符串
|
||||
public static String toJson(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj); // 将对象转换为 JSON 字符串
|
||||
} catch (JsonProcessingException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return null; // 如果出现异常,返回 null
|
||||
}
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class SnowflakeIdUtils {
|
||||
|
||||
public static long MAX_START_INTERVAL_TIME = TimeUnit.SECONDS.toNanos(5L);
|
||||
private static final long twepoch = 1288834974657L;
|
||||
|
||||
private static final long workerIdBits = 5L;
|
||||
private static final long datacenterIdBits = 5L;
|
||||
private static final long maxWorkerId = 31L;
|
||||
private static final long maxDatacenterId = 31L;
|
||||
private static final long sequenceBits = 12L;
|
||||
|
||||
private static final long workerIdShift = 12L;
|
||||
private static final long datacenterIdShift = 17L;
|
||||
private static final long timestampLeftShift = 22L;
|
||||
private static final long sequenceMask = 4095L;
|
||||
|
||||
// 这两个必须初始化
|
||||
private static long workerId;
|
||||
private static long datacenterId;
|
||||
|
||||
private static long sequence = 0L;
|
||||
private static long lastTimestamp = -1L;
|
||||
|
||||
private static InetAddress inetAddress;
|
||||
|
||||
// 初始化一次即可,线程安全调用
|
||||
public static synchronized void init(InetAddress address) {
|
||||
if (inetAddress == null) {
|
||||
inetAddress = address;
|
||||
datacenterId = getDatacenterId(maxDatacenterId);
|
||||
workerId = getMaxWorkerId(datacenterId, maxWorkerId);
|
||||
long start = System.nanoTime();
|
||||
long end = System.nanoTime();
|
||||
if (end - start > MAX_START_INTERVAL_TIME) {
|
||||
log.warn("Initialization Sequence Very Slow! Get datacenterId:{} workerId:{}", datacenterId, workerId);
|
||||
} else {
|
||||
initLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void init(long fixedWorkerId, long fixedDatacenterId) {
|
||||
Assert.isTrue(fixedWorkerId <= maxWorkerId && fixedWorkerId >= 0,
|
||||
String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
||||
Assert.isTrue(fixedDatacenterId <= maxDatacenterId && fixedDatacenterId >= 0,
|
||||
String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
||||
workerId = fixedWorkerId;
|
||||
datacenterId = fixedDatacenterId;
|
||||
initLog();
|
||||
}
|
||||
|
||||
private static void initLog() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Initialization Sequence datacenterId:{} workerId:{}", datacenterId, workerId);
|
||||
}
|
||||
}
|
||||
|
||||
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
|
||||
StringBuilder mpid = new StringBuilder();
|
||||
mpid.append(datacenterId);
|
||||
String name = ManagementFactory.getRuntimeMXBean().getName();
|
||||
if (StringUtils.isNotBlank(name)) {
|
||||
mpid.append(name.split("@")[0]);
|
||||
}
|
||||
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1L);
|
||||
}
|
||||
|
||||
protected static long getDatacenterId(long maxDatacenterId) {
|
||||
long id = 0L;
|
||||
try {
|
||||
if (inetAddress == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Use localhost address");
|
||||
}
|
||||
inetAddress = InetAddress.getLocalHost();
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get {} network interface", inetAddress);
|
||||
}
|
||||
NetworkInterface network = NetworkInterface.getByInetAddress(inetAddress);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get network interface info: {}", network);
|
||||
}
|
||||
if (network == null) {
|
||||
log.warn("Unable to get network interface for {}", inetAddress);
|
||||
id = 1L;
|
||||
} else {
|
||||
byte[] mac = network.getHardwareAddress();
|
||||
if (mac != null && mac.length >= 2) {
|
||||
id = ((0xffL & (long) mac[mac.length - 2]) | (0xff00L & ((long) mac[mac.length - 1] << 8))) >> 6;
|
||||
id %= maxDatacenterId + 1L;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("getDatacenterId error: {}", e.getMessage(), e);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public static synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
|
||||
if (timestamp < lastTimestamp) {
|
||||
long offset = lastTimestamp - timestamp;
|
||||
if (offset > 5L) {
|
||||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
|
||||
}
|
||||
try {
|
||||
SnowflakeIdUtils.class.wait(offset << 1);
|
||||
timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastTimestamp == timestamp) {
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (sequence == 0) {
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
sequence = ThreadLocalRandom.current().nextLong(1, 3);
|
||||
}
|
||||
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
return ((timestamp - twepoch) << timestampLeftShift)
|
||||
| (datacenterId << datacenterIdShift)
|
||||
| (workerId << workerIdShift)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
protected static long tilNextMillis(long lastTimestamp) {
|
||||
long timestamp = timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
protected static long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static long parseIdTimestamp(long id) {
|
||||
return (id >> 22) + 1288834974657L;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
datasource:
|
||||
db1:
|
||||
url: jdbc:jtds:sqlserver://192.168.1.176:1433;databaseName=G3-Email
|
||||
url: jdbc:jtds:sqlserver://127.0.0.1:1433;databaseName=test1
|
||||
username: sa
|
||||
password: sa
|
||||
driverClassName: net.sourceforge.jtds.jdbc.Driver
|
||||
db2:
|
||||
url: jdbc:jtds:sqlserver://192.168.1.176:1433;databaseName=Sllog
|
||||
url: jdbc:jtds:sqlserver://127.0.0.1:1433;databaseName=test2
|
||||
username: sa
|
||||
password: sa
|
||||
driverClassName: net.sourceforge.jtds.jdbc.Driver
|
||||
Reference in new issue
Block a user