---初始化项目
This commit is contained in:
@ -0,0 +1,16 @@
|
||||
package com.pictc.cache;
|
||||
|
||||
public abstract class AbstractCache<K,V> implements TanukiCache<K,V>{
|
||||
|
||||
private final String cache_name;
|
||||
|
||||
public AbstractCache(String name) {
|
||||
this.cache_name=name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCacheName() {
|
||||
return cache_name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.pictc.cache;
|
||||
|
||||
public class CacheFactory{
|
||||
|
||||
public static final String PROVIDER="provider-name";
|
||||
|
||||
public static final String PROVIDER_CLASS="provider-classpath";
|
||||
|
||||
public static <K, V> TanukiCache<K, V> factory(String cacheName) {
|
||||
return new DefaultCacheProvider<K, V>(cacheName);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
package com.pictc.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class DefaultCacheProvider<K,V> extends AbstractCache<K,V> implements TanukiCache<K,V>{
|
||||
|
||||
private final HashMap<K, V> cache;
|
||||
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
private final Lock readLock = lock.readLock();
|
||||
|
||||
private final Lock writeLock = lock.writeLock();
|
||||
|
||||
public DefaultCacheProvider(String cache_name) {
|
||||
super(cache_name);
|
||||
cache = new HashMap<K, V>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void save(K key, V value) {
|
||||
writeLock.lock();
|
||||
try {
|
||||
if(cache.containsKey(key)) cache.remove(key);
|
||||
cache.put(key, value);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
writeLock.lock();
|
||||
try {
|
||||
cache.remove(key);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public V get(K key) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return cache.get(key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean containsKey(K key) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return cache.containsKey(key);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
writeLock.lock();
|
||||
try {
|
||||
cache.clear();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> values() {
|
||||
return new ArrayList<V>(cache.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(K key, V value, long time, TimeUnit unit) {
|
||||
writeLock.lock();
|
||||
try {
|
||||
cache.put(key, value);
|
||||
setExpire(key, time, unit);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<K> keys() {
|
||||
return cache.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setExpire(K key, long time, TimeUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.pictc.cache;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface TanukiCache<K,V>{
|
||||
|
||||
String getCacheName();
|
||||
|
||||
void save(K key,V value);
|
||||
|
||||
void save(K key,V value,long time,TimeUnit unit);
|
||||
|
||||
boolean setExpire(K key,long time,TimeUnit unit);
|
||||
|
||||
void remove(K key);
|
||||
|
||||
V get(K key);
|
||||
|
||||
boolean containsKey(K key);
|
||||
|
||||
List<V> values();
|
||||
|
||||
Set<K> keys();
|
||||
|
||||
void clear();
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.pictc.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@ConfigurationProperties("datalog.db")
|
||||
@Data
|
||||
public class DataLogDbConfig {
|
||||
|
||||
private String url;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String driverClassName;
|
||||
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
package com.pictc.config;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.pictc.jdbc.JdbcContextUtils;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
@Configuration
|
||||
public class JdbcConfig {
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.master.username:itc_dne}")
|
||||
private String globalUsername;
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.master.password:itc_dne}")
|
||||
private String globalPassword;
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.master.driver-class-name:com.kingbase8.Driver}")
|
||||
private String globalDriver;
|
||||
|
||||
@Bean
|
||||
public JdbcContextUtils jdbcContextUtils() throws SQLException {
|
||||
JdbcContextUtils contextUtils = new JdbcContextUtils();
|
||||
contextUtils.setLogSource(logDataSource());
|
||||
return contextUtils;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataLogDbConfig logDataDbConfig() {
|
||||
return new DataLogDbConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 额外的日志数据源配置
|
||||
*/
|
||||
public DataSource logDataSource() throws SQLException {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
DataLogDbConfig dbConfig = logDataDbConfig();
|
||||
// 日志数据库连接信息
|
||||
dataSource.setUrl(dbConfig.getUrl());
|
||||
dataSource.setUsername(StringUtils.opt(dbConfig.getUsername(),globalUsername));
|
||||
dataSource.setPassword(StringUtils.opt(dbConfig.getPassword(),globalPassword));
|
||||
dataSource.setDriverClassName(StringUtils.opt(dbConfig.getDriverClassName(),globalDriver));
|
||||
|
||||
// 日志库连接池参数(可独立配置)
|
||||
dataSource.setInitialSize(5);
|
||||
dataSource.setMinIdle(3);
|
||||
dataSource.setMaxActive(20);
|
||||
dataSource.setMaxWait(20000);
|
||||
dataSource.setTimeBetweenEvictionRunsMillis(45000);
|
||||
dataSource.setMinEvictableIdleTimeMillis(1200000);
|
||||
|
||||
// 连接验证
|
||||
dataSource.setValidationQuery("SELECT 1");
|
||||
dataSource.setTestWhileIdle(true);
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.pictc.utils.DataLogTools;
|
||||
import com.pictc.utils.MybatisTools;
|
||||
import com.pictc.utils.SpringTools;
|
||||
|
||||
@Configuration
|
||||
public class PcitcAutoConfig {
|
||||
|
||||
@Bean
|
||||
public SpringTools springTools() {
|
||||
return new SpringTools();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MybatisTools mapperManager() {
|
||||
return new MybatisTools();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public DataLogTools dataLogTools() {
|
||||
return new DataLogTools();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.pictc.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ScanConfig {
|
||||
|
||||
|
||||
public static final String AUTO_FILE_NAME="auto-scan.txt";
|
||||
|
||||
private static final String FILE_PROCOTOL="file";
|
||||
|
||||
private static final String JAR_PROCOTOL="jar";
|
||||
|
||||
private static ClassLoader getDefaultClassLoader() {
|
||||
ClassLoader cl = null;
|
||||
try {
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
catch (Throwable ex) {}
|
||||
if (cl == null) {
|
||||
cl = ScanConfig.class.getClassLoader();
|
||||
if (cl == null) {
|
||||
try {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
catch (Throwable ex) {}
|
||||
}
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
public static void scan(String name,ScanFilter filter) {
|
||||
try {
|
||||
Enumeration<URL> dirs = getDefaultClassLoader().getResources(name);
|
||||
if(dirs!=null) {
|
||||
while(dirs.hasMoreElements()) {
|
||||
URL url = dirs.nextElement();
|
||||
if(FILE_PROCOTOL.equals(url.getProtocol())) {
|
||||
filter.accept(readConf(url.openStream()));
|
||||
}else if(JAR_PROCOTOL.equals(url.getProtocol())) {
|
||||
JarFile jarFile = ((JarURLConnection)url.openConnection()).getJarFile();
|
||||
ZipEntry entry = jarFile.getEntry(name);
|
||||
if(entry!=null) {
|
||||
filter.accept(readConf(jarFile.getInputStream(entry)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
log.info("没有扫描到任何东西!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties readConf(InputStream in) {
|
||||
Properties pro = new Properties();
|
||||
try {
|
||||
pro.load(in);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.info("读取配置文件错误");
|
||||
}
|
||||
return pro;
|
||||
}
|
||||
|
||||
public static void scanConfig(ScanFilter filter) {
|
||||
scan(AUTO_FILE_NAME,filter);
|
||||
}
|
||||
|
||||
|
||||
public interface ScanFilter{
|
||||
|
||||
public void accept(Properties conf);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pictc.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
|
||||
|
||||
public class UniqueNameGenerator extends AnnotationBeanNameGenerator {
|
||||
|
||||
@Override
|
||||
protected String buildDefaultBeanName(BeanDefinition definition) {
|
||||
return definition.getBeanClassName();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package com.pictc.converts;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.pictc.converts.date.DateHandler;
|
||||
import com.pictc.converts.date.LocalDateHandler;
|
||||
import com.pictc.converts.date.LocalDateTimeHandler;
|
||||
import com.pictc.converts.date.LocalTimeHandler;
|
||||
import com.pictc.converts.date.TimeHandler;
|
||||
import com.pictc.converts.date.TimestampHandler;
|
||||
import com.pictc.converts.primitive.BigDecimalHandler;
|
||||
import com.pictc.converts.primitive.BigIntegerHandler;
|
||||
import com.pictc.converts.primitive.BooleanHandler;
|
||||
import com.pictc.converts.primitive.ByteHandler;
|
||||
import com.pictc.converts.primitive.CharacterHandler;
|
||||
import com.pictc.converts.primitive.DoubleHandler;
|
||||
import com.pictc.converts.primitive.EnumHandler;
|
||||
import com.pictc.converts.primitive.FloatHandler;
|
||||
import com.pictc.converts.primitive.IntegerHandler;
|
||||
import com.pictc.converts.primitive.LongHandler;
|
||||
import com.pictc.converts.primitive.ShortHandler;
|
||||
import com.pictc.converts.primitive.StringHandler;
|
||||
import com.pictc.utils.BeanUtils;
|
||||
import com.pictc.utils.ClassUtils;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ConverUtil {
|
||||
|
||||
private static Map<Class<?>, SuperHandler> handlers = new HashMap<Class<?>,SuperHandler>();
|
||||
|
||||
static {
|
||||
Class<?>[] hcls = new Class<?>[] { DateHandler.class,TimestampHandler.class,TimeHandler.class,
|
||||
LocalDateTimeHandler.class,LocalDateHandler.class,LocalTimeHandler.class,
|
||||
BooleanHandler.class, ByteHandler.class,
|
||||
DoubleHandler.class, FloatHandler.class,
|
||||
IntegerHandler.class, LongHandler.class, ShortHandler.class,
|
||||
StringHandler.class,CharacterHandler.class,
|
||||
BigIntegerHandler.class,BigDecimalHandler.class };
|
||||
for (int i = 0; i < hcls.length; i++) {
|
||||
try {
|
||||
SuperHandler handler = BeanUtils.newInstance(hcls[i]);
|
||||
Class<?>[] classes = handler.getConverts();
|
||||
for (int j = 0; j < classes.length; j++) {
|
||||
handlers.put(classes[j], handler);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("类型转换器初始化异常",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void register(Class<?> cls) {
|
||||
if (handlers.containsKey(cls)) {
|
||||
return;
|
||||
}
|
||||
if(cls.isEnum()) {
|
||||
handlers.put(cls, new EnumHandler(cls));
|
||||
return;
|
||||
}
|
||||
if (!ClassUtils.hashClass(cls, SuperHandler.class)) {
|
||||
return;
|
||||
}
|
||||
TypeHandler<?> handler;
|
||||
try {
|
||||
handler = BeanUtils.newInstance(cls);
|
||||
handlers.put(cls, handler);
|
||||
} catch (Exception e) {
|
||||
log.error("注册类型转换器异常",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> TypeHandler<T> geTypeHandler(Class<T> cls) {
|
||||
if (!handlers.containsKey(cls)) {
|
||||
register(cls);
|
||||
}
|
||||
return (TypeHandler<T>) handlers.get(cls);
|
||||
}
|
||||
|
||||
//字符串
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static Object toJsonValue(Class<?> klass,Object val){
|
||||
TypeHandler handler = geTypeHandler(klass);
|
||||
return handler!=null?handler.convert(val):val;
|
||||
}
|
||||
|
||||
//字符串
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>T jsonToValue(Class<T> klass,Object val){
|
||||
TypeHandler<T> handler = geTypeHandler(klass);
|
||||
return handler!=null?handler.valueToObject(val):(T) val;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.pictc.converts;
|
||||
|
||||
public class ConvertException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ConvertException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConvertException(Class<?> from,Object val,Class<?> to) {
|
||||
super(from.getName() + "类型 "+(val==null?"null":val.toString())+" 无法转换至-->" + to.getName());
|
||||
}
|
||||
|
||||
public ConvertException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.converts;
|
||||
|
||||
public class ObjectHandler implements TypeHandler<Object> {
|
||||
|
||||
private Class<?>[] converts = new Class<?>[] { Object.class };
|
||||
|
||||
@Override
|
||||
public Object convert(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object valueToObject(Object val) {
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Object.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.pictc.converts;
|
||||
|
||||
|
||||
public interface SuperHandler {
|
||||
|
||||
boolean isType(Class<?> type);
|
||||
|
||||
Class<?>[] getConverts();
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.pictc.converts;
|
||||
|
||||
public interface TypeHandler<T> extends SuperHandler{
|
||||
|
||||
boolean isType(Class<?> type);
|
||||
|
||||
Class<?>[] getConverts();
|
||||
|
||||
/**
|
||||
* 转换json时调用
|
||||
* @param <T>
|
||||
*/
|
||||
Object convert(T value);
|
||||
|
||||
/**
|
||||
* json转换对象是调用
|
||||
* @param <T>
|
||||
*/
|
||||
T valueToObject(Object val);
|
||||
|
||||
public abstract class TypeHandlerVoid implements TypeHandler<Object>{}
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class DateHandler implements TypeHandler<Date>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Date.class};
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Date.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Date value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Date.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return new Date(Long.valueOf(val.toString()));
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Date.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
import com.pictc.utils.DateUtils;
|
||||
|
||||
public class LocalDateHandler implements TypeHandler<LocalDate>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {LocalDate.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return LocalDate.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(LocalDate value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return DateUtils.format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return LocalDate.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return DateUtils.toLocalDate(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,LocalDate.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
import com.pictc.utils.DateUtils;
|
||||
|
||||
public class LocalDateTimeHandler implements TypeHandler<LocalDateTime>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {LocalDateTime.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return LocalDateTime.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(LocalDateTime value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return DateUtils.format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return LocalDateTime.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return DateUtils.toLocalDateTime(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,LocalDateTime.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.time.LocalTime;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
import com.pictc.utils.DateUtils;
|
||||
|
||||
public class LocalTimeHandler implements TypeHandler<LocalTime>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {LocalTime.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return LocalTime.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(LocalTime value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return DateUtils.format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return LocalTime.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return DateUtils.toLocalTime(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,LocalTime.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.sql.Time;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class TimeHandler implements TypeHandler<Time>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Time.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Time.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Time value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Time.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return new Time(Long.valueOf(val.toString()));
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Time.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package com.pictc.converts.date;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
import com.pictc.utils.ClassUtils;
|
||||
import com.pictc.utils.DateUtils;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
|
||||
public class TimestampHandler implements TypeHandler<Timestamp> {
|
||||
|
||||
private Class<?>[] converts = new Class<?>[] { Timestamp.class };
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Timestamp.class.equals(type);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object convert(Timestamp value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String str = value.toString();
|
||||
if (str.contains(".")) {
|
||||
str = str.split("\\.")[0];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Timestamp valueToObject(Object val) {
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs = val.getClass();
|
||||
if (isType(vcs)) {
|
||||
return Timestamp.class.cast(val);
|
||||
} else if (val instanceof String) {
|
||||
String str = (String) val;
|
||||
if (str.matches("^\\d+$")) {
|
||||
return new Timestamp(Long.valueOf(str));
|
||||
}else if(str.matches("^.*T.*\\+.*$")) {
|
||||
LocalDateTime date = LocalDateTime.parse(str,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
||||
return DateUtils.toTimestamp(date);
|
||||
} else if (StringUtils.isEmpty(str)) {
|
||||
return null;
|
||||
} else {
|
||||
throw new ConvertException(vcs, val, Timestamp.class);
|
||||
}
|
||||
}else if(ClassUtils.isDate(vcs)) {
|
||||
return new Timestamp(((Date)val).getTime());
|
||||
}else if(Long.class.equals(vcs) || long.class.equals(vcs)) {
|
||||
return new Timestamp(Long.class.cast(val));
|
||||
}else if(LocalDateTime.class.equals(vcs)){
|
||||
return DateUtils.toTimestamp(LocalDateTime.class.cast(val));
|
||||
} else {
|
||||
throw new ConvertException(vcs, val, Timestamp.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
public class BigDecimalHandler implements TypeHandler<BigDecimal>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {BigDecimal.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return BigDecimal.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convert(BigDecimal value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return BigDecimal.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
String strVal=val.toString();
|
||||
if(!StringUtils.isEmpty(strVal)) {
|
||||
return new BigDecimal(strVal);
|
||||
}
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,BigDecimal.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class BigIntegerHandler implements TypeHandler<BigInteger>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {BigInteger.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return BigInteger.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(BigInteger value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return BigInteger.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return new BigInteger(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,BigInteger.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class BooleanHandler implements TypeHandler<Boolean>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Boolean.class,boolean.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Boolean.class.equals(type)||boolean.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Boolean value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return false;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Boolean.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return Boolean.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Boolean.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class ByteHandler implements TypeHandler<Byte>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Byte.class,byte.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Byte.class.equals(type)||byte.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Byte value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Byte.class.cast(val);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).byteValue();
|
||||
}else {
|
||||
try {
|
||||
return Byte.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Byte.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class CharacterHandler implements TypeHandler<Character>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Character.class,char.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Character.class.equals(type)|| char.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Character value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Character.class.cast(val);
|
||||
}else {
|
||||
try {
|
||||
return val.toString().charAt(0);
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Character.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class DoubleHandler implements TypeHandler<Double>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Double.class,double.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Double.class.equals(type) || double.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Double value) {
|
||||
return doubleToString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Double.class.cast(val);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).doubleValue();
|
||||
}else {
|
||||
try {
|
||||
return Double.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Double.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String doubleToString(double d) {
|
||||
if (Double.isInfinite(d) || Double.isNaN(d)) {
|
||||
return "null";
|
||||
}
|
||||
String string = Double.toString(d);
|
||||
if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) {
|
||||
while (string.endsWith("0")) {
|
||||
string = string.substring(0, string.length() - 1);
|
||||
}
|
||||
if (string.endsWith(".")) {
|
||||
string = string.substring(0, string.length() - 1);
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class EnumHandler implements TypeHandler<Enum<?>>{
|
||||
|
||||
private Class<?> klazz;
|
||||
|
||||
public EnumHandler(Class<?> klazz) {
|
||||
super();
|
||||
this.klazz = klazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return type.isEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object convert(Enum<?> value) {
|
||||
if(value==null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T>T valueToObject(Class<T> clazz,Object val) {
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return (T)val;
|
||||
}else {
|
||||
try {
|
||||
Method method=clazz.getMethod("valueOf", String.class);
|
||||
return (T) method.invoke(null,val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Enum.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum<?> valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return (Enum<?>) val;
|
||||
}else {
|
||||
try {
|
||||
Method method=klazz.getMethod("valueOf", String.class);
|
||||
return (Enum<?>)method.invoke(null,val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,klazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class FloatHandler implements TypeHandler<Float>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Float.class,float.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Float.class.equals(type)|| float.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Float value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Float.class.cast(val);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).floatValue();
|
||||
}else {
|
||||
try {
|
||||
return Float.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Float.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class IntegerHandler implements TypeHandler<Integer>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Integer.class,int.class};
|
||||
|
||||
|
||||
@Override
|
||||
public Object convert(Integer value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer valueToObject(Object val){
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Integer.class.cast(val);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).intValue();
|
||||
}else {
|
||||
try {
|
||||
return Integer.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Integer.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Integer.class.equals(type)|| int.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class LongHandler implements TypeHandler<Long>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Long.class,long.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Long.class.equals(type)||long.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Long value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Long.class.cast(val);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).longValue();
|
||||
}else {
|
||||
try {
|
||||
return Long.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Long.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.ConvertException;
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class ShortHandler implements TypeHandler<Short>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {Short.class,short.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return Short.class.equals(type)|| short.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Short value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> vcs=val.getClass();
|
||||
if(isType(vcs)) {
|
||||
return Short.class.cast(vcs);
|
||||
}else if(Number.class.equals(vcs)) {
|
||||
return Number.class.cast(val).shortValue();
|
||||
}else {
|
||||
try {
|
||||
return Short.valueOf(val.toString());
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(vcs,val,Short.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.pictc.converts.primitive;
|
||||
|
||||
import com.pictc.converts.TypeHandler;
|
||||
|
||||
public class StringHandler implements TypeHandler<String>{
|
||||
|
||||
private Class<?>[] converts=new Class<?>[] {String.class};
|
||||
|
||||
@Override
|
||||
public boolean isType(Class<?> type) {
|
||||
return String.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToObject(Object val) {
|
||||
if(val==null) {
|
||||
return null;
|
||||
}
|
||||
return val.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getConverts() {
|
||||
return converts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||
import com.pictc.annotations.datalog.LogField;
|
||||
import com.pictc.jdbc.JdbcContextUtils;
|
||||
import com.pictc.utils.SpringAnnotationUtils;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class LogFieldInfo implements Comparable<LogFieldInfo>{
|
||||
|
||||
private LogField annotation;
|
||||
|
||||
private Field field;
|
||||
|
||||
private TableFieldInfo fieldInfo;
|
||||
|
||||
public static LogFieldInfo ofField(Field field) {
|
||||
return new LogFieldInfo().setField(field).setAnnotation(SpringAnnotationUtils.findAnnotation(field, LogField.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(LogFieldInfo o) {
|
||||
return annotation.index() - o.annotation.index();
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return annotation.name();
|
||||
}
|
||||
|
||||
public String getColumn() {
|
||||
return fieldInfo!=null?fieldInfo.getColumn():JdbcContextUtils.fieldToColumn(field.getName());
|
||||
}
|
||||
|
||||
public Class<?> getJavaType(){
|
||||
return field.getType();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.pictc.annotations.datalog.JoinType;
|
||||
import com.pictc.annotations.datalog.LogJoin;
|
||||
import com.pictc.utils.DataLogTools;
|
||||
import com.pictc.utils.SpringAnnotationUtils;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class LogJoinInfo {
|
||||
|
||||
private Field field;
|
||||
|
||||
private LogJoin join;
|
||||
|
||||
public static LogJoinInfo ofAnnotation(Class<?> klazz,Field field) {
|
||||
return new LogJoinInfo().setJoin(SpringAnnotationUtils.findAnnotation(field, LogJoin.class)).setField(field);
|
||||
}
|
||||
|
||||
public LogTableInfo getTableInfo() {
|
||||
return DataLogTools.getAnnotation(join.target());
|
||||
}
|
||||
|
||||
public boolean isList() {
|
||||
return join.type()==JoinType.MANY;
|
||||
}
|
||||
|
||||
public Class<?> getTargetClass() {
|
||||
return join.target();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.pictc.annotations.datalog.LogField;
|
||||
import com.pictc.annotations.datalog.LogJoin;
|
||||
import com.pictc.annotations.datalog.LogTable;
|
||||
import com.pictc.utils.BeanUtils;
|
||||
import com.pictc.utils.CollectionUtils;
|
||||
import com.pictc.utils.MybatisTools;
|
||||
import com.pictc.utils.SpringAnnotationUtils;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LogTableInfo {
|
||||
|
||||
private LogTable table;
|
||||
|
||||
private Field idField;
|
||||
|
||||
private TableInfo info;
|
||||
|
||||
private List<LogFieldInfo> fields = CollectionUtils.newArrayList();
|
||||
|
||||
private Map<String,LogFieldInfo> fieldMap = CollectionUtils.newConcurrentHashMap();
|
||||
|
||||
private Map<String,LogFieldInfo> columnMap = CollectionUtils.newConcurrentHashMap();
|
||||
|
||||
private List<LogJoinInfo> joins = CollectionUtils.newArrayList();
|
||||
|
||||
private Class<?> klazz;
|
||||
|
||||
public LogTableInfo(Class<?> klazz) {
|
||||
super();
|
||||
this.klazz = klazz;
|
||||
table = SpringAnnotationUtils.findAnnotation(klazz, LogTable.class);
|
||||
info = MybatisTools.getTableInfo(table.source());
|
||||
initId();
|
||||
initFields();
|
||||
initJoins();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return table.name();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return table!=null;
|
||||
}
|
||||
|
||||
private void initId() {
|
||||
String idKey = info.getKeyProperty();
|
||||
if(StringUtils.isEmpty(idKey)) {
|
||||
idKey = "id";
|
||||
}
|
||||
idField = BeanUtils.getField(idKey,klazz);
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
if(isValid()) {
|
||||
List<Field> _fields = BeanUtils.getFields(klazz, LogField.class);
|
||||
if(CollectionUtils.isNotEmpty(_fields)) {
|
||||
Map<String, TableFieldInfo> fieldMap = null;
|
||||
if(info!=null) {
|
||||
fieldMap = info.getFieldList().stream().collect(Collectors.toMap(TableFieldInfo::getProperty,Function.identity()));
|
||||
}
|
||||
for (Field field : _fields) {
|
||||
LogFieldInfo fieldInfo = LogFieldInfo.ofField(field);
|
||||
if(fieldMap!=null) fieldInfo.setFieldInfo(fieldMap.get(field.getName()));
|
||||
fields.add(fieldInfo);
|
||||
}
|
||||
Collections.sort(fields);
|
||||
this.fieldMap = fields.stream().collect(Collectors.toMap(LogFieldInfo::getFieldName,Function.identity()));
|
||||
this.columnMap = fields.stream().collect(Collectors.toMap(LogFieldInfo::getColumn,Function.identity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initJoins() {
|
||||
if(isValid()) {
|
||||
List<Field> _fields = BeanUtils.getFields(klazz, LogJoin.class);
|
||||
if(CollectionUtils.isNotEmpty(_fields)) {
|
||||
for (Field field : _fields) {
|
||||
fields.add(LogFieldInfo.ofField(field));
|
||||
joins.add(LogJoinInfo.ofAnnotation(klazz, field));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Long getIdValue(Object obj) {
|
||||
return BeanUtils.getFieldValue(idField,obj);
|
||||
}
|
||||
|
||||
public void setIdValue(Object entity, Long id) {
|
||||
if(entity==null) return;
|
||||
BeanUtils.setFieldValue(idField,id,entity);
|
||||
}
|
||||
|
||||
|
||||
public Object getFieldValue(Object entity,String field) {
|
||||
if(entity==null) return null;
|
||||
LogFieldInfo fieldInfo = this.fieldMap.get(field);
|
||||
return BeanUtils.getFieldValue(fieldInfo.getField(),entity);
|
||||
}
|
||||
|
||||
public Object getFieldValue(Object entity,Field field) {
|
||||
if(entity==null) return null;
|
||||
return BeanUtils.getFieldValue(field,entity);
|
||||
}
|
||||
|
||||
|
||||
public void setFieldValue(Object entity,String field,Object value) {
|
||||
if(entity==null) return;
|
||||
LogFieldInfo fieldInfo = this.fieldMap.get(field);
|
||||
BeanUtils.setFieldValue(fieldInfo.getField(),value,entity);
|
||||
}
|
||||
|
||||
public void setFieldValue(Object entity,Field field,Object value) {
|
||||
if(entity==null) return;
|
||||
BeanUtils.setFieldValue(field,value,entity);
|
||||
}
|
||||
|
||||
|
||||
public String getColumn(String field) {
|
||||
LogFieldInfo fieldInfo = this.fieldMap.get(field);
|
||||
return fieldInfo.getColumn();
|
||||
}
|
||||
|
||||
|
||||
public String getIdColumn() {
|
||||
LogFieldInfo fieldInfo = this.fieldMap.get(idField.getName());
|
||||
return fieldInfo.getColumn();
|
||||
}
|
||||
|
||||
public Class<?> getEntityType() {
|
||||
return info.getEntityType();
|
||||
}
|
||||
|
||||
public Object toEntity(Object dto) {
|
||||
return BeanUtil.toBean(dto, info.getEntityType());
|
||||
}
|
||||
|
||||
|
||||
public Object toDto(Object entity) {
|
||||
return BeanUtil.toBean(entity,klazz);
|
||||
}
|
||||
|
||||
|
||||
public String getTableName() {
|
||||
return info.getTableName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.pictc.exceptions;
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2025年9月16日 下午3:43:37
|
||||
* @Description: 数据操作异常
|
||||
*/
|
||||
public class OrmException extends RuntimeException{
|
||||
|
||||
/**
|
||||
* @Fields {todo}(用一句话描述这个变量表示什么)
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OrmException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OrmException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public OrmException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public OrmException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OrmException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.pictc.exceptions;
|
||||
|
||||
public class TFieldException extends RuntimeException{
|
||||
|
||||
/**
|
||||
* @Fields {todo}(用一句话描述这个变量表示什么)
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TFieldException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TFieldException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public TFieldException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public TFieldException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TFieldException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.pictc.exceptions;
|
||||
|
||||
public class TMethodException extends RuntimeException{
|
||||
|
||||
/**
|
||||
* @Fields {todo}(用一句话描述这个变量表示什么)
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TMethodException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TMethodException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public TMethodException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public TMethodException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TMethodException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,258 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.pictc.utils.CollectionUtils;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
public class JdbcContext {
|
||||
|
||||
public static final int DEF_STEP = 1000;
|
||||
|
||||
private JdbcTemplate jdbc;
|
||||
|
||||
private DataSource source;
|
||||
|
||||
private DataSource logSource;
|
||||
|
||||
private Connection conn;
|
||||
|
||||
private PreparedStatement stmt;
|
||||
|
||||
private CallableStatement ctmt;
|
||||
|
||||
private long start;
|
||||
|
||||
private int size = 0;
|
||||
|
||||
private boolean isQuery = false;
|
||||
|
||||
private boolean isCall = false;
|
||||
|
||||
private boolean datalog = false;
|
||||
|
||||
private String sql;
|
||||
|
||||
private List<JdbcParam> params;
|
||||
|
||||
private List<List<JdbcParam>> batchParams;
|
||||
|
||||
public JdbcContext(boolean isQuery) throws SQLException {
|
||||
this(isQuery, false);
|
||||
}
|
||||
|
||||
public JdbcContext(boolean isQuery,boolean datalog) throws SQLException {
|
||||
super();
|
||||
this.isQuery = isQuery;
|
||||
this.datalog = datalog;
|
||||
this.start = System.currentTimeMillis();
|
||||
this.source = JdbcContextUtils.getSource();
|
||||
this.logSource = JdbcContextUtils.getLogSource();
|
||||
this.jdbc = JdbcContextUtils.getJdbc();
|
||||
this.conn = datalog?DataSourceUtils.getConnection(this.logSource):DataSourceUtils.getConnection(this.source);
|
||||
}
|
||||
|
||||
public JdbcContext init(String sql) throws SQLException {
|
||||
this.sql = sql;
|
||||
this.stmt = (PreparedStatement) getStatement(this.conn,sql);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataSource getReleaseSource() {
|
||||
return datalog?logSource:source;
|
||||
}
|
||||
|
||||
public JdbcContext initCall(String sql) throws SQLException {
|
||||
this.sql = sql;
|
||||
this.isCall = true;
|
||||
this.ctmt = (CallableStatement) getStatement(this.conn,sql);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JdbcContext addParam(int jdbc,Object val) {
|
||||
if(params==null) {
|
||||
params = CollectionUtils.newArrayList();
|
||||
}
|
||||
params.add(new JdbcParam().setJdbc(jdbc).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JdbcContext addBatchParam(int index,int jdbc,Object val) {
|
||||
if(batchParams==null) {
|
||||
batchParams = CollectionUtils.newArrayList();
|
||||
}
|
||||
|
||||
if(batchParams.size() <=index) {
|
||||
batchParams.add(CollectionUtils.newArrayList());
|
||||
}
|
||||
List<JdbcParam> bpam = batchParams.get(index);
|
||||
bpam.add(new JdbcParam().setJdbc(jdbc).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
private Statement getStatement(Connection conn,String sql) throws SQLException {
|
||||
Statement stmt = null;
|
||||
if(this.isCall) {
|
||||
stmt = conn.prepareCall(sql);
|
||||
}else if(this.isQuery) {
|
||||
stmt = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
|
||||
}else {
|
||||
stmt = conn.prepareStatement(sql);
|
||||
}
|
||||
int fetchSize = jdbc.getFetchSize();
|
||||
if (fetchSize >= 0) {
|
||||
stmt.setFetchSize(fetchSize);
|
||||
}
|
||||
int maxRows = jdbc.getMaxRows();
|
||||
if (maxRows >= 0) {
|
||||
stmt.setMaxRows(maxRows);
|
||||
}
|
||||
DataSourceUtils.applyTimeout(stmt,getReleaseSource(),jdbc.getQueryTimeout());
|
||||
return stmt;
|
||||
}
|
||||
|
||||
private void executeParams() throws SQLException {
|
||||
if(params!=null) {
|
||||
for (int i = 0; i < params.size(); i++) {
|
||||
JdbcParam parameter = params.get(i);
|
||||
int index = i+1;
|
||||
if(parameter.isOut()) {
|
||||
ctmt.registerOutParameter(index,parameter.getJdbc());
|
||||
continue;
|
||||
}
|
||||
this.setParameter(index,parameter.getJdbc(),parameter.getVal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int executeUpdate() throws SQLException {
|
||||
executeParams();
|
||||
size = this._executeUpdate();
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
public boolean execute() throws SQLException {
|
||||
executeParams();
|
||||
return this._execute();
|
||||
}
|
||||
|
||||
public int executeBatch() throws SQLException {
|
||||
return executeBatch(DEF_STEP);
|
||||
}
|
||||
|
||||
public int executeBatch(int step) throws SQLException {
|
||||
int rows = 0;
|
||||
step = step <=0?DEF_STEP:step;
|
||||
if(batchParams!=null && !batchParams.isEmpty()) {
|
||||
int j = 0;
|
||||
for (List<JdbcParam> list : batchParams) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
JdbcParam parameter = list.get(i);
|
||||
setParameter(i+1, parameter.getJdbc(),parameter.getVal());
|
||||
}
|
||||
this.addBatch();
|
||||
j++;
|
||||
if(j%step==0) {
|
||||
rows=countRow(rows,this._executeBatch());
|
||||
}
|
||||
}
|
||||
}
|
||||
rows=countRow(rows,this._executeBatch());
|
||||
size = rows;
|
||||
return rows;
|
||||
}
|
||||
|
||||
public ResultSet executeQuery() throws SQLException {
|
||||
executeParams();
|
||||
ResultSet rset = this._executeQuery();
|
||||
rset.last();
|
||||
size = rset.getRow(); //获得ResultSet的总行数
|
||||
rset.beforeFirst();
|
||||
return rset;
|
||||
}
|
||||
|
||||
private ResultSet _executeQuery() throws SQLException {
|
||||
return getStatement().executeQuery();
|
||||
}
|
||||
|
||||
private PreparedStatement getStatement() {
|
||||
return this.isCall?ctmt:stmt;
|
||||
}
|
||||
|
||||
private void setParameter(int index,int jdbc,Object val) throws SQLException {
|
||||
PreparedStatement _stmt = getStatement();
|
||||
if(val==null) {
|
||||
_stmt.setNull(index,jdbc);
|
||||
}else {
|
||||
_stmt.setObject(index,val,jdbc);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBatch() throws SQLException {
|
||||
getStatement().addBatch();
|
||||
}
|
||||
|
||||
private int[] _executeBatch() throws SQLException {
|
||||
return getStatement().executeBatch();
|
||||
}
|
||||
|
||||
private int _executeUpdate() throws SQLException {
|
||||
return getStatement().executeUpdate();
|
||||
}
|
||||
|
||||
|
||||
private boolean _execute() throws SQLException {
|
||||
return getStatement().execute();
|
||||
}
|
||||
|
||||
private int countRow(int rows,int[] rowArray) {
|
||||
if(rowArray!=null) {
|
||||
for (int i = 0; i < rowArray.length; i++) {
|
||||
rows+=rowArray[i];
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
public DataAccessException createException(SQLException e) {
|
||||
return jdbc.getExceptionTranslator().translate(sql,null,e);
|
||||
}
|
||||
|
||||
public void end() {
|
||||
JdbcUtils.closeStatement(getStatement());
|
||||
if(conn!=null) {
|
||||
DataSourceUtils.releaseConnection(conn,getReleaseSource());
|
||||
}
|
||||
log.info(" Statement: 【{}】",sql);
|
||||
if(params!=null && !params.isEmpty()) {
|
||||
log.info("Parameters: {}",params.toString());
|
||||
}
|
||||
long con = System.currentTimeMillis()-start;
|
||||
if(!this.isQuery) {
|
||||
log.info(" consuming: 【{} ms】--- 数据:【{}条】--- 效率:【{} ms/条】",con,size,size>0?(con/size):con);
|
||||
}else {
|
||||
log.info(" total: {}",size);
|
||||
log.info(" consuming: 【{} ms】",con);
|
||||
}
|
||||
log.info("-----------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
|
||||
public class JdbcContextUtils {
|
||||
|
||||
private static JdbcTemplate jdbc;
|
||||
|
||||
private static DataSource source;
|
||||
|
||||
private static DataSource logSource;
|
||||
|
||||
@Autowired
|
||||
public void setJdbc(JdbcTemplate jdbc) {
|
||||
JdbcContextUtils.jdbc = jdbc;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setSource(DataSource source) {
|
||||
JdbcContextUtils.source = source;
|
||||
}
|
||||
|
||||
public void setLogSource(DataSource source) {
|
||||
JdbcContextUtils.logSource = source;
|
||||
}
|
||||
|
||||
public static JdbcTemplate getJdbc() {
|
||||
return JdbcContextUtils.jdbc;
|
||||
}
|
||||
|
||||
public static DataSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public static DataSource getLogSource() {
|
||||
return logSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰命名的字符串转为下划线
|
||||
* */
|
||||
public static String fieldToColumn(String str) {
|
||||
StringBuilder result=new StringBuilder();
|
||||
char[] chars=str.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
if(Character.isUpperCase(chars[i])) {
|
||||
if(i>0) {
|
||||
result.append('_');
|
||||
}
|
||||
result.append(Character.toLowerCase(chars[i]));
|
||||
continue;
|
||||
}
|
||||
result.append(chars[i]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,315 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.pictc.jdbc.model.QueryParameter;
|
||||
import com.pictc.utils.CollectionUtils;
|
||||
|
||||
|
||||
public class JdbcTools {
|
||||
|
||||
/**
|
||||
* 执行增删改sql
|
||||
* */
|
||||
public static int execute(String sql) {
|
||||
return execute(sql, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行增删改sql
|
||||
* */
|
||||
public static int execute(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
return context.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
* */
|
||||
public static int executeBatch(String sql,List<List<JdbcParam>> batchParams) {
|
||||
return executeBatch(sql,-1, batchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
* */
|
||||
public static int executeBatch(String sql,int step,List<List<JdbcParam>> batchParams){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setBatchParams(batchParams);
|
||||
return context.executeBatch(step);
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询基础数据类型
|
||||
* */
|
||||
public static <T>T queryPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
while (set.next()) {
|
||||
return ResultSetUtils.getObject(set,1,type);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询基础数据类型
|
||||
* */
|
||||
public static <T>List<T> queryListPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
List<T> res = CollectionUtils.newArrayList();
|
||||
while (set.next()) {
|
||||
res.add(ResultSetUtils.getObject(set,1,type));
|
||||
}
|
||||
return res;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询对象
|
||||
* */
|
||||
public static JSONObject queryObj(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
while (set.next()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
for (String key : names.keySet()) {
|
||||
obj.put(names.get(key),set.getObject(key));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询集合
|
||||
* */
|
||||
public static JSONArray queryArray(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
JSONArray result = new JSONArray();
|
||||
while (set.next()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
for (String key : names.keySet()) {
|
||||
obj.put(names.get(key),set.getObject(key));
|
||||
}
|
||||
result.add(obj);
|
||||
}
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
} finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行存储过程返回基础数据类型
|
||||
* */
|
||||
public static <T>T callPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true);
|
||||
context.initCall(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
while (set.next()) {
|
||||
return ResultSetUtils.getObject(set,1,type);
|
||||
}
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行存储过程返回基础数据类型
|
||||
* */
|
||||
public static <T>List<T> callListPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true);
|
||||
context.initCall(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
List<T> res = CollectionUtils.newArrayList();
|
||||
while (set.next()) {
|
||||
res.add(ResultSetUtils.getObject(set,1,type));
|
||||
}
|
||||
return res;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行存储过程返回对象
|
||||
* */
|
||||
public static JSONObject callObj(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true);
|
||||
context.initCall(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
while (set.next()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
for (String key : names.keySet()) {
|
||||
obj.put(names.get(key),set.getObject(key));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行存储过程,返回集合
|
||||
* */
|
||||
public static JSONArray callArray(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true);
|
||||
context.initCall(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
JSONArray result = new JSONArray();
|
||||
while (set.next()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
for (String key : names.keySet()) {
|
||||
obj.put(names.get(key),set.getObject(key));
|
||||
}
|
||||
result.add(obj);
|
||||
}
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
//IPage<DemoCustomer>
|
||||
public static IPage<JSONObject> queryPage(String baseSql,QueryParameter param) {
|
||||
SqlBuilder sql = new SqlBuilder();
|
||||
sql.append(baseSql);
|
||||
List<JdbcParam> params = QueryParameterUtils.toJdbcParams(sql, param.getAllCriterias());
|
||||
|
||||
SqlBuilder countSql = new SqlBuilder();
|
||||
countSql.select().append(" count(*) ").from().leftBracket().append(sql).rightBracket().as().append("TMP_CT");
|
||||
Long total = queryPrimitive(countSql.toString(),Long.class,params);
|
||||
|
||||
List<JdbcParam> pageParams = CollectionUtils.newArrayList();
|
||||
for (JdbcParam item : params) {
|
||||
pageParams.add(item);
|
||||
}
|
||||
|
||||
int start = (param.getIndex()-1)*param.getSize();
|
||||
pageParams.add(new JdbcParam().setVal(param.getSize()).setJdbc(Types.INTEGER).setJavaType(Integer.class));
|
||||
pageParams.add(new JdbcParam().setVal(start).setJdbc(Types.INTEGER).setJavaType(Integer.class));
|
||||
|
||||
QueryParameterUtils.parseOrders(sql, param.getOrders());
|
||||
SqlBuilder pageSql = new SqlBuilder();
|
||||
pageSql.append(sql.toString());
|
||||
pageSql.limitFull();
|
||||
|
||||
JSONArray list = queryArray(pageSql.toString(), pageParams);
|
||||
List<JSONObject> records = CollectionUtils.newArrayList();
|
||||
if(list!=null) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
records.add(list.getJSONObject(i));
|
||||
}
|
||||
}
|
||||
Page<JSONObject> page = new Page<>(param.getIndex(),param.getSize(),total);
|
||||
page.setRecords(records);
|
||||
return page;
|
||||
}
|
||||
|
||||
public static JSONArray query(String baseSql,QueryParameter param){
|
||||
SqlBuilder sql = new SqlBuilder();
|
||||
sql.append(baseSql);
|
||||
List<JdbcParam> params = QueryParameterUtils.toJdbcParams(sql, param.getAllCriterias());
|
||||
QueryParameterUtils.parseOrders(sql, param.getOrders());
|
||||
return queryArray(sql.toString(), params);
|
||||
}
|
||||
|
||||
|
||||
public static JSONObject queryObj(String baseSql,QueryParameter param){
|
||||
SqlBuilder sql = new SqlBuilder();
|
||||
sql.append(baseSql);
|
||||
List<JdbcParam> params = QueryParameterUtils.toJdbcParams(sql, param.getAllCriterias());
|
||||
QueryParameterUtils.parseOrders(sql, param.getOrders());
|
||||
return queryObj(sql.toString(), params);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.pictc.jdbc.model.Criteria;
|
||||
import com.pictc.jdbc.model.CriteriaGroup;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.pictc.jdbc.model.JdbcType;
|
||||
import com.pictc.jdbc.model.Link;
|
||||
import com.pictc.jdbc.model.QueryOrder;
|
||||
import com.pictc.jdbc.model.Criteria.DataType;
|
||||
import com.pictc.jdbc.model.QueryOrder.QueryOrderType;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
public class QueryParameterUtils {
|
||||
|
||||
private static final String TBL_ALIAS = "t";
|
||||
|
||||
public static List<JdbcParam> toJdbcParams(SqlBuilder sql,List<CriteriaGroup> groups) {
|
||||
List<JdbcParam> params = new ArrayList<JdbcParam>();
|
||||
boolean hasWhere = false;
|
||||
if(groups!=null && !groups.isEmpty()) {
|
||||
for (CriteriaGroup group : groups) {
|
||||
List<Criteria> cris = group.getCriterias();
|
||||
if(cris==null || cris.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if(!hasWhere) {
|
||||
hasWhere = true;
|
||||
sql.where();
|
||||
}else {
|
||||
if(group.getLink()==Link.AND) {
|
||||
sql.and();
|
||||
}else {
|
||||
sql.or();
|
||||
}
|
||||
}
|
||||
sql.leftBracket();
|
||||
boolean c_flag = false;
|
||||
for (Criteria criteria : cris) {
|
||||
if(!c_flag) {
|
||||
c_flag = true;
|
||||
}else {
|
||||
if(criteria.getLink()==Link.AND) {
|
||||
sql.and();
|
||||
}else {
|
||||
sql.or();
|
||||
}
|
||||
}
|
||||
|
||||
if(criteria.isNot()) {
|
||||
sql.not();
|
||||
}
|
||||
String col = convertHump(criteria.getField());
|
||||
if(criteria.getDataType()==DataType.STRING) {
|
||||
sql.append("IFNULL(");
|
||||
sql.append(TBL_ALIAS).dot().appendSeparator(col);
|
||||
sql.append(",'')");
|
||||
}else {
|
||||
sql.append(TBL_ALIAS).dot().appendSeparator(col);
|
||||
}
|
||||
JdbcType jdbc = criteria.getJdbc();
|
||||
int valueType = 0;
|
||||
switch (criteria.getType()) {
|
||||
case NULL:
|
||||
valueType = -1;
|
||||
sql.isNull();
|
||||
break;
|
||||
case EQ:
|
||||
sql.eq().placeholder();
|
||||
break;
|
||||
case LIKE:
|
||||
sql.like().placeholder();
|
||||
break;
|
||||
case GT:
|
||||
sql.gt().placeholder();
|
||||
break;
|
||||
case EQ_GT:
|
||||
sql.gtEq().placeholder();
|
||||
break;
|
||||
case LT:
|
||||
sql.lt().placeholder();
|
||||
break;
|
||||
case EQ_LT:
|
||||
sql.ltEq().placeholder();
|
||||
break;
|
||||
case BETWEEN:
|
||||
valueType = 1;
|
||||
if(criteria.getVal()==null || criteria.getSecondVal()==null) {
|
||||
throw new RuntimeException(StringUtils.format("filed:[{0}] --> 条件:BETWEEN 值不能为空!", criteria.getField()));
|
||||
}
|
||||
sql.between().placeholder().and().placeholder();
|
||||
params.add(new JdbcParam().setJdbc(jdbc.getJdbc()).setJavaType(jdbc.getJavaClass()).setVal(criteria.getVal()));
|
||||
params.add(new JdbcParam().setJdbc(jdbc.getJdbc()).setJavaType(jdbc.getJavaClass()).setVal(criteria.getSecondVal()));
|
||||
break;
|
||||
case IN:
|
||||
valueType = 2;
|
||||
//criteria.getListVal()
|
||||
if(criteria.getListVal()==null || criteria.getListVal().isEmpty()) {
|
||||
throw new RuntimeException(StringUtils.format("filed:[{0}] --> 条件:IN 值不能为空!", criteria.getField()));
|
||||
}
|
||||
sql.inStart();
|
||||
boolean inFlag = false;
|
||||
for (Object val : criteria.getListVal()) {
|
||||
if(!inFlag) {
|
||||
inFlag = true;
|
||||
}else {
|
||||
sql.comma();
|
||||
}
|
||||
sql.placeholder();
|
||||
params.add(new JdbcParam().setJdbc(jdbc.getJdbc()).setJavaType(jdbc.getJavaClass()).setVal(val));
|
||||
}
|
||||
sql.inEnd();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(valueType==0) {
|
||||
params.add(new JdbcParam().setJdbc(jdbc.getJdbc()).setJavaType(jdbc.getJavaClass()).setVal(criteria.getVal()));
|
||||
}
|
||||
}
|
||||
sql.rightBracket();
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
public static void parseOrders(SqlBuilder builder,List<QueryOrder> orders) {
|
||||
if(orders!=null) {
|
||||
boolean flag = false;
|
||||
for (QueryOrder order : orders) {
|
||||
if(order.getType()==QueryOrderType.NONE) {
|
||||
continue;
|
||||
}
|
||||
if(!flag) {
|
||||
builder.orderBy();
|
||||
flag = true;
|
||||
}else {
|
||||
builder.comma();
|
||||
}
|
||||
String col = convertHump(order.getField());
|
||||
builder.space().append(TBL_ALIAS).dot().appendSeparator(col);
|
||||
if(order.getType()==QueryOrderType.ASC) {
|
||||
builder.asc();
|
||||
}else {
|
||||
builder.desc();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰命名的字符串转为下划线
|
||||
* */
|
||||
public static String convertHump(String str) {
|
||||
StringBuilder result=new StringBuilder();
|
||||
char[] chars=str.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
if(Character.isUpperCase(chars[i])) {
|
||||
if(i>0) {
|
||||
result.append('_');
|
||||
}
|
||||
result.append(Character.toLowerCase(chars[i]));
|
||||
continue;
|
||||
}
|
||||
result.append(chars[i]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,359 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.sql.Array;
|
||||
import java.sql.Date;
|
||||
import java.sql.NClob;
|
||||
import java.sql.Ref;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.RowId;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.SQLXML;
|
||||
import java.sql.Struct;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
|
||||
public class ResultSetUtils {
|
||||
|
||||
private static Pattern linePattern = Pattern.compile("_(\\w)");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getObject(ResultSet res,int columnIndex,Class<T> type) throws SQLException {
|
||||
if (type.equals(String.class)) {
|
||||
return (T) res.getString(columnIndex);
|
||||
|
||||
} else if (type.equals(BigDecimal.class)) {
|
||||
return (T) res.getBigDecimal(columnIndex);
|
||||
|
||||
} else if (type.equals(BigInteger.class)) {
|
||||
return (T) getBigInteger(res, columnIndex);
|
||||
|
||||
} else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE)) {
|
||||
return (T) Boolean.valueOf(res.getBoolean(columnIndex));
|
||||
|
||||
} else if (type.equals(Integer.class) || type.equals(Integer.TYPE)) {
|
||||
return (T) Integer.valueOf(res.getInt(columnIndex));
|
||||
|
||||
} else if (type.equals(Long.class) || type.equals(Long.TYPE)) {
|
||||
return (T) Long.valueOf(res.getLong(columnIndex));
|
||||
} else if (type.equals(Float.class) || type.equals(Float.TYPE)) {
|
||||
return (T) Float.valueOf(res.getFloat(columnIndex));
|
||||
|
||||
} else if (type.equals(Double.class) || type.equals(Double.TYPE)) {
|
||||
return (T) Double.valueOf(res.getDouble(columnIndex));
|
||||
|
||||
} else if (type.equals(byte[].class)) {
|
||||
return (T) res.getBytes(columnIndex);
|
||||
|
||||
} else if (type.equals(Date.class)) {
|
||||
return (T) res.getDate(columnIndex);
|
||||
|
||||
} else if (type.equals(Time.class)) {
|
||||
return (T) res.getTime(columnIndex);
|
||||
|
||||
} else if (type.equals(Timestamp.class)) {
|
||||
return (T) res.getTimestamp(columnIndex);
|
||||
|
||||
} else if (type.equals(java.sql.Clob.class)) {
|
||||
return (T) res.getClob(columnIndex);
|
||||
|
||||
} else if (type.equals(java.sql.Blob.class)) {
|
||||
return (T) res.getBlob(columnIndex);
|
||||
|
||||
} else if (type.equals(Array.class)) {
|
||||
return (T) res.getArray(columnIndex);
|
||||
|
||||
} else if (type.equals(Ref.class)) {
|
||||
return (T) res.getRef(columnIndex);
|
||||
|
||||
} else if (type.equals(URL.class)) {
|
||||
return (T) res.getURL(columnIndex);
|
||||
|
||||
} else if (type.equals(Struct.class)) {
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
|
||||
} else if (type.equals(RowId.class)) {
|
||||
return (T) res.getRowId(columnIndex);
|
||||
|
||||
} else if (type.equals(NClob.class)) {
|
||||
return (T) res.getNClob(columnIndex);
|
||||
|
||||
} else if (type.equals(SQLXML.class)) {
|
||||
return (T) res.getSQLXML(columnIndex);
|
||||
|
||||
} else if (type.equals(LocalDate.class)) {
|
||||
return (T) getLocalDate(res,columnIndex);
|
||||
|
||||
} else if (type.equals(LocalDateTime.class)) {
|
||||
return (T) getLocalDateTime(res,columnIndex);
|
||||
|
||||
} else if (type.equals(LocalTime.class)) {
|
||||
return (T) getLocalTime(res,columnIndex);
|
||||
|
||||
} else if (type.equals(OffsetDateTime.class)) {
|
||||
try {
|
||||
String odt = res.getString(columnIndex);
|
||||
return odt == null ? null : (T) OffsetDateTime.parse(odt);
|
||||
} catch (DateTimeParseException e) {
|
||||
// Let it continue and try by object deserialization.
|
||||
}
|
||||
|
||||
} else if (type.equals(OffsetTime.class)) {
|
||||
try {
|
||||
String ot = res.getString(columnIndex);
|
||||
return ot == null ? null : (T) OffsetTime.parse(ot);
|
||||
} catch (DateTimeParseException e) {}
|
||||
}else if(type.isEnum()) {
|
||||
try {
|
||||
String _vl = res.getString(columnIndex);
|
||||
if(!StringUtils.isEmpty(_vl)) {
|
||||
Method method=Enum.class.getMethod("valueOf", String.class);
|
||||
return (T) method.invoke(null,_vl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return (T) res.getObject(columnIndex);
|
||||
}
|
||||
|
||||
private static LocalDate getLocalDate(ResultSet res,int columnIndex) throws SQLException {
|
||||
Date date = res.getDate(columnIndex);
|
||||
if(date!=null) {
|
||||
return date.toLocalDate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LocalDateTime getLocalDateTime(ResultSet res,int columnIndex) throws SQLException {
|
||||
Timestamp date = res.getTimestamp(columnIndex);
|
||||
if(date!=null) {
|
||||
return date.toLocalDateTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LocalTime getLocalTime(ResultSet res,int columnIndex) throws SQLException {
|
||||
Time date = res.getTime(columnIndex);
|
||||
if(date!=null) {
|
||||
return date.toLocalTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BigInteger getBigInteger(ResultSet res,int columnIndex) throws SQLException {
|
||||
String stringVal = res.getString(columnIndex);
|
||||
if (stringVal == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BigInteger(stringVal);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new RuntimeException("ResultSet.Bad_format_for_BigInteger");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getObject(ResultSet res,String name,Class<T> type) throws SQLException {
|
||||
if (type.equals(String.class)) {
|
||||
return (T) res.getString(name);
|
||||
|
||||
} else if (type.equals(BigDecimal.class)) {
|
||||
return (T) res.getBigDecimal(name);
|
||||
|
||||
} else if (type.equals(BigInteger.class)) {
|
||||
return (T) getBigInteger(res, name);
|
||||
|
||||
} else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE)) {
|
||||
return (T) Boolean.valueOf(res.getBoolean(name));
|
||||
|
||||
} else if (type.equals(Integer.class) || type.equals(Integer.TYPE)) {
|
||||
return (T) Integer.valueOf(res.getInt(name));
|
||||
|
||||
} else if (type.equals(Long.class) || type.equals(Long.TYPE)) {
|
||||
return (T) Long.valueOf(res.getLong(name));
|
||||
|
||||
} else if (type.equals(Float.class) || type.equals(Float.TYPE)) {
|
||||
return (T) Float.valueOf(res.getFloat(name));
|
||||
|
||||
} else if (type.equals(Double.class) || type.equals(Double.TYPE)) {
|
||||
return (T) Double.valueOf(res.getDouble(name));
|
||||
|
||||
} else if (type.equals(byte[].class)) {
|
||||
return (T) res.getBytes(name);
|
||||
|
||||
} else if (type.equals(Date.class)) {
|
||||
return (T) res.getDate(name);
|
||||
|
||||
} else if (type.equals(Time.class)) {
|
||||
return (T) res.getTime(name);
|
||||
|
||||
} else if (type.equals(java.util.Date.class) || type.equals(Timestamp.class)) {
|
||||
return (T) res.getTimestamp(name);
|
||||
|
||||
} else if (type.equals(java.sql.Clob.class)) {
|
||||
return (T) res.getClob(name);
|
||||
|
||||
} else if (type.equals(java.sql.Blob.class)) {
|
||||
return (T) res.getBlob(name);
|
||||
|
||||
} else if (type.equals(Array.class)) {
|
||||
return (T) res.getArray(name);
|
||||
|
||||
} else if (type.equals(Ref.class)) {
|
||||
return (T) res.getRef(name);
|
||||
|
||||
} else if (type.equals(URL.class)) {
|
||||
return (T) res.getURL(name);
|
||||
|
||||
} else if (type.equals(Struct.class)) {
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
|
||||
} else if (type.equals(RowId.class)) {
|
||||
return (T) res.getRowId(name);
|
||||
|
||||
} else if (type.equals(NClob.class)) {
|
||||
return (T) res.getNClob(name);
|
||||
|
||||
} else if (type.equals(SQLXML.class)) {
|
||||
return (T) res.getSQLXML(name);
|
||||
|
||||
} else if (type.equals(LocalDate.class)) {
|
||||
return (T) getLocalDate(res,name);
|
||||
|
||||
} else if (type.equals(LocalDateTime.class)) {
|
||||
return (T) getLocalDateTime(res,name);
|
||||
|
||||
} else if (type.equals(LocalTime.class)) {
|
||||
return (T) getLocalTime(res,name);
|
||||
|
||||
} else if (type.equals(OffsetDateTime.class)) {
|
||||
try {
|
||||
String odt = res.getString(name);
|
||||
return odt == null ? null : (T) OffsetDateTime.parse(odt);
|
||||
} catch (DateTimeParseException e) {
|
||||
// Let it continue and try by object deserialization.
|
||||
}
|
||||
|
||||
} else if (type.equals(OffsetTime.class)) {
|
||||
try {
|
||||
String ot = res.getString(name);
|
||||
return ot == null ? null : (T) OffsetTime.parse(ot);
|
||||
} catch (DateTimeParseException e) {}
|
||||
}else if(type.isEnum()) {
|
||||
try {
|
||||
String _vl = res.getString(name);
|
||||
if(!StringUtils.isEmpty(_vl)) {
|
||||
Method method=Enum.class.getMethod("valueOf", String.class);
|
||||
return (T) method.invoke(null,_vl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return (T) res.getObject(name);
|
||||
}
|
||||
|
||||
private static LocalDate getLocalDate(ResultSet res,String name) throws SQLException {
|
||||
Date date = res.getDate(name);
|
||||
if(date!=null) {
|
||||
return date.toLocalDate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LocalDateTime getLocalDateTime(ResultSet res,String name) throws SQLException {
|
||||
Timestamp date = res.getTimestamp(name);
|
||||
if(date!=null) {
|
||||
return date.toLocalDateTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LocalTime getLocalTime(ResultSet res,String name) throws SQLException {
|
||||
Time date = res.getTime(name);
|
||||
if(date!=null) {
|
||||
return date.toLocalTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BigInteger getBigInteger(ResultSet res,String name) throws SQLException {
|
||||
String stringVal = res.getString(name);
|
||||
if (stringVal == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BigInteger(stringVal);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new RuntimeException("ResultSet.Bad_format_for_BigInteger");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <T>T getSingleValue(ResultSet res,Class<T> klass) throws SQLException{
|
||||
if(res.next()) {
|
||||
return getObject(res,1, klass);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结果集的标题名称
|
||||
* */
|
||||
public static Map<String,String> getMapColumns(ResultSet set) throws SQLException{
|
||||
ResultSetMetaData meta=set.getMetaData();
|
||||
Map<String,String> result=new HashMap<>();
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
result.put(meta.getColumnLabel(i), parseKey(meta.getColumnLabel(i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结果集的标题名称
|
||||
* */
|
||||
public static Set<String> getResultColumns(ResultSet set) throws SQLException{
|
||||
ResultSetMetaData meta=set.getMetaData();
|
||||
Set<String> result=new HashSet<>(meta.getColumnCount());
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
result.add(meta.getColumnLabel(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String parseKey(String str) {
|
||||
str = str.toLowerCase();
|
||||
Matcher matcher = linePattern.matcher(str);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,433 @@
|
||||
package com.pictc.jdbc;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class SqlBuilder {
|
||||
|
||||
public static final String MysqlSeparator="`";
|
||||
|
||||
public static final String KBaseSeparator="\"";
|
||||
|
||||
public static final String OracleSeparator="\"";
|
||||
|
||||
public static final String strSeparator="'";
|
||||
|
||||
public static final String space=" ";
|
||||
|
||||
public static final String dot=".";
|
||||
|
||||
public static final String comma=",";
|
||||
|
||||
public static final String enter="\n\t\t";
|
||||
|
||||
public static final String leftBracket="(";
|
||||
|
||||
public static final String rightBracket=")";
|
||||
|
||||
public static final String placeholder="?";
|
||||
|
||||
public static final String as=" AS ";
|
||||
|
||||
public static final String select="SELECT ";
|
||||
|
||||
public static final String distinct=" DISTINCT";
|
||||
|
||||
public static final String from=" FROM ";
|
||||
|
||||
public static final String leftJoin=" LEFT JOIN ";
|
||||
|
||||
public static final String rightJoin=" RIGHT JOIN ";
|
||||
|
||||
public static final String innerJoin=" INNER JOIN ";
|
||||
|
||||
public static final String on=" ON ";
|
||||
|
||||
public static final String where=" WHERE ";
|
||||
|
||||
public static final String AND =" AND ";
|
||||
|
||||
public static final String OR =" OR ";
|
||||
|
||||
public static final String not=" NOT ";
|
||||
|
||||
public static final String eq=" = ";
|
||||
|
||||
public static final String notEq=" <> ";
|
||||
|
||||
public static final String between=" BETWEEN ";
|
||||
|
||||
public static final String exists=" EXISTS ";
|
||||
|
||||
public static final String in=" IN(";
|
||||
|
||||
public static final String gt=" > ";
|
||||
|
||||
public static final String gtEq=" >= ";
|
||||
|
||||
public static final String lt=" < ";
|
||||
|
||||
public static final String ltEq=" <= ";
|
||||
|
||||
public static final String like=" LIKE ";
|
||||
|
||||
public static final String isNull=" IS NULL ";
|
||||
|
||||
public static final String isNotNull=" IS NOT NULL ";
|
||||
|
||||
public static final String groupBy=" GROUP BY";
|
||||
|
||||
public static final String having=" HAVING ";
|
||||
|
||||
public static final String orderBy=" ORDER BY ";
|
||||
|
||||
public static final String orderAsc=" ASC ";
|
||||
|
||||
public static final String orderDesc=" DESC ";
|
||||
|
||||
public static final String avg=" AVG";
|
||||
|
||||
public static final String min=" MIN";
|
||||
|
||||
public static final String max=" MAX";
|
||||
|
||||
public static final String count=" COUNT";
|
||||
|
||||
public static final String sum=" SUM";
|
||||
|
||||
public static final String insert="INSERT INTO ";
|
||||
|
||||
public static final String values=" VALUES";
|
||||
|
||||
public static final String update="UPDATE ";
|
||||
|
||||
public static final String set=" SET ";
|
||||
|
||||
public static final String delete="DELETE ";
|
||||
|
||||
public static final String limit=" LIMIT ";
|
||||
|
||||
public static final String offset=" OFFSET ";
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
private String separator = KBaseSeparator;
|
||||
|
||||
public SqlBuilder() {
|
||||
|
||||
}
|
||||
|
||||
public SqlBuilder(String separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
public static SqlBuilder mysql() {
|
||||
return new SqlBuilder(MysqlSeparator);
|
||||
}
|
||||
|
||||
public static SqlBuilder oracle() {
|
||||
return new SqlBuilder(OracleSeparator);
|
||||
}
|
||||
|
||||
public static SqlBuilder kbase() {
|
||||
return new SqlBuilder(KBaseSeparator);
|
||||
}
|
||||
|
||||
public String getSeparator() {
|
||||
return separator;
|
||||
}
|
||||
|
||||
public SqlBuilder space() {
|
||||
builder.append(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder dot() {
|
||||
builder.append(dot);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder comma() {
|
||||
builder.append(comma);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder enter() {
|
||||
builder.append(enter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder leftBracket() {
|
||||
builder.append(leftBracket);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder rightBracket() {
|
||||
builder.append(rightBracket);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder leftJoin() {
|
||||
builder.append(leftJoin);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder rightJoin() {
|
||||
builder.append(rightJoin);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder innerJoin() {
|
||||
builder.append(innerJoin);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder on() {
|
||||
builder.append(on);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder append(Object obj) {
|
||||
builder.append(obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder appendSeparator(String... names) {
|
||||
Assert.isTrue(!(names==null || names.length==0),"参数不能为空!");
|
||||
boolean flag = false;
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if(names[i]!=null) {
|
||||
if(!flag) {
|
||||
flag = true;
|
||||
}else {
|
||||
dot();
|
||||
}
|
||||
builder.append(separator);
|
||||
builder.append(names[i]);
|
||||
builder.append(separator);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder appendStrSeparator(String... names) {
|
||||
Assert.isTrue(!(names==null || names.length==0),"参数不能为空!");
|
||||
boolean flag = false;
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if(names[i]!=null) {
|
||||
if(!flag) {
|
||||
flag = true;
|
||||
}else {
|
||||
dot();
|
||||
}
|
||||
builder.append(strSeparator);
|
||||
builder.append(names[i]);
|
||||
builder.append(strSeparator);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public StringBuilder stringBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public SqlBuilder where() {
|
||||
builder.append(where);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder and() {
|
||||
builder.append(AND);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder or() {
|
||||
builder.append(OR);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder not() {
|
||||
builder.append(not);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder eq() {
|
||||
builder.append(eq);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder notEq() {
|
||||
builder.append(notEq);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder between() {
|
||||
builder.append(between);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder exists() {
|
||||
builder.append(exists);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder inStart() {
|
||||
builder.append(in);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder inEnd() {
|
||||
builder.append(rightBracket);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder gt() {
|
||||
builder.append(gt);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder gtEq() {
|
||||
builder.append(gtEq);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder lt() {
|
||||
builder.append(lt);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder ltEq() {
|
||||
builder.append(ltEq);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder like() {
|
||||
builder.append(like);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder isNull() {
|
||||
builder.append(isNull);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder isNotNull() {
|
||||
builder.append(isNotNull);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder groupBy() {
|
||||
builder.append(groupBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder having() {
|
||||
builder.append(having);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder orderBy() {
|
||||
builder.append(orderBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder asc() {
|
||||
builder.append(orderAsc);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder desc() {
|
||||
builder.append(orderDesc);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder avg() {
|
||||
builder.append(avg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder min() {
|
||||
builder.append(min);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder max() {
|
||||
builder.append(max);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder count() {
|
||||
builder.append(count);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder sum() {
|
||||
builder.append(sum);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder insertInto() {
|
||||
builder.append(insert);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder values() {
|
||||
builder.append(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder update() {
|
||||
builder.append(update);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder set() {
|
||||
builder.append(set);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder delete() {
|
||||
builder.append(delete);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder placeholder() {
|
||||
builder.append(placeholder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder as() {
|
||||
builder.append(as);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder select() {
|
||||
builder.append(select);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder distinct() {
|
||||
builder.append(distinct);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder from() {
|
||||
builder.append(from);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder limit() {
|
||||
builder.append(limit);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SqlBuilder limitFull() {
|
||||
builder.append(limit).append(placeholder).append(offset).append(placeholder);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
public class AliasManager {
|
||||
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.compress.utils.Sets;
|
||||
import com.pictc.utils.DateUtils;
|
||||
import com.pictc.utils.StringUtils;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class Criteria implements Serializable{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
private static final Set<Class<?>> DoubleClass = Sets.newHashSet(Double.class,double.class,float.class,Float.class,BigDecimal.class);
|
||||
|
||||
private static final Set<Class<?>> DateClass = Sets.newHashSet(Date.class,Timestamp.class,java.sql.Date.class,Time.class);
|
||||
|
||||
private static final Set<Class<?>> IntClass = Sets.newHashSet(int.class,Integer.class,byte.class,Byte.class,short.class,Short.class,long.class,Long.class,BigInteger.class);
|
||||
|
||||
public enum Type{
|
||||
EQ("="),LIKE("LIKE"),GT(">"),EQ_GT(">="),LT("<"),EQ_LT("<="),
|
||||
BETWEEN("BETWEEN"),IN("IN"),NULL("IS NULL");
|
||||
|
||||
private String sql;
|
||||
|
||||
private Type(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum DataType{
|
||||
DATE,INTEGER,DOUBLE,STRING
|
||||
}
|
||||
|
||||
@ApiModelProperty(name = "条件连接条件,默认为AND")
|
||||
private Link link = Link.AND;
|
||||
|
||||
@ApiModelProperty(name = "条件是否取反")
|
||||
private boolean not;
|
||||
|
||||
@ApiModelProperty(name = "属性名")
|
||||
private String field;
|
||||
|
||||
@ApiModelProperty(name = "条件操作符,默认为EQ")
|
||||
private Type type = Type.EQ;
|
||||
|
||||
private DataType dataType = null; //数据类型
|
||||
|
||||
@ApiModelProperty(name = "条件值")
|
||||
private Object val;
|
||||
|
||||
@ApiModelProperty(name = "条件第二值")
|
||||
private Object secondVal;
|
||||
|
||||
@ApiModelProperty(name = "条件in的List值")
|
||||
private List<Object> listVal;
|
||||
|
||||
private String sql;
|
||||
|
||||
public JdbcType getJdbc() {
|
||||
switch (dataType) {
|
||||
case DATE: return JdbcType.TIMESTAMP;
|
||||
case INTEGER: return JdbcType.INTEGER;
|
||||
case DOUBLE: return JdbcType.DECIMAL;
|
||||
default: return JdbcType.VARCHAR;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getVal() {
|
||||
if(val!=null) {
|
||||
return parseVal(val);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Criteria setVal(Object val) {
|
||||
this.val = val;
|
||||
parseDataType(val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object getSecondVal() {
|
||||
if(secondVal!=null) {
|
||||
return parseVal(secondVal);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Object> getListVal() {
|
||||
if(listVal!=null && !listVal.isEmpty()) {
|
||||
List<Object> res = new ArrayList<Object>(listVal.size());
|
||||
for (Object _lval : listVal) {
|
||||
res.add(parseVal(_lval));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Criteria setListVal(List<Object> listVal) {
|
||||
this.listVal = listVal;
|
||||
if(listVal!=null && !listVal.isEmpty()) {
|
||||
Object object = listVal.get(0);
|
||||
parseDataType(object);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void parseDataType(Object _val) {
|
||||
if(dataType==null) {
|
||||
if(_val!=null) {
|
||||
Class<?> clazz = _val.getClass();
|
||||
if(DoubleClass.contains(clazz)) {
|
||||
dataType = DataType.DOUBLE;
|
||||
}else if(DateClass.contains(clazz)) {
|
||||
dataType = DataType.DATE;
|
||||
}else if(IntClass.contains(clazz)) {
|
||||
dataType = DataType.INTEGER;
|
||||
}else {
|
||||
dataType = DataType.STRING;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object parseVal(Object _val) {
|
||||
String _str = _val.toString();
|
||||
if(StringUtils.isEmpty(_str)) return null;
|
||||
if(dataType==DataType.DATE) {
|
||||
if(_val instanceof Timestamp || _val instanceof Date) {
|
||||
return _val;
|
||||
}else if(_str.matches("^\\d+$")) {
|
||||
return new Timestamp(Long.valueOf(_str));
|
||||
}
|
||||
return Timestamp.from(DateUtils.stringToDate(_str,DATE_FORMAT).toInstant());
|
||||
}else if(dataType==DataType.DOUBLE) {
|
||||
if(_val instanceof BigDecimal) {
|
||||
return _val;
|
||||
}
|
||||
return new BigDecimal(_str);
|
||||
}else if(dataType==DataType.INTEGER) {
|
||||
if(_val instanceof Integer) {
|
||||
return _val;
|
||||
}
|
||||
return Integer.valueOf(_str);
|
||||
}
|
||||
return _str;
|
||||
}
|
||||
|
||||
public boolean isBetween() {
|
||||
return type==Type.BETWEEN;
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return type==Type.NULL;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return type==Type.IN;
|
||||
}
|
||||
|
||||
public boolean hasSql() {
|
||||
return !StringUtils.isEmpty(sql);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,143 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.pictc.jdbc.model.Criteria.Type;
|
||||
import com.pictc.utils.CollectionUtils;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public class CriteriaGroup implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(name = "条件组")
|
||||
private List<Criteria> criterias = CollectionUtils.newArrayList();
|
||||
|
||||
@ApiModelProperty(name = "条件组之间的连接方式:默认为AND")
|
||||
private Link link = Link.AND;
|
||||
|
||||
public boolean hasCriteria() {
|
||||
return criterias!=null && !criterias.isEmpty();
|
||||
}
|
||||
|
||||
public CriteriaGroup andSql(String sql,Object val) {
|
||||
return sql(Link.AND, sql, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orSql(String sql,Object val) {
|
||||
return sql(Link.OR, sql, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup sql(Link link,String sql,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.EQ).setSql(sql).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup add(Criteria criteria) {
|
||||
criterias.add(criteria);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andEq(String field,Object val) {
|
||||
return eq(Link.AND, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orEq(String field,Object val) {
|
||||
return eq(Link.OR, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup eq(Link link,String field,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.EQ).setField(field).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andLike(String field,Object val) {
|
||||
return like(Link.AND, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orLike(String field,Object val) {
|
||||
return like(Link.OR, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup like(Link link,String field,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.LIKE).setField(field).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andGt(String field,Object val) {
|
||||
return gt(Link.AND, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orGt(String field,Object val) {
|
||||
return gt(Link.OR, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup gt(Link link,String field,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.GT).setField(field).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andEqLt(String field,Object val) {
|
||||
return eqLt(Link.AND, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orEqLt(String field,Object val) {
|
||||
return eqLt(Link.OR, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup eqLt(Link link,String field,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.EQ_LT).setField(field).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andEqGt(String field,Object val) {
|
||||
return eqGt(Link.AND, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup orEqGt(String field,Object val) {
|
||||
return eqGt(Link.OR, field, val);
|
||||
}
|
||||
|
||||
public CriteriaGroup eqGt(Link link,String field,Object val) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.EQ_GT).setField(field).setVal(val));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andBetween(String field,Object val,Object secondVal) {
|
||||
return between(Link.AND, field, val, secondVal);
|
||||
}
|
||||
|
||||
public CriteriaGroup orBetween(String field,Object val,Object secondVal) {
|
||||
return between(Link.OR, field, val, secondVal);
|
||||
}
|
||||
|
||||
public CriteriaGroup between(Link link,String field,Object val,Object secondVal) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.BETWEEN).setField(field).setVal(val).setSecondVal(secondVal));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaGroup andIn(String field,List<Object> listVal) {
|
||||
return in(Link.AND, field, listVal);
|
||||
}
|
||||
|
||||
public CriteriaGroup orIn(String field,List<Object> listVal) {
|
||||
return in(Link.OR, field, listVal);
|
||||
}
|
||||
|
||||
public CriteriaGroup in(Link link,String field,List<Object> listVal) {
|
||||
criterias.add(new Criteria().setLink(link).setType(Type.IN).setField(field).setListVal(listVal));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2023年7月17日 上午9:33:16
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class ExportColumn {
|
||||
|
||||
private String field;
|
||||
|
||||
private String title;
|
||||
|
||||
private int width;
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2023年7月17日 上午9:32:42
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class ExportParam implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<ExportColumn> columns;
|
||||
|
||||
private JSONObject filters;
|
||||
|
||||
private String sqlId;
|
||||
|
||||
private CriteriaGroup criterias;
|
||||
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class JdbcParam implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int jdbc;
|
||||
|
||||
private Object val;
|
||||
|
||||
private boolean out;
|
||||
|
||||
private Class<?> javaType;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return val+"("+JdbcType.valueOf(jdbc).name()+")";
|
||||
}
|
||||
|
||||
public static JdbcParam ofOut(int jdbc,Class<?> javaType) {
|
||||
return new JdbcParam().setJdbc(jdbc).setJavaType(javaType).setOut(true);
|
||||
}
|
||||
|
||||
public static JdbcParam of(int jdbc,Class<?> javaType,Object val) {
|
||||
return new JdbcParam().setJdbc(jdbc).setJavaType(javaType).setVal(val);
|
||||
}
|
||||
|
||||
public static JdbcParam ofString(String val) {
|
||||
return new JdbcParam().setJdbc(Types.VARCHAR).setJavaType(String.class).setVal(val);
|
||||
}
|
||||
|
||||
// 整数类型
|
||||
public static JdbcParam ofInt(Integer val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.INTEGER)
|
||||
.setJavaType(Integer.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 长整数类型
|
||||
public static JdbcParam ofLong(Long val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.BIGINT)
|
||||
.setJavaType(Long.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 布尔类型
|
||||
public static JdbcParam ofBoolean(Boolean val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.BOOLEAN)
|
||||
.setJavaType(Boolean.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 浮点类型
|
||||
public static JdbcParam ofFloat(Float val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.FLOAT)
|
||||
.setJavaType(Float.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 双精度浮点类型
|
||||
public static JdbcParam ofDouble(Double val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.DOUBLE)
|
||||
.setJavaType(Double.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 字节类型
|
||||
public static JdbcParam ofByte(Byte val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.TINYINT)
|
||||
.setJavaType(Byte.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 短整数类型
|
||||
public static JdbcParam ofShort(Short val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.SMALLINT)
|
||||
.setJavaType(Short.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 日期类型
|
||||
public static JdbcParam ofDate(Date val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.DATE)
|
||||
.setJavaType(Date.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 时间戳类型
|
||||
public static JdbcParam ofTimestamp(Timestamp val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.TIMESTAMP)
|
||||
.setJavaType(java.sql.Timestamp.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
|
||||
// 高精度小数类型
|
||||
public static JdbcParam ofBigDecimal(BigDecimal val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.DECIMAL)
|
||||
.setJavaType(BigDecimal.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// 大整数类型
|
||||
public static JdbcParam ofBigInteger(BigInteger val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.NUMERIC)
|
||||
.setJavaType(BigInteger.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// Java 8 本地日期类型 (仅日期)
|
||||
public static JdbcParam ofLocalDate(LocalDate val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.DATE)
|
||||
.setJavaType(LocalDate.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// Java 8 本地时间类型 (仅时间)
|
||||
public static JdbcParam ofLocalTime(LocalTime val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.TIME)
|
||||
.setJavaType(LocalTime.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
// Java 8 本地日期时间类型 (日期+时间)
|
||||
public static JdbcParam ofLocalDateTime(LocalDateTime val) {
|
||||
return new JdbcParam()
|
||||
.setJdbc(Types.TIMESTAMP)
|
||||
.setJavaType(LocalDateTime.class)
|
||||
.setVal(val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.sql.Types;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public enum JdbcType {
|
||||
|
||||
CHAR(Types.CHAR,"CHAR",String.class,false,1,null),VARCHAR(Types.VARCHAR,"VARCHAR",String.class,false,255,null),
|
||||
|
||||
INTEGER(Types.INTEGER,"INTEGER",Integer.class,true,7,null),BIGINT(Types.BIGINT,"BIGINT",Long.class,true,12,null),
|
||||
DECIMAL(Types.DECIMAL,"DECIMAL",java.math.BigDecimal.class,true,60,30),
|
||||
|
||||
FLOAT(Types.FLOAT,"FLOAT",float.class,true,10,5),DOUBLE(Types.DOUBLE,"DOUBLE",double.class,true,30,10),
|
||||
|
||||
DATE(Types.DATE,"DATE",java.sql.Date.class,false,null,null),TIMESTAMP(Types.TIMESTAMP,"DATETIME",java.sql.Timestamp.class,false,null,null),
|
||||
|
||||
CLOB(Types.CLOB,"CLOB",java.sql.Clob.class,false,null,null),
|
||||
|
||||
JSONOBJ(Types.LONGVARCHAR,"JSON",com.alibaba.fastjson.JSONObject.class,false,null,null),
|
||||
JSONLIST(Types.LONGVARCHAR,"JSON",com.alibaba.fastjson.JSONArray.class,false,null,null);
|
||||
|
||||
private Integer jdbc;
|
||||
|
||||
private Class<?> javaClass;
|
||||
|
||||
private boolean isDecimal;
|
||||
|
||||
private String nativeName;
|
||||
|
||||
private Integer leng;
|
||||
|
||||
private Integer digits;
|
||||
|
||||
private JdbcType(int jdbcType,String nativeName,Class<?> javaClass, boolean isDecimal,Integer leng,Integer digits) {
|
||||
this.jdbc = jdbcType;
|
||||
this.javaClass = javaClass;
|
||||
this.isDecimal = isDecimal;
|
||||
this.nativeName = nativeName;
|
||||
this.leng = leng;
|
||||
this.digits = digits;
|
||||
}
|
||||
|
||||
public boolean isDate() {
|
||||
return this == DATE || this==TIMESTAMP;
|
||||
}
|
||||
|
||||
public static JdbcType valueOf(int jdbc) {
|
||||
JdbcType[] values = JdbcType.values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
JdbcType item = values[i];
|
||||
if(item.getJdbc()==jdbc) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return JdbcType.VARCHAR;
|
||||
}
|
||||
|
||||
public static JdbcType valueOf(Class<?> java) {
|
||||
JdbcType[] values = JdbcType.values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
JdbcType item = values[i];
|
||||
if(item.getJavaClass().equals(java)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return JdbcType.VARCHAR;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
public enum Link {
|
||||
|
||||
AND,OR
|
||||
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
|
||||
import com.pictc.jdbc.model.Criteria.DataType;
|
||||
import com.pictc.utils.DateUtils;
|
||||
import com.pictc.utils.StringUtils;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2022年12月13日 上午11:44:58
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class ParamItem implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
private DataType dataType; //数据类型
|
||||
|
||||
private Object val;
|
||||
|
||||
public JdbcParam toParam() {
|
||||
JdbcType jdbc = getJdbc();
|
||||
return new JdbcParam().setJavaType(jdbc.getJavaClass()).setJdbc(jdbc.getJdbc()).setVal(parseVal(val));
|
||||
}
|
||||
|
||||
public JdbcType getJdbc() {
|
||||
switch (dataType) {
|
||||
case DATE: return JdbcType.TIMESTAMP;
|
||||
case INTEGER: return JdbcType.INTEGER;
|
||||
case DOUBLE: return JdbcType.DECIMAL;
|
||||
default: return JdbcType.VARCHAR;
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getJavaType(){
|
||||
switch (dataType) {
|
||||
case DATE: return Timestamp.class;
|
||||
case INTEGER: return Integer.class;
|
||||
case DOUBLE: return Double.class;
|
||||
default: return String.class;
|
||||
}
|
||||
}
|
||||
|
||||
private Object parseVal(Object _val) {
|
||||
String _str = _val.toString();
|
||||
if(StringUtils.isEmpty(_str)) return null;
|
||||
if(dataType==DataType.DATE) {
|
||||
if(_val instanceof Timestamp || _val instanceof Date) {
|
||||
return _val;
|
||||
}else if(_str.matches("^\\d+$")) {
|
||||
return new Timestamp(Long.valueOf(_str));
|
||||
}
|
||||
return Timestamp.from(DateUtils.stringToDate(_str,DATE_FORMAT).toInstant());
|
||||
}else if(dataType==DataType.DOUBLE) {
|
||||
if(_val instanceof BigDecimal) {
|
||||
return _val;
|
||||
}
|
||||
return new BigDecimal(_str);
|
||||
}else if(dataType==DataType.INTEGER) {
|
||||
if(_val instanceof Integer) {
|
||||
return _val;
|
||||
}
|
||||
return Integer.valueOf(_str);
|
||||
}
|
||||
return _str;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2022年12月13日 上午11:42:00
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@ApiModel
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public class ParamQueryBo implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String queryId;
|
||||
|
||||
private List<ParamItem> params;
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public class QueryOrder implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(name = "属性")
|
||||
private String field;
|
||||
|
||||
@ApiModelProperty(name = "排序方式:ASC,DESC,NONE,默认 ASC")
|
||||
private QueryOrderType type = QueryOrderType.ASC;
|
||||
|
||||
public enum QueryOrderType{
|
||||
ASC,DESC,NONE
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.pictc.jdbc.model.Criteria.DataType;
|
||||
import com.pictc.jdbc.model.Criteria.Type;
|
||||
import com.pictc.utils.CollectionUtils;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public class QueryParameter implements Serializable{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String queryId;
|
||||
|
||||
private Class<?> entityClass; //实体类型
|
||||
|
||||
@ApiModelProperty(name = "实体对象,会已eq方式转为查询条件")
|
||||
private JSONObject data;
|
||||
|
||||
@ApiModelProperty(name = "where条件")
|
||||
private List<CriteriaGroup> criterias;
|
||||
|
||||
@ApiModelProperty(name = "排序配置")
|
||||
private List<QueryOrder> orders;
|
||||
|
||||
@ApiModelProperty(name = "查询指定列")
|
||||
private Set<String> froms;
|
||||
|
||||
private int index;
|
||||
|
||||
private int size;
|
||||
|
||||
private boolean page;
|
||||
|
||||
@ApiModelProperty(hidden = true)
|
||||
public List<CriteriaGroup> getAllCriterias(){
|
||||
List<CriteriaGroup> res = null;
|
||||
if(criterias!=null) {
|
||||
res = CollectionUtils.newArrayList();
|
||||
for (CriteriaGroup group : criterias) {
|
||||
res.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
if(data!=null && !data.isEmpty()) {
|
||||
if(res==null) {
|
||||
res = CollectionUtils.newArrayList();
|
||||
}
|
||||
res.add(objToCriteria(data));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private CriteriaGroup objToCriteria(JSONObject pojo) {
|
||||
CriteriaGroup group = new CriteriaGroup();
|
||||
for (String key : pojo.keySet()) {
|
||||
Object val = pojo.get(key);
|
||||
if(val==null || val instanceof JSONObject || val instanceof JSONArray) {
|
||||
continue;
|
||||
}else {
|
||||
JdbcType type = JdbcType.valueOf(val.getClass());
|
||||
DataType dtype = DataType.STRING;
|
||||
if(type.isDecimal()) {
|
||||
dtype = DataType.DOUBLE;
|
||||
}else if(type.isDate()) {
|
||||
dtype = DataType.DATE;
|
||||
}
|
||||
group.add(new Criteria().setType(Type.EQ).setVal(val).setDataType(dtype).setField(key));
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.ibatis.mapping.ResultFlag;
|
||||
import org.apache.ibatis.mapping.ResultMapping;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class TResultCol {
|
||||
|
||||
private String property;
|
||||
|
||||
private String column;
|
||||
|
||||
private String alias;
|
||||
|
||||
private Class<?> javaType;
|
||||
|
||||
private JdbcType jdbcType;
|
||||
|
||||
private TypeHandler<?> typeHandler;
|
||||
|
||||
private String nestedResultMapId;
|
||||
|
||||
private String nestedQueryId;
|
||||
|
||||
private Set<String> notNullColumns;
|
||||
|
||||
private String columnPrefix;
|
||||
|
||||
private List<ResultFlag> flags;
|
||||
|
||||
private List<ResultMapping> composites;
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pictc.jdbc.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.pictc.datalog.LogTableInfo;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class TResultMap {
|
||||
|
||||
private String id;
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private LogTableInfo tabInfo;
|
||||
|
||||
private String alias;
|
||||
|
||||
private List<TResultCol> propertys;
|
||||
|
||||
private TResultCol idProperty;
|
||||
|
||||
private List<TResultMap> ones;
|
||||
|
||||
private List<TResultMap> manys;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.pictc.orm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class BaseMasterEntity implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Long createUserId;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createDate;
|
||||
/**
|
||||
* 修改人ID
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.UPDATE)
|
||||
private Long modifyUserId;
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.UPDATE)
|
||||
private LocalDateTime modifyDate;
|
||||
/**
|
||||
* 逻辑删除标识
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@TableLogic
|
||||
private Integer deleteMark;
|
||||
/**
|
||||
* 启用/作废标识
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Integer enabledMark;
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@ApiModelProperty("")
|
||||
private Long tenantId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ArrayUtils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T[] of(T... parameters) {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>T[] valueOf(List<T> list){
|
||||
if(list!=null) {
|
||||
T[] result = null;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
T item = list.get(i);
|
||||
if(result==null) {
|
||||
result = (T[]) Array.newInstance(item.getClass(),list.size());
|
||||
}
|
||||
result[i] = item;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T[] ofCollection(Collection<T> objs){
|
||||
T[] result=null;
|
||||
if(objs!=null) {
|
||||
Iterator<T> it=objs.iterator();
|
||||
int i=0;
|
||||
while (it.hasNext()) {
|
||||
T item =it.next();
|
||||
if(result==null) {
|
||||
result = (T[]) Array.newInstance(item.getClass(),objs.size());
|
||||
}
|
||||
result[i] = item;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> String join(T[] array){
|
||||
return join(array,",",null);
|
||||
}
|
||||
|
||||
|
||||
public static <T> String join(T[] array,String split){
|
||||
return join(array, split, null);
|
||||
}
|
||||
|
||||
public static <T> String join(T[] array,String split,String suffix){
|
||||
if(array==null || array.length==0){
|
||||
return null;
|
||||
}
|
||||
StringBuilder str=new StringBuilder();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if(i>0) {
|
||||
str.append(split);
|
||||
}
|
||||
if(suffix!=null) str.append(suffix);
|
||||
str.append(array[i].toString());
|
||||
if(suffix!=null) str.append(suffix);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,447 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.pictc.exceptions.TFieldException;
|
||||
import com.pictc.exceptions.TMethodException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2023年8月11日
|
||||
* @Description: java对象反射工具类
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public class BeanUtils {
|
||||
|
||||
|
||||
private BeanUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 获取java类的属性map集合
|
||||
* @param @param cls
|
||||
* @param @return 参数
|
||||
* @return Map<String,Field> 返回类型
|
||||
* @throws
|
||||
*/
|
||||
public static Map<String, Field> getMapFields(Class<?> cls) {
|
||||
Map<String, Field> fields = CollectionUtils.newHashMap();
|
||||
if (cls != null) {
|
||||
List<Field> fieldList = new ArrayList<Field>();
|
||||
Set<String> names = new HashSet<String>();
|
||||
getFields(cls, fieldList,names);
|
||||
for (Field field : fieldList) {
|
||||
if (hasGetSet(field, cls)) {
|
||||
fields.put(field.getName(), field);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 获取对象非空值的Map集合
|
||||
* @param @param obj
|
||||
* @param @return 参数
|
||||
* @return Map<String,Object> 返回类型
|
||||
* @throws
|
||||
*/
|
||||
public static Map<String,Object> getBeanNotNullValue(Object obj){
|
||||
Map<String,Object> rel=CollectionUtils.newHashMap();
|
||||
if(obj==null) {
|
||||
return rel;
|
||||
}
|
||||
Field[] fields= getFields(obj.getClass());
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Object val=getFieldValue(fields[i], obj);
|
||||
if(val!=null) {
|
||||
rel.put(fields[i].getName(),val);
|
||||
}
|
||||
}
|
||||
return rel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 获取Class 包含指定注解类型的属性
|
||||
* @param @param cls
|
||||
* @param @param annotation
|
||||
* @param @return 参数
|
||||
* @return List<Field> 返回类型
|
||||
* @throws
|
||||
*/
|
||||
public static List<Field> getFields(Class<?> cls, Class<? extends Annotation> annotation) {
|
||||
List<Field> result = CollectionUtils.newArrayList();
|
||||
Field[] fields = getFields(cls);
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (field.isAnnotationPresent(annotation)) {
|
||||
result.add(field);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 获取Class 属性数组
|
||||
* @param @param cls
|
||||
* @param @return 参数
|
||||
* @return Field[] 返回类型
|
||||
* @throws
|
||||
*/
|
||||
public static Field[] getFields(Class<?> cls) {
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
Set<String> names = new HashSet<String>();
|
||||
getFields(cls, fields,names);
|
||||
Field[] result = new Field[fields.size()];
|
||||
fields.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static void getFields(Class<?> cls, List<Field> fields,Set<String> names) {
|
||||
if (!cls.equals(Object.class)) {
|
||||
Field[] _fields = cls.getDeclaredFields();
|
||||
for (int i = 0; i < _fields.length; i++) {
|
||||
Field field = _fields[i];
|
||||
if(names.contains(field.getName())) {
|
||||
continue;
|
||||
}
|
||||
fields.add(field);
|
||||
names.add(field.getName());
|
||||
}
|
||||
getFields(cls.getSuperclass(), fields,names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 判断class是否有指定属性名的getter、setter方法
|
||||
* @param fieldName
|
||||
* @param cls
|
||||
* @return boolean 返回类型
|
||||
*/
|
||||
public static boolean hasGetSet(String fieldName, Class<?> cls) {
|
||||
try {
|
||||
return hasGetSet(cls.getDeclaredField(fieldName), cls);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Class【"+cls+"】-属性【"+fieldName+"】获取getter、setter方法异常",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasGetSet(Field field, Class<?> cls) {
|
||||
Class<?> type = field.getType();
|
||||
String name = field.getName();
|
||||
String getName = null;
|
||||
String uname = getMethodName(name);
|
||||
if (type.equals(boolean.class) || type.equals(Boolean.class)) {
|
||||
if (name.startsWith("is")) {
|
||||
getName = name;
|
||||
} else {
|
||||
getName = "is" + uname;
|
||||
}
|
||||
} else {
|
||||
getName = "get" + uname;
|
||||
}
|
||||
String setName = "set" + uname;
|
||||
Class<?> beanType = cls;
|
||||
do {
|
||||
if (findGetSet(beanType, getName, setName, type)) {
|
||||
return true;
|
||||
}
|
||||
beanType = beanType.getSuperclass();
|
||||
} while (!Object.class.equals(beanType));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static boolean findGetSet(Class<?> beanType, String getName, String setName, Class<?> type) {
|
||||
Method getMethod = null;
|
||||
Method setMethod = null;
|
||||
try {
|
||||
getMethod = beanType.getDeclaredMethod(getName);
|
||||
setMethod = beanType.getDeclaredMethod(setName, type);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return getMethod != null && setMethod != null;
|
||||
}
|
||||
|
||||
|
||||
private static String getMethodName(String name) {
|
||||
return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
}
|
||||
|
||||
|
||||
public static void setFieldValue(Field field, Object value, Object bean) {
|
||||
try {
|
||||
if(field==null) {
|
||||
throw new TFieldException("setFieldValue时field不能为空");
|
||||
}
|
||||
if (!field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
field.set(bean, value);
|
||||
} catch (Exception e) {
|
||||
throw new TFieldException("setFieldValue异常", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void setFieldValue(String fieldName, Object value, Object bean) {
|
||||
setFieldValue(getField(fieldName, bean), value, bean);
|
||||
}
|
||||
|
||||
|
||||
public static <T> T getFieldValue(String fieldName, Object bean) {
|
||||
return getFieldValue(getField(fieldName, bean), bean);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> T getFieldValue(Field field, Object bean) {
|
||||
Object value = null;
|
||||
if(field==null) {
|
||||
throw new TFieldException("获取属性值时field不能为空");
|
||||
}
|
||||
if (!field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
try {
|
||||
value = field.get(bean);
|
||||
} catch (Exception e) {
|
||||
throw new TFieldException("getFieldValue异常", e);
|
||||
}
|
||||
return value==null?null:(T)value;
|
||||
}
|
||||
|
||||
public static Field getField(String fieldName, Object bean) {
|
||||
return getField(fieldName, bean.getClass());
|
||||
}
|
||||
|
||||
public static Field getField(String fieldName, Class<?> cls) {
|
||||
try {
|
||||
return cls.getDeclaredField(fieldName);
|
||||
} catch (Exception e) {
|
||||
throw new TFieldException("获取属性异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Class<?> cls) {
|
||||
return newInstance(cls,false);
|
||||
}
|
||||
|
||||
public static <T> T newInstance(ClassLoader loader,Class<?> cls) {
|
||||
return newInstance(loader,cls,false);
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Class<?> cls,boolean ignoreError) {
|
||||
return newInstance(null,cls,ignoreError);
|
||||
}
|
||||
|
||||
public static <T> T newInstance(ClassLoader loader,Class<?> cls,boolean ignoreError) {
|
||||
try {
|
||||
return (T) ClassUtils.loadClass(loader,cls.getName()).getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
if(!ignoreError) {
|
||||
throw new RuntimeException("实例化:Class【"+cls.getName()+"】异常",e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T newInstance(String className) {
|
||||
return newInstance(className, false);
|
||||
}
|
||||
|
||||
public static <T> T newInstance(String className,boolean ignoreError) {
|
||||
try {
|
||||
return (T) ClassUtils.loadClass(className).getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
if(!ignoreError) {
|
||||
throw new RuntimeException("实例化:Class【"+className+"】异常",e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T>T deepCopy(Object source){
|
||||
if(source!=null) {
|
||||
Map<String,Object> cache = CollectionUtils.newHashMap();
|
||||
try {
|
||||
return (T) deepCopy(source.getClass(),source,cache);
|
||||
} finally {
|
||||
cache.clear();
|
||||
cache = null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T>T deepCopy(Type javaType,Object source){
|
||||
if(source!=null) {
|
||||
Map<String,Object> cache = CollectionUtils.newHashMap();
|
||||
try {
|
||||
return (T) deepCopy(javaType,source,cache);
|
||||
} finally {
|
||||
cache.clear();
|
||||
cache = null;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Object deepCopy(Type javaType,Object source,Map<String,Object> cache){
|
||||
if(source==null) {
|
||||
return null;
|
||||
}
|
||||
String addr = Integer.toHexString(source.hashCode());
|
||||
if(cache.containsKey(addr)) {
|
||||
return cache.get(addr);
|
||||
}
|
||||
|
||||
TypeInfo type = new TypeInfo(javaType);
|
||||
Object target = null;
|
||||
if(type.isPrimitive() || type.isEnum()) {
|
||||
target = source;
|
||||
}else if(type.isArray()) {
|
||||
int length = Array.getLength(source);
|
||||
List<Object> list = new ArrayList<Object>(length);
|
||||
for (int j = 0; j < length; j += 1) {
|
||||
Object obj = Array.get(source, j);
|
||||
list.add(deepCopy(type.getArrayType(),obj));
|
||||
}
|
||||
target = list.toArray();
|
||||
}else if(type.isCollection()) {
|
||||
Collection<Object> cvals = (Collection<Object>) source;
|
||||
Collection<Object> nvals = type.newCollection();
|
||||
for (Object obj : cvals) {
|
||||
nvals.add(deepCopy(type.getCollectionType(),obj));
|
||||
}
|
||||
target = nvals;
|
||||
}else if(type.isMap()) {
|
||||
Map<Object, Object> mapVal = type.newMap();
|
||||
Map<?, ?> valMap = (Map<?, ?>) source;
|
||||
for (final Entry<?, ?> e : valMap.entrySet()) {
|
||||
final Object value = e.getValue();
|
||||
if (value != null) {
|
||||
mapVal.put(e.getKey(),deepCopy(value));
|
||||
}
|
||||
}
|
||||
target = mapVal;
|
||||
}else {
|
||||
Class<?> klass = type.getKlass();
|
||||
target = newInstance(klass);
|
||||
cache.put(addr,target);
|
||||
Field[] fields = getFields(klass);
|
||||
Class<?> sklazz = source.getClass();
|
||||
Map<String, Field> mapFields = getMapFields(sklazz);
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
Field sf = mapFields.get(field.getName());
|
||||
if(sf==null || !sf.getType().equals(field.getType())) {
|
||||
continue;
|
||||
}
|
||||
Object val = getFieldValue(sf, source);
|
||||
if(val!=null) {
|
||||
setFieldValue(field,deepCopy(field.getGenericType(),val, cache),target);
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用方法
|
||||
* */
|
||||
public static <T>T callMethod(Method method, Object obj, Object... values) throws InstantiationException,
|
||||
IllegalAccessException, NumberFormatException, IllegalArgumentException,
|
||||
InvocationTargetException {
|
||||
return (T) method.invoke(obj, values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断类是否含义该属性
|
||||
*
|
||||
* @param klass
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasField(Class<?> klass, String field) {
|
||||
Class<?> btype = klass;
|
||||
while (!Object.class.equals(btype)) {
|
||||
try {
|
||||
btype.getDeclaredField(field);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
btype = btype.getSuperclass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> cls, String name, Class<?>... agrs) {
|
||||
Method method = null;
|
||||
try {
|
||||
if (agrs == null || agrs.length == 0) {
|
||||
method = cls.getDeclaredMethod(name);
|
||||
} else {
|
||||
method = cls.getDeclaredMethod(name, agrs);
|
||||
}
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
throw new TMethodException(e);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
public static Method getHasMethod(Class<?> cls, String name, Class<?>... agrs) {
|
||||
Method method = null;
|
||||
try {
|
||||
if (agrs == null || agrs.length == 0) {
|
||||
method = cls.getDeclaredMethod(name);
|
||||
} else {
|
||||
method = cls.getDeclaredMethod(name, agrs);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
return method;
|
||||
}
|
||||
|
||||
public static <T>T copyBean(Object source,T target){
|
||||
if(source!=null) {
|
||||
Field[] ffields = getFields(target.getClass());
|
||||
Map<String,Field> tarNames = CollectionUtils.newHashMap();
|
||||
for (int i = 0; i < ffields.length; i++) {
|
||||
tarNames.put(ffields[i].getName(),ffields[i]);
|
||||
}
|
||||
Field[] fields = getFields(source.getClass());
|
||||
for (Field field : fields) {
|
||||
if(tarNames.containsKey(field.getName())) {
|
||||
setFieldValue(tarNames.get(field.getName()),getFieldValue(field,source),target);
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,342 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.sql.Date;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ClassUtils {
|
||||
|
||||
private static Set<Class<?>> primitives=CollectionUtils.newHashSet();
|
||||
private static Set<Class<?>> numbers=CollectionUtils.newHashSet();
|
||||
private static Set<Class<?>> integers=CollectionUtils.newHashSet();
|
||||
private static Set<Class<?>> doubles=CollectionUtils.newHashSet();
|
||||
private static Set<Class<?>> dates=CollectionUtils.newHashSet();
|
||||
private static Set<Class<?>> strings=CollectionUtils.newHashSet();
|
||||
|
||||
static {
|
||||
primitives.add(BigDecimal.class);primitives.add(BigInteger.class);
|
||||
primitives.add(Integer.class);primitives.add(int.class);
|
||||
primitives.add(Double.class);primitives.add(double.class);
|
||||
primitives.add(Float.class);primitives.add(float.class);
|
||||
primitives.add(Long.class);primitives.add(long.class);
|
||||
primitives.add(Short.class);primitives.add(short.class);
|
||||
primitives.add(Byte.class);primitives.add(byte.class);
|
||||
primitives.add(Boolean.class);primitives.add(boolean.class);
|
||||
primitives.add(Character.class);primitives.add(char.class);
|
||||
primitives.add(String.class);primitives.add(Date.class);
|
||||
primitives.add(Timestamp.class);primitives.add(java.util.Date.class);
|
||||
primitives.add(Time.class);
|
||||
|
||||
integers.add(Integer.class);integers.add(int.class);
|
||||
integers.add(Long.class);integers.add(long.class);
|
||||
integers.add(Short.class);integers.add(short.class);
|
||||
integers.add(Byte.class);integers.add(byte.class);
|
||||
integers.add(BigInteger.class);
|
||||
|
||||
doubles.add(Double.class);doubles.add(double.class);
|
||||
doubles.add(Float.class);doubles.add(float.class);
|
||||
doubles.add(BigDecimal.class);
|
||||
|
||||
numbers.add(Integer.class);numbers.add(int.class);
|
||||
numbers.add(Double.class);numbers.add(double.class);
|
||||
numbers.add(Float.class);numbers.add(float.class);
|
||||
numbers.add(Long.class);numbers.add(long.class);
|
||||
numbers.add(Short.class);numbers.add(short.class);
|
||||
numbers.add(Byte.class);numbers.add(byte.class);
|
||||
numbers.add(BigDecimal.class);numbers.add(BigInteger.class);
|
||||
|
||||
dates.add(Date.class); dates.add(Time.class);
|
||||
dates.add(Timestamp.class);dates.add(java.util.Date.class);
|
||||
|
||||
strings.add(Character.class);strings.add(char.class);
|
||||
strings.add(String.class);strings.add(StringBuilder.class);
|
||||
strings.add(StringBuffer.class);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为基本数据类型
|
||||
* */
|
||||
public static boolean isPrimitive(Class<?> klass) {
|
||||
return primitives.contains(klass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为字符串类型
|
||||
* */
|
||||
public static boolean isString(Class<?> cls) {
|
||||
return strings.contains(cls) || hashClass(cls, CharSequence.class);
|
||||
}
|
||||
|
||||
public static boolean isNumber(Class<?> type) {
|
||||
return numbers.contains(type);
|
||||
}
|
||||
|
||||
public static boolean isInt(Class<?> type) {
|
||||
return integers.contains(type);
|
||||
}
|
||||
|
||||
public static boolean isDouble(Class<?> type) {
|
||||
return doubles.contains(type);
|
||||
}
|
||||
|
||||
public static boolean isDate(Class<?> type) {
|
||||
return dates.contains(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是map集合
|
||||
* */
|
||||
public static boolean isMap(Class<?> klass) {
|
||||
return hashClass(klass, Map.class);
|
||||
}
|
||||
/**
|
||||
* 是否是set集合
|
||||
* */
|
||||
public static boolean isSet(Class<?> klass) {
|
||||
return hashClass(klass, Set.class);
|
||||
}
|
||||
/**
|
||||
* 是否是list集合
|
||||
* */
|
||||
public static boolean isList(Class<?> klass) {
|
||||
return hashClass(klass, List.class);
|
||||
}
|
||||
|
||||
public static boolean isCollection(Class<?> klass) {
|
||||
return isList(klass) || isSet(klass);
|
||||
}
|
||||
|
||||
/**
|
||||
* klass是否实现了face类或接口
|
||||
* @author tanuki
|
||||
* @param klass 要判断的类型
|
||||
* @param face 指定的类型
|
||||
* */
|
||||
public static boolean hashClass(Class<?> klass, Class<?> face) {
|
||||
if (klass.equals(face)) {
|
||||
return true;
|
||||
} else {
|
||||
if (Object.class.equals(klass)) {
|
||||
return false;
|
||||
}
|
||||
Class<?>[] cls = klass.getInterfaces();
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
if (hashClass(cls[i], face)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!klass.isInterface()) {
|
||||
if (hashClass(klass.getSuperclass(), face)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type 类型转 class
|
||||
* */
|
||||
public static Class<?> getClass(Type type) throws ClassNotFoundException{
|
||||
String cStr=type.toString();
|
||||
if(cStr.indexOf("class ")==0){
|
||||
return Class.forName(cStr.substring(6, cStr.length()));
|
||||
}else if(cStr.indexOf("interface ")==0){
|
||||
return Class.forName(cStr.substring(10, cStr.length()));
|
||||
}else{
|
||||
if(cStr.indexOf("<")!=-1){
|
||||
return Class.forName(cStr.substring(0, cStr.indexOf("<")));
|
||||
}
|
||||
return Class.forName(cStr.substring(0, cStr.length()));
|
||||
}
|
||||
}
|
||||
|
||||
public static Type[] getFeildFan(Field field) {
|
||||
Type type = field.getGenericType();
|
||||
if(type instanceof ParameterizedType){
|
||||
return ((ParameterizedType)type).getActualTypeArguments();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Type getFeildFan(Field field,int index) {
|
||||
Type type = field.getGenericType();
|
||||
if(type instanceof ParameterizedType){
|
||||
return ((ParameterizedType)type).getActualTypeArguments()[index];
|
||||
}
|
||||
return field.getType();
|
||||
}
|
||||
|
||||
public static Class<?> getFeildFanClass(Field field,int index) throws ClassNotFoundException {
|
||||
return getClass(getFeildFan(field, index));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结合的泛型
|
||||
* */
|
||||
public static Type getCollectionFan(Type type){
|
||||
Type result=null;
|
||||
if(type instanceof ParameterizedType){
|
||||
result=((ParameterizedType)type).getActualTypeArguments()[0];
|
||||
}else{
|
||||
result=type;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取结合的泛型
|
||||
* @throws ClassNotFoundException
|
||||
* */
|
||||
public static Class<?> getCollectionFanClass(Type type) throws ClassNotFoundException{
|
||||
Class<?> result=null;
|
||||
if(type instanceof ParameterizedType){
|
||||
result= getClass(((ParameterizedType)type).getActualTypeArguments()[0]);
|
||||
}else{
|
||||
result = getClass(type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结合的泛型
|
||||
* @throws ClassNotFoundException
|
||||
* */
|
||||
public static Class<?> getArrayClass(Class<?> type) throws ClassNotFoundException{
|
||||
return type.getComponentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 反射对象获取泛型
|
||||
* </p>
|
||||
*
|
||||
* @param clazz 对象
|
||||
* @param index 泛型所在位置
|
||||
* @return Class
|
||||
*/
|
||||
public static Class<?> getSuperClassGenericType(final Class<?> clazz, final int index) {
|
||||
Type genType = clazz.getGenericSuperclass();
|
||||
if (!(genType instanceof ParameterizedType)) {
|
||||
log.warn("Warn: {}'s superclass not ParameterizedType", clazz.getSimpleName());
|
||||
return Object.class;
|
||||
}
|
||||
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
|
||||
if (index >= params.length || index < 0) {
|
||||
log.warn("Warn: Index: {}, Size of {}'s Parameterized Type: {} .", index,clazz.getSimpleName(), params.length);
|
||||
return Object.class;
|
||||
}
|
||||
if (!(params[index] instanceof Class)) {
|
||||
log.warn("Warn: {} not set the actual class on superclass generic parameter",clazz.getSimpleName());
|
||||
return Object.class;
|
||||
}
|
||||
return (Class<?>) params[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map的泛型
|
||||
* */
|
||||
public static Type[] getMapFan(Type type){
|
||||
Type[] result=null;
|
||||
if(type instanceof ParameterizedType){
|
||||
result=((ParameterizedType)type).getActualTypeArguments();
|
||||
}else{
|
||||
result=new Type[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取远程jar包加载到当前jvm中
|
||||
* */
|
||||
public static void loadJar(Set<String> urls) {
|
||||
Method method = null;
|
||||
boolean accessible = false;
|
||||
try {
|
||||
method= URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
accessible = method.isAccessible();
|
||||
if (accessible == false) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
for (String address : urls) {
|
||||
method.invoke(classLoader,new URL(address));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
if(method!=null) {
|
||||
method.setAccessible(accessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ClassLoader getDefaultClassLoader() {
|
||||
ClassLoader cl = null;
|
||||
try {
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
catch (Throwable ex) {}
|
||||
if (cl == null) {
|
||||
cl = ClassUtils.class.getClassLoader();
|
||||
if (cl == null) {
|
||||
try {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
catch (Throwable ex) {}
|
||||
}
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>T newInstance(String className) {
|
||||
try {
|
||||
return (T) ClassUtils.loadClass(className).newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class<?> loadClass(String className) {
|
||||
ClassLoader loader = getDefaultClassLoader();
|
||||
if(loader==null) throw new RuntimeException("ClassLoader为空");
|
||||
try {
|
||||
return loader.loadClass(className);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> loadClass(ClassLoader loader,String className) {
|
||||
try {
|
||||
if(loader==null) {
|
||||
return loadClass(className);
|
||||
}
|
||||
return loader.loadClass(className);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class CollectionUtils{
|
||||
|
||||
public static <T>List<T> newVector(){
|
||||
return new Vector<T>();
|
||||
}
|
||||
|
||||
public static <T>List<T> newConcurrentArrayList(){
|
||||
return new CopyOnWriteArrayList<T>();
|
||||
}
|
||||
|
||||
public static <T>List<T> newArrayList(){
|
||||
return new ArrayList<T>();
|
||||
}
|
||||
|
||||
public static <T>List<T> newArrayList(int size){
|
||||
return new ArrayList<T>(size);
|
||||
}
|
||||
|
||||
public static <T>List<T> newLinkedList(){
|
||||
return new LinkedList<T>();
|
||||
}
|
||||
|
||||
|
||||
public static <V, K>Map<K,V> newHashMap(){
|
||||
return new HashMap<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newHashtable(){
|
||||
return new Hashtable<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newIdentityHashMap(){
|
||||
return new IdentityHashMap<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newLinkedHashMap(){
|
||||
return new LinkedHashMap<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newTreeMap(){
|
||||
return new TreeMap<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newWeakHashMap(){
|
||||
return new WeakHashMap<K,V>();
|
||||
}
|
||||
|
||||
public static <V, K> Map<K,V> newConcurrentHashMap(){
|
||||
return new ConcurrentHashMap<K,V>();
|
||||
}
|
||||
|
||||
public static Properties newProperties(){
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
|
||||
public static <T> Set<T> newHashSet(){
|
||||
return new HashSet<T>();
|
||||
}
|
||||
|
||||
public static <T> Set<T> newLinkedHashSet(){
|
||||
return new LinkedHashSet<T>();
|
||||
}
|
||||
|
||||
public static <T> Set<T> newTreeSet(){
|
||||
return new TreeSet<T>();
|
||||
}
|
||||
|
||||
public static <T> Set<T> newConcurrentSet(){
|
||||
return new ConcurrentSkipListSet<T>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T[] toArray(Collection<T> collection) {
|
||||
if(collection!=null) {
|
||||
return (T[]) collection.toArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Collection<?> collection) {
|
||||
return collection==null || collection.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Collection<?> collection) {
|
||||
return collection!=null && !collection.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,873 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.Charset;
|
||||
import java.sql.Date;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import com.esotericsoftware.kryo.kryo5.minlog.Log;
|
||||
import com.google.api.client.util.Sets;
|
||||
import com.pictc.annotations.datalog.JoinCaseType;
|
||||
import com.pictc.annotations.datalog.JoinValueType;
|
||||
import com.pictc.annotations.datalog.LogJoin;
|
||||
import com.pictc.annotations.datalog.LogJoinColumn;
|
||||
import com.pictc.annotations.datalog.ValueDirectionType;
|
||||
import com.pictc.converts.ConverUtil;
|
||||
import com.pictc.datalog.LogFieldInfo;
|
||||
import com.pictc.datalog.LogJoinInfo;
|
||||
import com.pictc.datalog.LogTableInfo;
|
||||
import com.pictc.exceptions.OrmException;
|
||||
import com.pictc.jdbc.JdbcContext;
|
||||
import com.pictc.jdbc.ResultSetUtils;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.xjrsoft.common.utils.SecureUtil;
|
||||
import com.xjrsoft.module.datalog.entity.DataChangeLog;
|
||||
import com.xjrsoft.module.datalog.entity.json.FieldChange;
|
||||
import com.xjrsoft.module.datalog.service.DatalogService;
|
||||
import com.xjrsoft.module.datalog.vo.OperationType;
|
||||
import com.xjrsoft.module.organization.dto.UserDto;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@SuppressWarnings({"unused","rawtypes","unchecked"})
|
||||
@Component
|
||||
public class DataLogTools {
|
||||
|
||||
private static Map<Class<?>,LogTableInfo> annotations = Maps.newHashMap();
|
||||
|
||||
private static Set<String> logTables = null;
|
||||
|
||||
private static Object lock = new Object();
|
||||
|
||||
public static final String SQL_HAS_TABLE = "select count(*) from log_table_info where tbl_name = ?";
|
||||
|
||||
public static final String SQL_INST_TABLE = "INSERT INTO log_table_info (tbl_name) VALUES (?);";
|
||||
|
||||
public static final String SQL_LOG_TABLE_LIST = "select tbl_name FROM log_table_info";
|
||||
|
||||
public static final String SQL_PLACEHOLDER = "\\$\\{TBL_NAME\\}";
|
||||
|
||||
public static final String[] SQL_CREATE_TABLE = {
|
||||
"CREATE TABLE ${TBL_NAME} (\r\n" +
|
||||
" id VARCHAR(32) NOT NULL,\r\n" +
|
||||
" flow_id VARCHAR(32),\r\n" +
|
||||
" pid VARCHAR(32) DEFAULT '#',\r\n" +
|
||||
" entity_class_name VARCHAR(255),\r\n" +
|
||||
" bus_name VARCHAR(100),\r\n" +
|
||||
" entity_id BIGINT,\r\n" +
|
||||
" field_changes TEXT,\r\n" +
|
||||
" operation_type VARCHAR(20),\r\n" +
|
||||
" operator_id BIGINT,\r\n" +
|
||||
" operator_name VARCHAR(100),\r\n" +
|
||||
" operation_time TIMESTAMPTZ,\r\n" +
|
||||
" operation_ip VARCHAR(50),\r\n" +
|
||||
" PRIMARY KEY (id)\r\n" +
|
||||
" );",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"flow_id\" IS '流水id';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"pid\" IS '父表ID,根节点#';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"entity_class_name\" IS '实体类名称(全类名)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"bus_name\" IS '业务名称';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"entity_id\" IS '操作的实体ID(主键值)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"field_changes\" IS '属性值记录(JSON格式存储字段变更详情)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_type\" IS '操作类型:INSERT-新增,UPDATE-修改,DELETE-删除';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operator_id\" IS '操作人ID';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operator_name\" IS '操作人姓名';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_time\" IS '操作时间';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_ip\" IS '操作IP地址';",
|
||||
"CREATE INDEX idx_${TBL_NAME}_enityt_id ON ${TBL_NAME} (entity_id)"
|
||||
};
|
||||
|
||||
public static final String SQL_INSERT = "INSERT INTO ${TBL_NAME} (\r\n" +
|
||||
" id, flow_id, pid, entity_class_name, bus_name, \r\n" +
|
||||
" entity_id, field_changes, operation_type, operator_id, \r\n" +
|
||||
" operator_name, operation_time, operation_ip\r\n" +
|
||||
") VALUES (?,?,?,?,?,?,?,?,?,?,?,?);";
|
||||
|
||||
|
||||
public static final String SQL_LIST = "SELECT * FROM ${TBL_NAME} WHERE entity_id = ? ORDER BY operation_time DESC, flow_id DESC";
|
||||
|
||||
public static final Set<String> excludeFields = SetUtils.of("tenantId");
|
||||
|
||||
|
||||
public static DataChangeLog createLog(Class<?> klazz,OperationType type) {
|
||||
DataChangeLog createLog = createLog(klazz, type, null);
|
||||
return createLog.setFlowId(IdUtil.getSnowflakeNextIdStr());
|
||||
}
|
||||
|
||||
public static DataChangeLog createLog(Class<?> klazz,OperationType type,DataChangeLog parent) {
|
||||
UserDto currentUser = SecureUtil.getCurrentUser();
|
||||
LogTableInfo annotation = getAnnotation(klazz);
|
||||
//变更人的IP地址
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String ipAddress = request.getRemoteAddr();
|
||||
DataChangeLog changeLog = new DataChangeLog()
|
||||
.setEntityClassName(klazz.getCanonicalName())
|
||||
.setBusName(annotation.getName())
|
||||
.setId(IdUtil.getSnowflakeNextIdStr())
|
||||
.setOperationIp(ipAddress)
|
||||
.setOperationType(type)
|
||||
.setOperatorId(currentUser.getId())
|
||||
.setOperatorName(currentUser.getName())
|
||||
.setOperationTime(LocalDateTime.now());
|
||||
if(parent!=null) {
|
||||
changeLog.setFlowId(parent.getFlowId());
|
||||
changeLog.setPid(parent.getId());
|
||||
}
|
||||
return changeLog;
|
||||
}
|
||||
|
||||
public static LogTableInfo getAnnotation(Class<?> klazz) {
|
||||
synchronized (lock) {
|
||||
if(annotations.containsKey(klazz)) {
|
||||
return annotations.get(klazz);
|
||||
}
|
||||
LogTableInfo tableInfo = new LogTableInfo(klazz);
|
||||
if(tableInfo.isValid()) {
|
||||
annotations.put(klazz,tableInfo);
|
||||
return tableInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T>T insert(T entity) {
|
||||
Class<? extends Object> klazz = entity.getClass();
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.INSERT);
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
initJoinValue(entity,tabInfo,null);
|
||||
Long idValue = tabInfo.getIdValue(entity);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
mapper.insert(BeanUtil.toBean(entity,tabInfo.getEntityType()));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.INSERT,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public static <T>T update(T dto) {
|
||||
Class<? extends Object> klazz = dto.getClass();
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
|
||||
Long idValue = tabInfo.getIdValue(dto);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object old = findById(klazz, idValue);
|
||||
if(old!=null) {
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.UPDATE);
|
||||
initJoinValue(dto,tabInfo,null);
|
||||
|
||||
mapper.updateById(tabInfo.toEntity(dto));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,dto,old);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.UPDATE,tabInfo,join,dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
}else {
|
||||
throw new OrmException("数据不存在");
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
||||
public static <T>T delete(T entity) {
|
||||
Class<? extends Object> klazz = entity.getClass();
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
Long idValue = tabInfo.getIdValue(entity);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
delete(entity, tabInfo, mapper);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public static <T>T deleteById(Class<T> klazz,Long id) {
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
T entity = findById(klazz, id);
|
||||
if(entity==null) return null;
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
|
||||
delete(entity, tabInfo, mapper);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static boolean deleteByIds(Class<?> klazz, @Valid List<Long> ids) {
|
||||
for (Long id : ids) {
|
||||
deleteById(klazz, id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T>T findById(Class<T> klazz,Serializable id){
|
||||
return findById(klazz,id,false);
|
||||
}
|
||||
|
||||
public static <T>T findById(Class<T> klazz,Serializable id,boolean full){
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object old = mapper.selectById(id);
|
||||
if(old==null) return null;
|
||||
T dto = (T) tabInfo.toDto(old);
|
||||
initJoinValues(tabInfo,dto,SetUtils.of(klazz), full);
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static void initJoinValues(LogTableInfo tabInfo,Object entity,Set<Class<?>> classPath,boolean full){
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
LogTableInfo joinTable = join.getTableInfo();
|
||||
if(full) {
|
||||
if(join.isList()) {
|
||||
List joinList = getJoinList(joinTable,join, mapper,tabInfo,entity);
|
||||
if(CollectionUtils.isNotEmpty(joinList)) {
|
||||
List listVal = new ArrayList();
|
||||
for (Object item : joinList) {
|
||||
Object voOjb = BeanUtil.toBean(item,joinTable.getKlazz());
|
||||
if(!classPath.contains(joinTable.getKlazz())) {
|
||||
Set<Class<?>> classes = SetUtils.ofCollection(classPath);
|
||||
classes.add(joinTable.getKlazz());
|
||||
initJoinValues(joinTable,voOjb,classes,full);
|
||||
}
|
||||
listVal.add(voOjb);
|
||||
}
|
||||
tabInfo.setFieldValue(entity,join.getField(),listVal);
|
||||
}
|
||||
}else {
|
||||
Object objVal = getJoinObj(joinTable,join, mapper,tabInfo,entity);
|
||||
Object voOjb = BeanUtil.toBean(objVal,joinTable.getKlazz());
|
||||
if(!classPath.contains(joinTable.getKlazz())) {
|
||||
Set<Class<?>> classes = SetUtils.ofCollection(classPath);
|
||||
classes.add(joinTable.getKlazz());
|
||||
initJoinValues(joinTable,voOjb,classes,full);
|
||||
}
|
||||
tabInfo.setFieldValue(entity,join.getField(),voOjb);
|
||||
}
|
||||
}else {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
if(join.isList()) {
|
||||
List joinList = getJoinList(joinTable,join, mapper,tabInfo,entity);
|
||||
if(CollectionUtils.isNotEmpty(joinList)) {
|
||||
List listVal = new ArrayList();
|
||||
for (Object item : joinList) {
|
||||
Object voOjb = BeanUtil.toBean(item,joinTable.getKlazz());
|
||||
if(!classPath.contains(joinTable.getKlazz())) {
|
||||
Set<Class<?>> classes = SetUtils.ofCollection(classPath);
|
||||
classes.add(joinTable.getKlazz());
|
||||
initJoinValues(joinTable,voOjb,classes,full);
|
||||
}
|
||||
listVal.add(voOjb);
|
||||
}
|
||||
tabInfo.setFieldValue(entity,join.getField(),listVal);
|
||||
}
|
||||
}else {
|
||||
Object objVal = getJoinObj(joinTable,join, mapper,tabInfo,entity);
|
||||
Object voOjb = BeanUtil.toBean(objVal,joinTable.getKlazz());
|
||||
if(!classPath.contains(joinTable.getKlazz())) {
|
||||
Set<Class<?>> classes = SetUtils.ofCollection(classPath);
|
||||
classes.add(joinTable.getKlazz());
|
||||
initJoinValues(joinTable,voOjb,classes,full);
|
||||
}
|
||||
tabInfo.setFieldValue(entity,join.getField(),voOjb);
|
||||
}
|
||||
}
|
||||
}
|
||||
classPath.add(joinTable.getKlazz());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void delete(Object entity,LogTableInfo tableinfo,BaseMapper mapper){
|
||||
Long idValue = tableinfo.getIdValue(entity);
|
||||
if(idValue!=null && idValue > 0) {
|
||||
// QueryChainWrapper wrapper = new QueryChainWrapper(mapper);
|
||||
// wrapper.eq(tableinfo.getIdColumn(),tableinfo.getIdValue(entity));
|
||||
// mapper.delete(wrapper);
|
||||
mapper.deleteById(idValue);
|
||||
}else {
|
||||
throw new RuntimeException("删除数据时,表【"+tableinfo.getName()+"】的主键为空,删除失败!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static <T>void initJoinValue(T entity,LogTableInfo tabInfo,Set<Class<?>> classes) {
|
||||
if(classes==null) {
|
||||
classes = CollectionUtils.newHashSet();
|
||||
}
|
||||
if(classes.contains(tabInfo.getEntityType())) return ;
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
Long idValue = tabInfo.getIdValue(entity);
|
||||
if(idValue == null || idValue <=0) {
|
||||
idValue = IdWorker.getId();
|
||||
tabInfo.setIdValue(entity,idValue);
|
||||
}
|
||||
classes.add(tabInfo.getEntityType());
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
LogJoinColumn[] columns = join.getJoin().columns();
|
||||
LogTableInfo joinTable = join.getTableInfo();
|
||||
if(classes.contains(joinTable.getEntityType())) {
|
||||
continue;
|
||||
}
|
||||
Object joinValue = tabInfo.getFieldValue(entity, join.getField());
|
||||
if(joinValue!=null && joinValue instanceof List) {
|
||||
List listValue = (List) joinValue;
|
||||
for (LogJoinColumn joinColumn : columns) {
|
||||
if (joinColumn.valueType() == JoinValueType.FEILD
|
||||
&& joinColumn.valueDirection() == ValueDirectionType.RIGHT) {
|
||||
Object joinFieldValue = tabInfo.getFieldValue(entity, joinColumn.field());
|
||||
for (Object item : listValue) {
|
||||
Long idValue2 = joinTable.getIdValue(item);
|
||||
if(idValue2==null || idValue2 <=0) {
|
||||
joinTable.setIdValue(joinValue, IdWorker.getId());
|
||||
}
|
||||
joinTable.setFieldValue(item, joinColumn.relatedField(), joinFieldValue);
|
||||
Set<Class<?>> joinClasses = SetUtils.ofCollection(classes);
|
||||
initJoinValue(item,joinTable,joinClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
Long idValue2 = joinTable.getIdValue(joinValue);
|
||||
if(idValue2==null || idValue2 <=0) {
|
||||
joinTable.setIdValue(joinValue,idValue2);
|
||||
}
|
||||
for (LogJoinColumn joinColumn : columns) {
|
||||
if(joinColumn.valueType()==JoinValueType.FEILD && joinColumn.valueDirection()==ValueDirectionType.LEFT) {
|
||||
Object joinFieldValue = joinTable.getFieldValue(joinValue, joinColumn.relatedField());
|
||||
tabInfo.setFieldValue(entity, joinColumn.field(),joinFieldValue);
|
||||
}else {
|
||||
Object joinFieldValue = tabInfo.getFieldValue(entity, joinColumn.field());
|
||||
joinTable.setFieldValue(joinValue, joinColumn.relatedField(), joinFieldValue);
|
||||
}
|
||||
}
|
||||
Set<Class<?>> joinClasses = SetUtils.ofCollection(classes);
|
||||
initJoinValue(joinValue,joinTable,joinClasses);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T>void buildJoins(List<DataChangeLog> logs,DataChangeLog parent,OperationType type,LogTableInfo parentInfo, LogJoinInfo join, T entity) {
|
||||
LogTableInfo joinTable = join.getTableInfo();
|
||||
BaseMapper mapper = MybatisTools.getMapper(joinTable.getEntityType());
|
||||
if(joinTable!=null) {
|
||||
if(join.isList()) {
|
||||
List listValue = BeanUtils.getFieldValue(join.getField(),entity);
|
||||
if(CollectionUtils.isNotEmpty(listValue)) {
|
||||
if(type==OperationType.INSERT || type==OperationType.DELETE) {
|
||||
if(type==OperationType.INSERT) {
|
||||
for (Object item : listValue) {
|
||||
Long idValue = joinTable.getIdValue(item);
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),type,parent);
|
||||
datalog.setEntityId(idValue);
|
||||
Object bean = BeanUtil.toBean(item,joinTable.getEntityType());
|
||||
mapper.insert(bean);
|
||||
buildFields(datalog,joinTable,item,null);
|
||||
logs.add(datalog);
|
||||
}
|
||||
}else {
|
||||
for (Object item : listValue) {
|
||||
Long idValue = joinTable.getIdValue(item);
|
||||
Object voOjb = BeanUtil.toBean(item,joinTable.getKlazz());
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),type,parent);
|
||||
datalog.setEntityId(idValue);
|
||||
delete(voOjb, joinTable, mapper);
|
||||
buildFields(datalog,joinTable,voOjb,null);
|
||||
logs.add(datalog);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
for (Object item : listValue) {
|
||||
Long idValue = joinTable.getIdValue(item);
|
||||
Object nval = BeanUtil.toBean(item,joinTable.getKlazz());
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),type,parent);
|
||||
datalog.setEntityId(idValue);
|
||||
Object old = findById(join.getTargetClass(), idValue);
|
||||
mapper.updateById(nval);
|
||||
buildFields(datalog,joinTable,nval,old);
|
||||
logs.add(datalog);
|
||||
}
|
||||
}
|
||||
} else if(type==OperationType.UPDATE || type==OperationType.DELETE){
|
||||
//进行修改或者删除时,级联对象为空时,需要删除旧数据
|
||||
List oldList = getJoinList(joinTable, join, mapper, parentInfo, entity);
|
||||
if(oldList!=null) {
|
||||
for (Object item : oldList) {
|
||||
Object voOjb = BeanUtil.toBean(item,joinTable.getKlazz());
|
||||
Long idValue = joinTable.getIdValue(item);
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),OperationType.DELETE,parent);
|
||||
datalog.setEntityId(idValue);
|
||||
delete(voOjb, joinTable, mapper);
|
||||
buildFields(datalog,joinTable,voOjb,null);
|
||||
logs.add(datalog);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Object val = BeanUtils.getFieldValue(join.getField(),entity);
|
||||
if(val!=null) {
|
||||
Long idValue = joinTable.getIdValue(val);
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),type,parent);
|
||||
logs.add(datalog);
|
||||
datalog.setEntityId(idValue);
|
||||
if(type==OperationType.INSERT || type==OperationType.DELETE) {
|
||||
if(type==OperationType.INSERT) {
|
||||
mapper.insert(val);
|
||||
}else {
|
||||
delete(val, joinTable, mapper);
|
||||
}
|
||||
buildFields(datalog,joinTable, val, null);
|
||||
}else {
|
||||
Object old = mapper.selectById(idValue);
|
||||
buildFields(datalog,joinTable,val,old);
|
||||
Object bean = BeanUtil.toBean(val,joinTable.getEntityType());
|
||||
mapper.updateById(bean);
|
||||
}
|
||||
} else if(type==OperationType.UPDATE || type==OperationType.DELETE){
|
||||
//进行修改或者删除时,级联对象为空时,需要删除旧数据
|
||||
Object old = getJoinObj(joinTable, join, mapper, parentInfo, entity);
|
||||
if(old!=null) {
|
||||
Object voOjb = BeanUtil.toBean(old,joinTable.getKlazz());
|
||||
Long idValue = joinTable.getIdValue(old);
|
||||
DataChangeLog datalog = createLog(join.getTargetClass(),OperationType.DELETE,parent);
|
||||
datalog.setEntityId(idValue);
|
||||
delete(voOjb, joinTable, mapper);
|
||||
buildFields(datalog,joinTable,voOjb,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List getJoinList(LogTableInfo joinTable, LogJoinInfo join, BaseMapper mapper,
|
||||
LogTableInfo parentInfo,Object parent) {
|
||||
LogJoin joinAnnotation = join.getJoin();
|
||||
LogJoinColumn[] columns = joinAnnotation.columns();
|
||||
QueryChainWrapper queryWrapper = new QueryChainWrapper(mapper);
|
||||
for (LogJoinColumn joinCol : columns) {
|
||||
if(joinCol.valueType()==JoinValueType.FEILD) {
|
||||
Object value = parentInfo.getFieldValue(parent,joinCol.field());
|
||||
if(value==null) return null;
|
||||
queryWrapper.eq(joinTable.getColumn(joinCol.relatedField()),value);
|
||||
}else {
|
||||
if(StringUtils.isNotEmpty(joinCol.relatedField())) {
|
||||
queryWrapper.eq(joinTable.getColumn(joinCol.relatedField()),ConverUtil.jsonToValue(joinCol.staticType(),joinCol.staticValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
private static Object getJoinObj(LogTableInfo joinTable,LogJoinInfo join,BaseMapper mapper,LogTableInfo parentInfo,Object parent) {
|
||||
LogJoin joinAnnotation = join.getJoin();
|
||||
LogJoinColumn[] columns = joinAnnotation.columns();
|
||||
QueryChainWrapper query = new QueryChainWrapper(mapper);
|
||||
for (LogJoinColumn joinCol : columns) {
|
||||
if(joinCol.valueType()==JoinValueType.FEILD) {
|
||||
Object value = parentInfo.getFieldValue(parent,joinCol.field());
|
||||
if(value==null) return null;
|
||||
query.eq(joinTable.getColumn(joinCol.relatedField()),value);
|
||||
}else {
|
||||
if(StringUtils.isNotEmpty(joinCol.relatedField())) {
|
||||
query.eq(joinTable.getColumn(joinCol.relatedField()),ConverUtil.jsonToValue(joinCol.staticType(),joinCol.staticValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapper.selectObjs(query);
|
||||
}
|
||||
|
||||
|
||||
private static <T>void buildFields(DataChangeLog datalog,LogTableInfo tableInfo,T entity,T old) {
|
||||
List<LogFieldInfo> fields = tableInfo.getFields();
|
||||
for (LogFieldInfo item : fields) {
|
||||
if(excludeFields.contains(item.getFieldName())) {
|
||||
continue;
|
||||
}
|
||||
FieldChange change = new FieldChange();
|
||||
change.setField(item.getFieldName());
|
||||
change.setName(item.getName());
|
||||
if(old!=null) {
|
||||
Object newVal = BeanUtils.getFieldValue(item.getField(),entity);
|
||||
Object oldVal = BeanUtils.getFieldValue(item.getField(),old);
|
||||
boolean flag = false;
|
||||
if((newVal==null && oldVal!=null) || (newVal!=null && oldVal==null)) {
|
||||
flag = true;
|
||||
}else if(newVal!=null && oldVal!=null && !newVal.equals(oldVal)) {
|
||||
flag = true;
|
||||
}
|
||||
change.setOldValue(parseValue(oldVal,item.getJavaType()));
|
||||
change.setNewValue(parseValue(newVal,item.getJavaType()));
|
||||
if(flag) {
|
||||
datalog.addFiledChnage(change);
|
||||
}
|
||||
}else {
|
||||
change.setNewValue(parseValue(BeanUtils.getFieldValue(item.getField(),entity),item.getField().getType()));
|
||||
datalog.addFiledChnage(change);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String parseValue(Object val,Class<?> type) {
|
||||
if(val==null) return null;
|
||||
if (type.equals(String.class)) {
|
||||
return String.class.cast(val);
|
||||
|
||||
} else if (type.equals(BigDecimal.class)) {
|
||||
return BigDecimal.class.cast(val).toString();
|
||||
|
||||
} else if (type.equals(BigInteger.class)) {
|
||||
return BigInteger.class.cast(val).toString();
|
||||
|
||||
} else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE)
|
||||
|| type.equals(Integer.class) || type.equals(Integer.TYPE)
|
||||
|| type.equals(Long.class) || type.equals(Long.TYPE)
|
||||
|| type.equals(Float.class) || type.equals(Float.TYPE)
|
||||
|| type.equals(Double.class) || type.equals(Double.TYPE)
|
||||
) {
|
||||
return val.toString();
|
||||
|
||||
} else if (type.equals(byte[].class)) {
|
||||
byte[] buf = (byte[])val;
|
||||
return new String(buf, Charset.forName("UTF-8"));
|
||||
|
||||
} else if (type.equals(Date.class) || type.equals(Time.class) || type.equals(Timestamp.class) || type.equals(java.util.Date.class)) {
|
||||
String fmt = null;
|
||||
if(type.equals(Date.class)) {
|
||||
fmt = DateUtils.GENERAL;
|
||||
}else if(type.equals(Time.class)) {
|
||||
fmt = DateUtils.FMT_TIME;
|
||||
}else {
|
||||
fmt = DateUtils.LONG_FORMAT;
|
||||
}
|
||||
return DateUtils.format(java.util.Date.class.cast(val),fmt);
|
||||
}else if (type.equals(LocalDate.class)) {
|
||||
return DateUtils.format(LocalDate.class.cast(val));
|
||||
|
||||
} else if (type.equals(LocalDateTime.class)) {
|
||||
return DateUtils.format(LocalDateTime.class.cast(val));
|
||||
|
||||
} else if (type.equals(LocalTime.class)) {
|
||||
return DateUtils.format(LocalDateTime.class.cast(val));
|
||||
} else if (type.equals(OffsetDateTime.class)) {
|
||||
return DateUtils.format(OffsetDateTime.class.cast(val));
|
||||
|
||||
} else if (type.equals(OffsetTime.class)) {
|
||||
return DateUtils.format(OffsetTime.class.cast(val));
|
||||
}else if(type.isEnum()) {
|
||||
return val.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 保存数据日志
|
||||
* @param logs 日志记录对象
|
||||
* @return void 返回类型
|
||||
*/
|
||||
public static void saveLogs(LogTableInfo tableInfo,List<DataChangeLog> logs) {
|
||||
String tableName = parseLogTableName(tableInfo);
|
||||
initTable(tableName);
|
||||
String sql = parseSql(SQL_INSERT, tableName);
|
||||
List<List<JdbcParam>> batchParams = CollectionUtils.newArrayList();
|
||||
for (DataChangeLog log : logs) {
|
||||
List<JdbcParam> params = CollectionUtils.newArrayList();
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, log.getId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, log.getFlowId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, log.getPid()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, log.getEntityClassName()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, log.getBusName()));
|
||||
params.add(JdbcParam.of(Types.BIGINT,long.class, log.getEntityId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,JSON.toJSONString(log.getFieldChanges())));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,log.getOperationType().name()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,long.class,log.getOperatorId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,log.getOperatorName()));
|
||||
params.add(JdbcParam.of(Types.TIMESTAMP,Timestamp.class,log.getOperationTime()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,log.getOperationIp()));
|
||||
batchParams.add(params);
|
||||
}
|
||||
executeBatch(sql, batchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 初始化日志表
|
||||
* @param tableName
|
||||
* @return void 返回类型
|
||||
*/
|
||||
private synchronized static boolean initTable(String tableName) {
|
||||
synchronized (lock) {
|
||||
//如果没有日志表时,重新创建
|
||||
if(!hasTable(tableName)) {
|
||||
for (int i = 0; i < SQL_CREATE_TABLE.length; i++) {
|
||||
execute(parseSql(SQL_CREATE_TABLE[i], tableName));
|
||||
}
|
||||
//将表名进行记录
|
||||
executeUpdate(SQL_INST_TABLE,ListUtils.ofArray(JdbcParam.ofString(tableName)));
|
||||
logTables.add(tableName);
|
||||
log.info("新增数据日志表:{}",tableName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static String parseSql(String sql,String tableName) {
|
||||
return sql.replaceAll(SQL_PLACEHOLDER,tableName);
|
||||
}
|
||||
|
||||
private static boolean hasTable(String tableName) {
|
||||
synchronized (lock) {
|
||||
if(logTables==null) {
|
||||
List<String> tabs = queryListPrimitive(SQL_LOG_TABLE_LIST,String.class, null);
|
||||
logTables = new HashSet<String>(tabs);
|
||||
}
|
||||
if(logTables.contains(tableName)) return true;
|
||||
Long count = queryPrimitive(SQL_HAS_TABLE,long.class,Lists.newArrayList(JdbcParam.ofString(tableName)));
|
||||
boolean flag = count!=null && count > 0;
|
||||
if(flag) {
|
||||
logTables.add(tableName);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 根据数据id获取操作日志
|
||||
* @param klass 数据java类型
|
||||
* @param dataId 数据id
|
||||
* @return List<DataChangeLog> 返回类型
|
||||
*/
|
||||
public static <T>List<DataChangeLog> findLogsByEntityId(Class<T> klass,@NonNull Long dataId) {
|
||||
LogTableInfo tabInfo = getAnnotation(klass);
|
||||
String tableName = parseLogTableName(tabInfo);
|
||||
if(initTable(tableName)) {
|
||||
return null;
|
||||
}
|
||||
List<DataChangeLog> result = CollectionUtils.newArrayList();
|
||||
String sql = parseSql(SQL_LIST, tableName);
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,false);
|
||||
context.init(sql);
|
||||
context.setParams(ListUtils.ofArray(JdbcParam.ofLong(dataId)));
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
while (set.next()) {
|
||||
DataChangeLog log = new DataChangeLog();
|
||||
log.setId(set.getString("id"));
|
||||
log.setFlowId(set.getString("flow_id"));
|
||||
log.setPid(set.getString("pid"));
|
||||
log.setEntityClassName(set.getString("entity_class_name"));
|
||||
log.setBusName(set.getString("bus_name"));
|
||||
log.setEntityId(set.getLong("entity_id"));
|
||||
log.setOperationType(OperationType.valueOf(set.getString("operation_type")));
|
||||
log.setOperationIp(set.getString("operation_ip"));
|
||||
log.setOperatorId(set.getLong("operator_id"));
|
||||
log.setOperatorName(set.getString("operator_name"));
|
||||
log.setOperationTime(ResultSetUtils.getObject(set,"operation_time",LocalDateTime.class));
|
||||
String json = set.getString("field_changes");
|
||||
if(StringUtils.isNotEmpty(json)) {
|
||||
log.setFieldChanges(JSON.parseArray(json).toJavaList(FieldChange.class));
|
||||
}
|
||||
result.add(log);
|
||||
}
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
} finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseLogTableName(LogTableInfo tableInfo) {
|
||||
String name = tableInfo.getTableName();
|
||||
return "datalog_"+name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行ddl语句
|
||||
* */
|
||||
public static boolean execute(String sql){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
return context.execute();
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改操作
|
||||
* */
|
||||
public static int executeUpdate(String sql,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
return context.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
* */
|
||||
public static int executeBatch(String sql,List<List<JdbcParam>> batchParams){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
context.setBatchParams(batchParams);
|
||||
return context.executeBatch(-1);
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询基础数据类型
|
||||
* */
|
||||
public static <T>T queryPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
while (set.next()) {
|
||||
return ResultSetUtils.getObject(set,1,type);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询基础数据类型
|
||||
* */
|
||||
public static <T>List<T> queryListPrimitive(String sql,Class<T> type,List<JdbcParam> params){
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
context.setParams(params);
|
||||
ResultSet set = context.executeQuery();
|
||||
List<T> res = CollectionUtils.newArrayList();
|
||||
while (set.next()) {
|
||||
res.add(ResultSetUtils.getObject(set,1,type));
|
||||
}
|
||||
return res;
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
}finally {
|
||||
context.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,448 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Calendar.DATE;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class DateUtils {
|
||||
|
||||
public static final String GENERAL = "yyyy-MM-dd";
|
||||
|
||||
public static final String FMT_TIME = "HH:mm:ss";
|
||||
|
||||
public static final String FMT_OFFSET_DATETIME = "yyyy-MM-dd HH:mm:ssXXX";
|
||||
|
||||
public static final String FMT_OFFSET_TIME = "HH:mm:ssXXX";
|
||||
|
||||
public static final String GENERAL_YYYYMMDD = "yyyyMMdd";
|
||||
|
||||
public static final String GENERAL_YYYYMMDDHHMMSS = "yyyyMMddHHmmSS";
|
||||
|
||||
public static final String LONG_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public final static DateTimeFormatter FORMATTER_YYYY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern(LONG_FORMAT);
|
||||
|
||||
// 针对GMT格式的日期转换格式
|
||||
public static final String GMT_DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'";
|
||||
|
||||
private static final SimpleDateFormat sdf = new SimpleDateFormat(LONG_FORMAT);
|
||||
|
||||
private static final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(GENERAL);
|
||||
|
||||
public static final ZoneId zone = ZoneId.of("GMT+8");
|
||||
|
||||
private static Set<Class<?>> dates = CollectionUtils.newHashSet();
|
||||
|
||||
static {
|
||||
dates.add(Date.class);
|
||||
dates.add(Time.class);
|
||||
dates.add(Timestamp.class);
|
||||
dates.add(java.util.Date.class);
|
||||
}
|
||||
|
||||
public static boolean isDate(Class<?> type) {
|
||||
return dates.contains(type);
|
||||
}
|
||||
|
||||
public static String formatDate(Date date) {
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static Date formatDate2Date(Date date) {
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String format = sdf.format(date);
|
||||
try {
|
||||
return sdf.parse(format);
|
||||
} catch (ParseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入的格式化规则格式化传入的日期
|
||||
*
|
||||
* @param date : 传入日期对象
|
||||
* @param dateFormat : 格式化规则(如:yyyy-MM-dd,yyyyMMdd等,如果传空或NULL则默认为yyyy-MM-dd)
|
||||
* @return String
|
||||
* @author 张江立
|
||||
*/
|
||||
public static String formatDate(Date date, String dateFormat) {
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null == dateFormat || "".equals(dateFormat)) {
|
||||
dateFormat = "yyyy-MM-dd";
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
String formatDateAfterStr = sdf.format(date);
|
||||
|
||||
return formatDateAfterStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对格林日期转换为字符串
|
||||
*
|
||||
* @param datestr:日期字符串,如:datestr = "Tue Jun 05 2018 13:11:11 GMT"
|
||||
* @return Date
|
||||
*/
|
||||
public static Date GMTDateToString(String datestr) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(GMT_DATE_FORMAT, Locale.ENGLISH);
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse(datestr);
|
||||
} catch (ParseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入日期添加天数
|
||||
*
|
||||
* @param date : 日期对象
|
||||
* @param days : 天数
|
||||
* @return Date
|
||||
*/
|
||||
public static Date addDays(Date date, int days) {
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(DATE, days);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期字符串转成日期对象
|
||||
*
|
||||
* @param dateString; 如:"2012-12-06"
|
||||
* @param dateFormat :格式化规则(如:yyyy-MM-dd)
|
||||
* :DateUtils.GENERAL
|
||||
* :DateUtils.LONG_FORMAT
|
||||
* @return Date
|
||||
*/
|
||||
public static Date stringToDate(String dateString, String dateFormat) {
|
||||
Date date = null;
|
||||
if (null == dateString || "".equals(dateString) || "null".equalsIgnoreCase(dateString) || null == dateFormat || "".equals(dateFormat)) {
|
||||
return date;
|
||||
}
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
date = sdf.parse(dateString);
|
||||
} catch (ParseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return date;
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 日期字符串转成日期对象,默认格式: yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateString
|
||||
* @return
|
||||
*/
|
||||
public static Date stringToDate(String dateString) {
|
||||
Date date = null;
|
||||
if (null == dateString || "".equals(dateString) || "null".equalsIgnoreCase(dateString)) {
|
||||
return date;
|
||||
}
|
||||
try {
|
||||
date = sdf.parse(dateString);
|
||||
} catch (ParseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return date;
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回昨天
|
||||
*
|
||||
* @param today
|
||||
* @return
|
||||
*/
|
||||
public static Date yesterday(Date today) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(today);
|
||||
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回明天
|
||||
*
|
||||
* @param today
|
||||
* @return
|
||||
*/
|
||||
public static Date tomorrow(Date today) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(today);
|
||||
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static final String format(Date date, String pattern) {
|
||||
if(date==null) return null;
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static final String format(LocalDate localDate) {
|
||||
return format(localDate, GENERAL);
|
||||
}
|
||||
|
||||
public static final String format(LocalDate localDate, String pattern) {
|
||||
if(localDate==null) return null;
|
||||
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return localDate.format(dateFormatter);
|
||||
}
|
||||
|
||||
public static final String format(LocalTime localDate) {
|
||||
return format(localDate,FMT_TIME);
|
||||
}
|
||||
|
||||
public static final String format(LocalTime localDate,String pattern) {
|
||||
if(localDate==null) return null;
|
||||
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return localDate.format(dateFormatter);
|
||||
}
|
||||
|
||||
public static final String format(LocalDateTime localDateTime) {
|
||||
return format(localDateTime,LONG_FORMAT);
|
||||
}
|
||||
|
||||
public static final String format(LocalDateTime localDateTime,String pattern) {
|
||||
if(localDateTime==null) return null;
|
||||
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return localDateTime.format(dateFormatter);
|
||||
}
|
||||
|
||||
|
||||
public static final String format(OffsetDateTime offsetDateTime) {
|
||||
return format(offsetDateTime,FMT_OFFSET_DATETIME);
|
||||
}
|
||||
|
||||
public static final String format(OffsetDateTime offsetDateTime,String pattern) {
|
||||
if(offsetDateTime==null) return null;
|
||||
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return offsetDateTime.format(dateFormatter);
|
||||
}
|
||||
|
||||
public static final String format(OffsetTime offsetTime) {
|
||||
return format(offsetTime,FMT_OFFSET_TIME);
|
||||
}
|
||||
|
||||
public static final String format(OffsetTime offsetDateTime,String pattern) {
|
||||
if(offsetDateTime==null) return null;
|
||||
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return offsetDateTime.format(dateFormatter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final String format(Date date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static long getDateTime(String dateStr) {
|
||||
Date date = stringToDate(dateStr, "yyyy-MM-dd HH:mm:ss");
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
// 取得当前日期(YYYYMMDD)
|
||||
public static String getYYYYMMDD() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(GENERAL_YYYYMMDD);
|
||||
return sdf.format(new Date());
|
||||
}
|
||||
|
||||
// 取得时间戳(YYYYMMDDHHMMSS)
|
||||
public static String getTimeStamp() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(GENERAL_YYYYMMDDHHMMSS);
|
||||
return sdf.format(new Date());
|
||||
}
|
||||
|
||||
public static String getYear() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
return cal.get(Calendar.YEAR) + "";
|
||||
}
|
||||
|
||||
public static String getMonth() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
int i = cal.get(Calendar.MONTH) + 1;
|
||||
if (i < 10) {
|
||||
return "0" + i;
|
||||
}
|
||||
return i + "";
|
||||
}
|
||||
|
||||
public static String getDate() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
int i = cal.get(Calendar.DATE);
|
||||
if (i < 10) {
|
||||
return "0" + i;
|
||||
}
|
||||
return i + "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上个月最后一天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMonthLastDate(String date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
||||
Calendar c = Calendar.getInstance();
|
||||
Date parse = new Date();
|
||||
// 设置为指定日期
|
||||
if (StringUtils.isNotEmpty(date)) {
|
||||
date = date.replace("-", "");
|
||||
try {
|
||||
parse = sdf.parse(date);
|
||||
} catch (ParseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
c.setTime(parse);
|
||||
// 指定日期月份减去一
|
||||
c.add(Calendar.MONTH, -1);
|
||||
// 指定日期月份减去一后的 最大天数
|
||||
c.set(Calendar.DATE, c.getActualMaximum(Calendar.DATE));
|
||||
// 获取最终的时间
|
||||
Date time = c.getTime();
|
||||
return sdf.format(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取yyyy-MM-dd当天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getToday() {
|
||||
String today = LocalDate.now().format(fmt);
|
||||
return today;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取yyyy-MM-dd明天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getTomorrow() {
|
||||
String tomorrow = LocalDate.now().plusDays(1).format(fmt);
|
||||
return tomorrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间
|
||||
*
|
||||
* @param date 时间
|
||||
* @param hour 小时
|
||||
* @param minute 分钟
|
||||
* @param second 秒钟
|
||||
* @param millisecond 毫秒
|
||||
* @return 返回值
|
||||
*/
|
||||
public static Date setDateTime(Date date, Integer hour, Integer minute, Integer second, Integer millisecond) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hour);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
calendar.set(Calendar.SECOND, second);
|
||||
calendar.set(Calendar.MILLISECOND, millisecond);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static LocalDateTime toLocalDateTime(String source){
|
||||
return toLocalDateTime(source, LONG_FORMAT);
|
||||
}
|
||||
|
||||
public static LocalDateTime toLocalDateTime(String source,String fmt){
|
||||
try {
|
||||
return LocalDateTime.parse(source,DateTimeFormatter.ofPattern(fmt));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalDate toLocalDate(String source){
|
||||
return toLocalDate(source, GENERAL);
|
||||
}
|
||||
|
||||
public static LocalDate toLocalDate(String source,String fmt){
|
||||
try {
|
||||
return LocalDate.parse(source,DateTimeFormatter.ofPattern(fmt));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalTime toLocalTime(String source){
|
||||
return toLocalTime(source, FMT_TIME);
|
||||
}
|
||||
|
||||
public static LocalTime toLocalTime(String source,String fmt){
|
||||
try {
|
||||
return LocalTime.parse(source,DateTimeFormatter.ofPattern(fmt));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Timestamp toTimestamp(String source,String fmt){
|
||||
try {
|
||||
SimpleDateFormat f = new SimpleDateFormat(fmt);
|
||||
return new Timestamp(f.parse(source).getTime());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalDateTime toLocalDateTime(Date date) {
|
||||
return LocalDateTime.ofInstant(new Date(date.getTime()).toInstant(), zone);
|
||||
}
|
||||
|
||||
public static Date toDate(LocalDateTime ldtime) {
|
||||
return Date.from(ldtime.atZone(zone).toInstant());
|
||||
}
|
||||
|
||||
public static Timestamp toTimestamp(LocalDateTime ldtime) {
|
||||
return Timestamp.from(ldtime.atZone(zone).toInstant());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,349 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.Socket;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
|
||||
|
||||
public class IoUtils {
|
||||
|
||||
private final static Charset charset=Charset.forName("UTF-8");
|
||||
|
||||
private final static ForkJoinPool forkJoinPool = new ForkJoinPool();
|
||||
|
||||
public static void closeQuietly(Closeable... closeables) {
|
||||
if (closeables == null)
|
||||
return;
|
||||
|
||||
for (Closeable closeable : closeables) {
|
||||
if (closeable == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In JDK 1.6, java.net.Socket doesn't implement Closeable, so we have this
|
||||
// overload.
|
||||
public static void closeQuietly(final Socket... sockets) {
|
||||
if (sockets == null)
|
||||
return;
|
||||
|
||||
for (Socket socket : sockets) {
|
||||
if (socket == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the text read from the given reader as a String. Closes the given
|
||||
* reader upon return.
|
||||
*/
|
||||
public static String getText(Reader reader) throws IOException {
|
||||
try {
|
||||
StringBuilder source = new StringBuilder();
|
||||
BufferedReader buffered = new BufferedReader(reader);
|
||||
String line = buffered.readLine();
|
||||
|
||||
while (line != null) {
|
||||
source.append(line);
|
||||
source.append('\n');
|
||||
line = buffered.readLine();
|
||||
}
|
||||
|
||||
return source.toString();
|
||||
} finally {
|
||||
closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text read from the given file as a String.
|
||||
*/
|
||||
public static String getText(File path) throws IOException {
|
||||
return getText(new FileReader(path));
|
||||
}
|
||||
|
||||
|
||||
public static String getText(InputStream stream) throws IOException {
|
||||
return getText(new InputStreamReader(stream,charset));
|
||||
}
|
||||
|
||||
public static String getText(InputStream stream,Charset charset) throws IOException {
|
||||
return getText(new InputStreamReader(stream,charset));
|
||||
}
|
||||
|
||||
public static void createDirectory(File dir) throws IOException {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStream(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
|
||||
try {
|
||||
int read = in.read(buffer);
|
||||
while (read > 0) {
|
||||
out.write(buffer, 0, read);
|
||||
read = in.read(buffer);
|
||||
}
|
||||
} finally {
|
||||
closeQuietly(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File source, File target) throws FileNotFoundException, IOException {
|
||||
if (!source.isFile())
|
||||
throw new IOException(
|
||||
String.format("Error copying file %s to %s; source file does not exist", source, target));
|
||||
|
||||
createDirectory(target.getParentFile());
|
||||
doCopyFile(source, target);
|
||||
checkSameSize(source, target);
|
||||
}
|
||||
|
||||
public static List<File> listFilesRecursively(File baseDir) throws IOException {
|
||||
if (!baseDir.exists())
|
||||
return Collections.emptyList();
|
||||
|
||||
List<File> result = new ArrayList<File>();
|
||||
doListFilesRecursively(baseDir, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getFileExtension(String filename) {
|
||||
int index = filename.lastIndexOf('.');
|
||||
return index == -1 ? null : filename.substring(index + 1, filename.length());
|
||||
}
|
||||
|
||||
public static void createFile(File file) throws IOException {
|
||||
if(!file.exists()) {
|
||||
if(file.isDirectory()) {
|
||||
file.mkdirs();
|
||||
}else {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void doListFilesRecursively(File baseDir, List<File> result) throws IOException {
|
||||
List<File> dirs = new ArrayList<File>();
|
||||
File[] files = baseDir.listFiles();
|
||||
if (files == null) {
|
||||
throw new IOException("Failed to list files of directory '" + baseDir + "'");
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
result.add(file);
|
||||
} else {
|
||||
dirs.add(file);
|
||||
}
|
||||
}
|
||||
for (File dir : dirs) {
|
||||
doListFilesRecursively(dir, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void doCopyFile(File source, File target) throws IOException {
|
||||
FileInputStream in = null;
|
||||
FileOutputStream out = null;
|
||||
|
||||
try {
|
||||
in = new FileInputStream(source);
|
||||
out = new FileOutputStream(target);
|
||||
// instead of checking transferred size, we'll compare file sizes in
|
||||
// checkSameSize()
|
||||
in.getChannel().transferTo(0, Long.MAX_VALUE, out.getChannel());
|
||||
} finally {
|
||||
closeQuietly(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkSameSize(File source, File target) throws IOException {
|
||||
long fromSize = source.length();
|
||||
long toSize = target.length();
|
||||
|
||||
if (fromSize != toSize)
|
||||
throw new IOException(
|
||||
String.format("Error copying file %s to %s; source file size is %d, but target file size is %d",
|
||||
source, target, fromSize, toSize));
|
||||
}
|
||||
|
||||
public static byte[] getBytes(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
copyStream(in, out);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] getBytes(File in) throws IOException {
|
||||
return getBytes(new FileInputStream(in));
|
||||
}
|
||||
|
||||
public static void streamToFile(InputStream in, File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
//createDirectory(file.getParentFile());
|
||||
file.createNewFile();// 将压缩文件内容写入到这个文件中
|
||||
}
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
int count;
|
||||
byte[] buf = new byte[8192];
|
||||
while ((count = in.read(buf)) != -1) {
|
||||
fos.write(buf, 0, count);
|
||||
}
|
||||
fos.flush();
|
||||
closeQuietly(in, fos);
|
||||
}
|
||||
|
||||
public static void byteToFile(byte[] bytes, File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
//createDirectory(file.getParentFile());
|
||||
file.createNewFile();// 将压缩文件内容写入到这个文件中
|
||||
}
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(bytes);
|
||||
fos.flush();
|
||||
closeQuietly(fos);
|
||||
}
|
||||
|
||||
public static void writeFile(File file, OutputStream out, boolean close) throws IOException {
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
int count;
|
||||
byte[] buf = new byte[8192];
|
||||
while ((count = in.read(buf)) != -1) {
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
out.flush();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
closeQuietly(in);
|
||||
if (close) {
|
||||
closeQuietly(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class FileSizeFinder extends RecursiveTask<Long> {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
final File file;
|
||||
public FileSizeFinder(final File theFile) {
|
||||
file = theFile;
|
||||
}
|
||||
@Override
|
||||
public Long compute() {
|
||||
long size = 0;
|
||||
if (file.isFile()) {
|
||||
size = file.length();
|
||||
} else {
|
||||
final File[] children = file.listFiles();
|
||||
if (children != null) {
|
||||
List<ForkJoinTask<Long>> tasks = new ArrayList<ForkJoinTask<Long>>();
|
||||
for (final File child : children) {
|
||||
if (child.isFile()) {
|
||||
size += child.length();
|
||||
} else {
|
||||
tasks.add(new FileSizeFinder(child));
|
||||
}
|
||||
}
|
||||
for (final ForkJoinTask<Long> task : invokeAll(tasks)) {
|
||||
size += task.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public static long getFileSize(File file) {
|
||||
return forkJoinPool.invoke(new FileSizeFinder(file));
|
||||
}
|
||||
|
||||
public static String getProjectPath() {
|
||||
String url=Thread.currentThread().getContextClassLoader().getResource("").getPath();
|
||||
try {
|
||||
url=url.substring(1, url.length()-15);
|
||||
if(url.contains("/targe")) {
|
||||
url = url.replace("/targe","");
|
||||
}
|
||||
return URLDecoder.decode(url,"utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
public static void delFile(File file) {
|
||||
if(file.isDirectory()) {
|
||||
File[] childs = file.listFiles();
|
||||
if(childs!=null) {
|
||||
for (int i = 0; i < childs.length; i++) {
|
||||
if(childs[i].isDirectory()) {
|
||||
delFile(childs[i]);
|
||||
}else {
|
||||
childs[i].delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
|
||||
public static List<File> findFile(File file,FilenameFilter filter) {
|
||||
List<File> res = new ArrayList<File>();
|
||||
findChilds(res, file, filter);
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void findChilds(List<File> res,File file,FilenameFilter filter) {
|
||||
if(file.isDirectory()) {
|
||||
File[] delFiles=file.listFiles(filter);
|
||||
for (int i = 0; i < delFiles.length; i++) {
|
||||
res.add(delFiles[i]);
|
||||
}
|
||||
File[] childs= file.listFiles();
|
||||
for (int i = 0; i < childs.length; i++) {
|
||||
findChilds(res,childs[i],filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class LambdaUtils {
|
||||
|
||||
private LambdaUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static <T, R>SerializedLambda getLambda(TFunction<T, R> fn) {
|
||||
// 从function取出序列化方法
|
||||
Method writeReplaceMethod = null;
|
||||
try {
|
||||
writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
|
||||
writeReplaceMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 从序列化方法取出序列化的lambda信息
|
||||
SerializedLambda lambda = null;
|
||||
try {
|
||||
lambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return lambda;
|
||||
}
|
||||
|
||||
public static <T, R>Field getField(TFunction<T, R> fn) {
|
||||
// 从序列化方法取出序列化的lambda信息
|
||||
SerializedLambda lambda = getLambda(fn);
|
||||
String fieldName = getFieldName(lambda);
|
||||
Field field = null;
|
||||
try {
|
||||
field = Class.forName(lambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
|
||||
} catch (ClassNotFoundException | NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
private static <T, R>String getFieldName(SerializedLambda lambda) {
|
||||
// 从lambda信息取出method、field、class等
|
||||
String implMethodName = lambda.getImplMethodName();
|
||||
// 确保方法是符合规范的get方法,boolean类型是is开头
|
||||
if (!implMethodName.startsWith("is") && !implMethodName.startsWith("get")) {
|
||||
throw new RuntimeException("get方法名称: " + implMethodName + ", 不符合java bean规范");
|
||||
}
|
||||
// get方法开头为 is 或者 get,将方法名 去除is或者get,然后首字母小写,就是属性名
|
||||
int prefixLen = implMethodName.startsWith("is") ? 2 : 3;
|
||||
|
||||
String fieldName = implMethodName.substring(prefixLen);
|
||||
String firstChar = fieldName.substring(0, 1);
|
||||
fieldName = fieldName.replaceFirst(firstChar, firstChar.toLowerCase());
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public static <T, R>String getFieldName(TFunction<T, R> fn) {
|
||||
SerializedLambda lambda = getLambda(fn);
|
||||
return getFieldName(lambda);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,129 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ListUtils {
|
||||
|
||||
public static enum ListType{
|
||||
ArrayList,LinkedList,Vector,CopyOnWriteArrayList
|
||||
}
|
||||
|
||||
public static ListType parseType(Class<?> cls) {
|
||||
if(LinkedList.class.equals(cls)) {
|
||||
return ListType.LinkedList;
|
||||
}else if(Vector.class.equals(cls)) {
|
||||
return ListType.Vector;
|
||||
}else if(CopyOnWriteArrayList.class.equals(cls)) {
|
||||
return ListType.CopyOnWriteArrayList;
|
||||
}else {
|
||||
return ListType.ArrayList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> getMapNewInstance(ListType type) {
|
||||
List<T> result=null;
|
||||
switch (type) {
|
||||
case LinkedList:
|
||||
result=CollectionUtils.newLinkedList();
|
||||
break;
|
||||
case Vector:
|
||||
result=CollectionUtils.newVector();
|
||||
break;
|
||||
case CopyOnWriteArrayList:
|
||||
result=CollectionUtils.newConcurrentArrayList();
|
||||
break;
|
||||
default:
|
||||
result=CollectionUtils.newArrayList();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T>List<T> newInstance(Class<?> cls) {
|
||||
return getMapNewInstance(parseType(cls));
|
||||
}
|
||||
|
||||
|
||||
public static <T> void forEach(@NonNull List<T> list,ListForEach<? super T> action){
|
||||
int i=0;
|
||||
Iterator<T> iterator=list.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
action.accept(iterator.next(),i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ListForEach<T>{
|
||||
|
||||
void accept(T t,int index);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> ofArray(T... objs){
|
||||
List<T> result=null;
|
||||
if(objs!=null && objs.length>0) {
|
||||
result=CollectionUtils.newArrayList();
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
result.add(objs[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> newArrayList(T... objs){
|
||||
List<T> result=null;
|
||||
if(objs!=null && objs.length>0) {
|
||||
result=CollectionUtils.newArrayList();
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
result.add(objs[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> ofCollection(Collection<?> list){
|
||||
List<T> result=null;
|
||||
if(list!=null && list.size()>0) {
|
||||
result=CollectionUtils.newArrayList();
|
||||
for (Object t : list) {
|
||||
result.add((T)t);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> List<T> ofArrays(T[] objs){
|
||||
List<T> result=null;
|
||||
if(objs!=null && objs.length>0) {
|
||||
result=CollectionUtils.newArrayList();
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
result.add(objs[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T>T getFirst(List<T> list){
|
||||
if(CollectionUtils.isNotEmpty(list)) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MapUtils {
|
||||
|
||||
public static enum MapType {
|
||||
hashMap,Hashtable,Properties,LinkedHashMap,IdentityHashMap,
|
||||
TreeMap,WeakHashMap,ConcurrentHashMap
|
||||
}
|
||||
|
||||
public static MapType parseMapType(Class<?> cls) {
|
||||
if(Hashtable.class.equals(cls)) {
|
||||
return MapType.Hashtable;
|
||||
}else if(Properties.class.equals(cls)) {
|
||||
return MapType.Properties;
|
||||
}else if(LinkedHashMap.class.equals(cls)) {
|
||||
return MapType.LinkedHashMap;
|
||||
}else if(IdentityHashMap.class.equals(cls)) {
|
||||
return MapType.IdentityHashMap;
|
||||
}else if(TreeMap.class.equals(cls)) {
|
||||
return MapType.TreeMap;
|
||||
}else if(WeakHashMap.class.equals(cls)) {
|
||||
return MapType.WeakHashMap;
|
||||
}else if(ConcurrentHashMap.class.equals(cls)) {
|
||||
return MapType.ConcurrentHashMap;
|
||||
}else {
|
||||
return MapType.hashMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> Map<K,V> getMapNewInstance(MapType type) {
|
||||
Map<K,V> result=null;
|
||||
switch (type) {
|
||||
case Hashtable:
|
||||
result=CollectionUtils.newHashtable();
|
||||
break;
|
||||
case Properties:
|
||||
result=(Map<K, V>) CollectionUtils.newProperties();
|
||||
break;
|
||||
case LinkedHashMap:
|
||||
result=CollectionUtils.newLinkedHashMap();
|
||||
break;
|
||||
case IdentityHashMap:
|
||||
result=CollectionUtils.newIdentityHashMap();
|
||||
break;
|
||||
case TreeMap:
|
||||
result=CollectionUtils.newTreeMap();
|
||||
break;
|
||||
case WeakHashMap:
|
||||
result=CollectionUtils.newWeakHashMap();
|
||||
break;
|
||||
case ConcurrentHashMap:
|
||||
result=CollectionUtils.newConcurrentHashMap();
|
||||
break;
|
||||
default:
|
||||
result=CollectionUtils.newHashMap();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <K, V> Map<K,V> newInstance(Class<?> cls) {
|
||||
return getMapNewInstance(parseMapType(cls));
|
||||
}
|
||||
|
||||
public static <K, V, R> Map<K,V> ofList(Collection<V> collections,TFunction<V, R> fn) {
|
||||
Map<K,V> map = CollectionUtils.newHashtable();
|
||||
Field field = LambdaUtils.getField(fn);
|
||||
for (V v : collections) {
|
||||
K k = BeanUtils.getFieldValue(field, v);
|
||||
map.put(k, v);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class MybatisTools implements ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* 存储Mapper类与实体类的映射关系
|
||||
* key: Mapper接口的Class对象
|
||||
* value: 对应的实体类的Class对象
|
||||
*/
|
||||
private static final Map<Class<?>,BaseMapper<?>> ENTITY_MAPPER_MAP = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
// 获取所有继承自BaseMapper的接口(即MyBatis-Plus的Mapper接口)
|
||||
|
||||
Map<String, BaseMapper> mapperBeans = applicationContext.getBeansOfType(BaseMapper.class);
|
||||
|
||||
for (BaseMapper<?> mapper : mapperBeans.values()) {
|
||||
// 获取Mapper接口的Class对象(因为mapper是代理对象,需要获取原始接口)
|
||||
Class<?> mapperInterface = getMapperInterface(mapper.getClass());
|
||||
|
||||
// 解析Mapper接口对应的实体类
|
||||
Class<?> entityClass = resolveEntityClass(mapperInterface);
|
||||
|
||||
if (entityClass != null) {
|
||||
ENTITY_MAPPER_MAP.put(entityClass, mapper);
|
||||
}
|
||||
}
|
||||
System.out.println(ENTITY_MAPPER_MAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Mapper代理对象对应的原始接口
|
||||
*/
|
||||
private Class<?> getMapperInterface(Class<?> mapperProxyClass) {
|
||||
// MyBatis的Mapper代理类会实现对应的Mapper接口
|
||||
Class<?>[] interfaces = mapperProxyClass.getInterfaces();
|
||||
for (Class<?> iface : interfaces) {
|
||||
// 判断是否是BaseMapper的子类
|
||||
if (BaseMapper.class.isAssignableFrom(iface) && iface != BaseMapper.class) {
|
||||
return iface;
|
||||
}
|
||||
}
|
||||
return mapperProxyClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Mapper接口对应的实体类(通过泛型参数)
|
||||
*/
|
||||
private Class<?> resolveEntityClass(Class<?> mapperInterface) {
|
||||
// 获取Mapper接口的泛型父类(BaseMapper<T>)
|
||||
Type[] genericInterfaces = mapperInterface.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
if (genericInterface instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
|
||||
// 检查是否是BaseMapper
|
||||
if (parameterizedType.getRawType() == BaseMapper.class) {
|
||||
// 获取泛型参数T(即实体类)
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
if (actualTypeArguments.length > 0 && actualTypeArguments[0] instanceof Class) {
|
||||
return (Class<?>) actualTypeArguments[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据实体类获取对应的Mapper类
|
||||
*/
|
||||
public static BaseMapper<?> getMapper(Class<?> entityClass) {
|
||||
return ENTITY_MAPPER_MAP.get(entityClass);
|
||||
}
|
||||
|
||||
|
||||
public static TableInfo getTableInfo(Class<?> entityClass) {
|
||||
return TableInfoHelper.getTableInfo(entityClass);
|
||||
}
|
||||
|
||||
public static TableInfo getTableInfo(String tablename) {
|
||||
return TableInfoHelper.getTableInfo(tablename);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class RegexUtils {
|
||||
|
||||
private static final Set<String> symbols=SetUtils.of("\\","^","$","*","+","?","{","}","[","]",".","|","-","\\b","\\B"
|
||||
,"\\c","\\d","\\D","\\f","\\n","\\r","\\s","\\S","\\t","\\v","\\w","\\W","\\x","\\u");
|
||||
|
||||
private static final String prefix="${";
|
||||
|
||||
private static final String suffixed="}";
|
||||
|
||||
private static final Pattern placeholder_regex=buildPlaceholderPattern(prefix, suffixed);
|
||||
|
||||
private RegexUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static boolean has(String regex,String str) {
|
||||
return has(Pattern.compile(regex), str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符中是否包含占位符
|
||||
* */
|
||||
public static boolean has(Pattern pattern,String str) {
|
||||
return pattern.matcher(str).find();
|
||||
}
|
||||
|
||||
public static boolean has(String str) {
|
||||
return placeholder_regex.matcher(str).find();
|
||||
}
|
||||
|
||||
public static List<String> findPlaceholder(String str) {
|
||||
return findPlaceholder(str,placeholder_regex,2,1);
|
||||
}
|
||||
|
||||
public static List<String> findPlaceholder(String str,String regex,int prefixLeng,int endLeng) {
|
||||
return findPlaceholder(str,Pattern.compile(regex),prefixLeng,endLeng);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找字符串中的占位符中的字符
|
||||
* */
|
||||
public static List<String> findPlaceholder(String str,Pattern pattern,int prefixLeng,int endLeng) {
|
||||
Matcher m=pattern.matcher(str);
|
||||
List<String> result=null;
|
||||
while (m.find()) {
|
||||
if(result==null) result=CollectionUtils.newArrayList();
|
||||
result.add(m.group().substring(prefixLeng, m.group().length()-endLeng));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String replacePlaceholder(String str,String[] replaceStr) {
|
||||
return replacePlaceholder(placeholder_regex, str, replaceStr);
|
||||
}
|
||||
|
||||
|
||||
public static String replacePlaceholder(String str,Map<String,String> values) {
|
||||
List<String> placeholders = findPlaceholder(str);
|
||||
List<String> replaceValues = CollectionUtils.newArrayList();
|
||||
for (String key : placeholders) {
|
||||
replaceValues.add(values.get(key));
|
||||
}
|
||||
String[] _vals = new String[replaceValues.size()];
|
||||
replaceValues.toArray(_vals);
|
||||
return replacePlaceholder(placeholder_regex, str,_vals);
|
||||
}
|
||||
|
||||
public static String replacePlaceholder(Pattern regex,String str,String[] replaceStr) {
|
||||
Matcher m=regex.matcher(str);
|
||||
StringBuilder result=new StringBuilder();
|
||||
int index=0;int before=0;
|
||||
while (m.find()) {
|
||||
result.append(str.subSequence(before, m.start()));
|
||||
before=m.end();
|
||||
if(index<replaceStr.length) {
|
||||
String _value = replaceStr[index];
|
||||
if(_value!=null) {
|
||||
result.append(_value);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if(str.length()!=before) result.append(str.subSequence(before, str.length()));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义字符中的正则元符
|
||||
* */
|
||||
public static String decodeRegex(String str) {
|
||||
for (String key : symbols) {
|
||||
if(str.contains(key)) {
|
||||
str=str.replace(key,"\\"+key);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建占位符的正则表达式
|
||||
* */
|
||||
public static Pattern buildPlaceholderPattern(String prefix,String suffixed) {
|
||||
prefix=decodeRegex(prefix);
|
||||
suffixed=decodeRegex(suffixed);
|
||||
return Pattern.compile(String.format("%s[^%s]*%s", prefix,suffixed,suffixed));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
public class SanDefaultFilter implements SanFilter{
|
||||
|
||||
public final String CLASS_SUFFIX = "^([^\\$]+|[^\\d+]+)\\.class";
|
||||
|
||||
@Override
|
||||
public boolean accept(String current_package,String scan_package) {
|
||||
if(StringUtils.isEmpty(scan_package)) {
|
||||
return true;
|
||||
}else if(scan_package.contains("*")) {
|
||||
return current_package.matches(scan_package);
|
||||
}
|
||||
return current_package.startsWith(scan_package);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(String className) {
|
||||
return className.matches(CLASS_SUFFIX);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
|
||||
public interface SanFilter {
|
||||
|
||||
public final String CLASS_SUFFIX = "^([^\\$]+|[^\\d+]+)\\.class";
|
||||
|
||||
public default boolean accept(String current_package,String scan_package) {
|
||||
if(scan_package.contains("*")) {
|
||||
return current_package.matches(scan_package);
|
||||
}
|
||||
return current_package.equals(scan_package) || current_package.startsWith(scan_package);
|
||||
};
|
||||
|
||||
public default boolean accept(String className) {
|
||||
return className.matches(CLASS_SUFFIX);
|
||||
};
|
||||
|
||||
public default boolean accept(Class<?> klazz) {
|
||||
return true;
|
||||
};
|
||||
|
||||
}
|
||||
@ -0,0 +1,200 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
public class ScanClasses {
|
||||
|
||||
private static Log log=LogFactory.getLog(ScanClasses.class);
|
||||
|
||||
/** 过滤器 **/
|
||||
private static SanFilter filter =new SanDefaultFilter();
|
||||
|
||||
public static final String CLASS_SUFFIX = ".class";
|
||||
|
||||
private static final String FILE_PROCOTOL="file";
|
||||
|
||||
private static final String JAR_PROCOTOL="jar";
|
||||
|
||||
private ScanClasses() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Set<String> packages) {
|
||||
return scan(packages, filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Set<String> packages,SanFilter filter) {
|
||||
return scan(packages,null,filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Set<String> packages,Set<Class<? extends Annotation>> annotations) {
|
||||
return scan(packages,annotations,filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Set<String> packages,Set<Class<? extends Annotation>> annotations,SanFilter filter) {
|
||||
Set<Class<?>> classes=CollectionUtils.newHashSet();
|
||||
Iterator<String> iterator=packages.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
scan(classes,iterator.next(),annotations,filter);
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(String[] packages) {
|
||||
return scan(packages, filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(String[] packages,SanFilter filter) {
|
||||
return scan(packages,null,filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(String[] packages,Set<Class<? extends Annotation>> annotations) {
|
||||
return scan(packages,annotations,filter);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(String[] packages,Set<Class<? extends Annotation>> annotations,SanFilter filter) {
|
||||
Set<Class<?>> classes=CollectionUtils.newHashSet();
|
||||
for (int i = 0; i < packages.length; i++) {
|
||||
scan(classes,packages[i],annotations,filter);
|
||||
}
|
||||
return classes;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void scan(Set<Class<?>> classes,String scan_package,Set<Class<? extends Annotation>> annotations,SanFilter filter){
|
||||
String current_package=getCurrentPackage(scan_package);
|
||||
// 获取包的名字 并进行替换
|
||||
String packageDirName = current_package.replace('.', '/');
|
||||
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
||||
Enumeration<URL> dirs = null;
|
||||
try {
|
||||
dirs = ClassUtils.getDefaultClassLoader().getResources(packageDirName);
|
||||
while(dirs.hasMoreElements()) {
|
||||
URL url = dirs.nextElement();
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug("url协议--->"+url.getProtocol());
|
||||
}
|
||||
if(FILE_PROCOTOL.equals(url.getProtocol())) {
|
||||
File file = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
|
||||
if(!file.exists() || !file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
if(file.isDirectory()) {
|
||||
File[] files=file.listFiles();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
scanFile(scan_package,current_package,files[i],annotations,classes,filter);
|
||||
}
|
||||
}else {
|
||||
scanFile(scan_package, current_package, file,annotations,classes,filter);
|
||||
}
|
||||
}else if(JAR_PROCOTOL.equals(url.getProtocol())) {
|
||||
scanJar(scan_package, current_package, ((JarURLConnection)url.openConnection()).getJarFile(),annotations,classes,filter);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("扫描claess异常",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getCurrentPackage(String scan_package) {
|
||||
if(scan_package.contains(".*")) {
|
||||
return scan_package.substring(0,scan_package.indexOf(".*"));
|
||||
}
|
||||
return scan_package;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下次扫描的包路径
|
||||
* */
|
||||
private static String getNextPackage(String current_package,String file_name) {
|
||||
String nextPackage=null;
|
||||
if(StringUtils.isEmpty(current_package)) {
|
||||
nextPackage= getClassName(file_name);
|
||||
}else {
|
||||
nextPackage=current_package+"."+getClassName(file_name);
|
||||
}
|
||||
return nextPackage;
|
||||
}
|
||||
|
||||
private static void scanFile(String scan_package,String current_package,File file,Set<Class<? extends Annotation>> annotations,Set<Class<?>> classes,SanFilter filter) {
|
||||
if(filter==null || (filter!=null && filter.accept(current_package,scan_package))){
|
||||
String file_name=file.getName();
|
||||
if(file.isDirectory()) {
|
||||
File[] files=file.listFiles();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
scanFile(scan_package,getNextPackage(current_package,file_name),files[i],annotations,classes,filter);
|
||||
}
|
||||
}else {
|
||||
if(filter==null || (filter!=null && filter.accept(file_name))) {
|
||||
parseClass(scan_package, current_package,getNextPackage(current_package,file_name),annotations,classes,filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void parseClass(String scan_package,String current_package,String className,Set<Class<? extends Annotation>> annotations,Set<Class<?>> classes,SanFilter filter) {
|
||||
Class<?> cls= ClassUtils.loadClass(className);
|
||||
if(annotations!=null && !annotations.isEmpty()) {
|
||||
for (Class<? extends Annotation> annotation : annotations) {
|
||||
if(cls.getAnnotation(annotation)!=null) {
|
||||
classes.add(cls);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}else if(filter!=null && filter.accept(cls)){
|
||||
classes.add(cls);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void scanJar(String scan_package,String current_package,JarFile jar,Set<Class<? extends Annotation>> annotations,Set<Class<?>> classes,SanFilter filter) {
|
||||
Enumeration<JarEntry> entrys= jar.entries();
|
||||
while(entrys.hasMoreElements()) {
|
||||
JarEntry entry=entrys.nextElement();
|
||||
if(!entry.isDirectory()) {
|
||||
String cpackage = getJarPackage(entry);
|
||||
if(filter==null || filter.accept(cpackage,scan_package)) {
|
||||
String name = entry.getName();
|
||||
if(filter==null || filter.accept(name)) {
|
||||
parseClass(scan_package,cpackage,getJarClassName(entry),annotations,classes,filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getJarPackage(JarEntry entry) {
|
||||
String name = entry.getName();
|
||||
if(name.lastIndexOf("/")!=-1) {
|
||||
name = name.substring(0, name.lastIndexOf("/"));
|
||||
}
|
||||
return name.replace("/", ".");
|
||||
}
|
||||
|
||||
private static String getJarClassName(JarEntry entry) {
|
||||
return entry.getName().substring(0, entry.getName().length()-6).replaceAll("/", ".");
|
||||
}
|
||||
|
||||
private static String getClassName(String name) {
|
||||
return name.split("\\.")[0];
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2023年1月8日 下午6:29:01
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class ScanFile {
|
||||
|
||||
|
||||
private static final String FILE_PROCOTOL="file";
|
||||
|
||||
private static final String JAR_PROCOTOL="jar";
|
||||
|
||||
public static void scan(String name,ScanFileFilter filter) {
|
||||
try {
|
||||
Enumeration<URL> dirs = getDefaultClassLoader().getResources(name);
|
||||
if(dirs!=null) {
|
||||
while(dirs.hasMoreElements()) {
|
||||
URL url = dirs.nextElement();
|
||||
if(FILE_PROCOTOL.equals(url.getProtocol())) {
|
||||
filter.accept(url.openStream());
|
||||
}else if(JAR_PROCOTOL.equals(url.getProtocol())) {
|
||||
JarFile jarFile = ((JarURLConnection)url.openConnection()).getJarFile();
|
||||
ZipEntry entry = jarFile.getEntry(name);
|
||||
if(entry!=null) {
|
||||
filter.accept(jarFile.getInputStream(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
log.info("没有扫描到任何东西!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassLoader getDefaultClassLoader() {
|
||||
ClassLoader cl = null;
|
||||
try {
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
if (cl == null) {
|
||||
cl = ScanFile.class.getClassLoader();
|
||||
if (cl == null) {
|
||||
try {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2023年1月8日 下午6:29:56
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public interface ScanFileFilter {
|
||||
|
||||
public void accept(InputStream in);
|
||||
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SetUtils {
|
||||
|
||||
public static enum SetType{
|
||||
HashSet,TreeSet,LinkedHashSet,ConcurrentSkipListSet
|
||||
}
|
||||
|
||||
|
||||
public static SetType parseType(Class<?> cls) {
|
||||
if(LinkedHashSet.class.equals(cls)) {
|
||||
return SetType.LinkedHashSet;
|
||||
}else if(TreeSet.class.equals(cls)) {
|
||||
return SetType.TreeSet;
|
||||
}else if(ConcurrentSkipListSet.class.equals(cls)) {
|
||||
return SetType.ConcurrentSkipListSet;
|
||||
}else {
|
||||
return SetType.HashSet;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Set<T> getMapNewInstance(SetType type) {
|
||||
Set<T> result=null;
|
||||
switch (type) {
|
||||
case LinkedHashSet:
|
||||
result=CollectionUtils.newLinkedHashSet();
|
||||
break;
|
||||
case TreeSet:
|
||||
result=CollectionUtils.newTreeSet();
|
||||
break;
|
||||
case ConcurrentSkipListSet:
|
||||
result=CollectionUtils.newConcurrentSet();
|
||||
break;
|
||||
default:
|
||||
result=CollectionUtils.newHashSet();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static <T> Set<T> newInstance(Class<?> cls) {
|
||||
return getMapNewInstance(parseType(cls));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> Set<T> of(T... objs){
|
||||
Set<T> result=null;
|
||||
if(objs!=null && objs.length>0) {
|
||||
result=CollectionUtils.newHashSet();
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
result.add(objs[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> Set<T> ofArray(T[] objs){
|
||||
Set<T> result=null;
|
||||
if(objs!=null && objs.length>0) {
|
||||
result=CollectionUtils.newHashSet();
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
result.add(objs[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> Set<T> ofCollection(Collection<T> objs){
|
||||
Set<T> result=null;
|
||||
if(objs!=null) {
|
||||
result=getMapNewInstance(SetType.HashSet);
|
||||
Iterator<T> it=objs.iterator();
|
||||
while (it.hasNext()) {
|
||||
result.add(it.next());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T, V, R> Set<V> ofCollection(Collection<T> collections,TFunction<V, R> fn) {
|
||||
Set<V> set = CollectionUtils.newHashSet();
|
||||
Field field = LambdaUtils.getField(fn);
|
||||
for (T t : collections) {
|
||||
V v = BeanUtils.getFieldValue(field, t);
|
||||
set.add(v);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <T>T getFirst(Set<T> sets){
|
||||
if(CollectionUtils.isNotEmpty(sets)) {
|
||||
for (T t : sets) {
|
||||
if(t!= null) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.pictc.cache.CacheFactory;
|
||||
import com.pictc.cache.TanukiCache;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2022年11月6日 上午10:22:31
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Component
|
||||
public class SpringAnnotationUtils implements EnvironmentAware{
|
||||
|
||||
private static final TanukiCache<String,InvocationHandler> handlerCache= CacheFactory.factory("Invocation-cache");
|
||||
|
||||
private static final TanukiCache<String,Annotation> findCache = CacheFactory.factory("Annotation-cache");
|
||||
|
||||
private static final String findKeyFormat="%s@%s";
|
||||
|
||||
private static final String handlerKeyFormat="%s@%s";
|
||||
|
||||
private static Environment environment;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A extends Annotation>A findAnnotation(Class<?> clazz,Class<A> annotationType){
|
||||
if(!clazz.isAnnotationPresent(annotationType)) {
|
||||
return null;
|
||||
}
|
||||
String key=String.format(findKeyFormat, clazz.getName(),annotationType.getName());
|
||||
if(!findCache.containsKey(key)) {
|
||||
findCache.save(key, resolveAnnotationEnvValue(clazz.getAnnotation(annotationType)));
|
||||
}
|
||||
return (A) findCache.get(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A extends Annotation>A findAnnotation(AnnotatedElement element,Class<A> annotationType){
|
||||
if(!element.isAnnotationPresent(annotationType)) {
|
||||
return null;
|
||||
}
|
||||
String key=String.format(findKeyFormat,System.identityHashCode(element),annotationType.getName());
|
||||
if(!findCache.containsKey(key)) {
|
||||
findCache.save(key, resolveAnnotationEnvValue(element.getAnnotation(annotationType)));
|
||||
}
|
||||
return (A) findCache.get(key);
|
||||
}
|
||||
|
||||
private static <A extends Annotation>A resolveAnnotationEnvValue(A annotation) {
|
||||
Map<String, Object> values=AnnotationUtils.getAnnotationAttributes(annotation);
|
||||
if(values!=null) {
|
||||
Set<Entry<String, Object>> vs= values.entrySet();
|
||||
for (Entry<String, Object> entry : vs) {
|
||||
values.put(entry.getKey(),parseValue(entry.getValue()));
|
||||
}
|
||||
}
|
||||
changeValues(annotation, values);
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String,Object> getValues(Annotation annotation){
|
||||
String key=String.format(handlerKeyFormat,annotation.getClass().getName(),System.identityHashCode(annotation));
|
||||
if(!handlerCache.containsKey(key)) {
|
||||
handlerCache.save(key, Proxy.getInvocationHandler(annotation));
|
||||
}
|
||||
InvocationHandler invocationHandler =handlerCache.get(key);
|
||||
try {
|
||||
Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
|
||||
declaredField.setAccessible(true);
|
||||
return (Map<String, Object>) declaredField.get(invocationHandler);
|
||||
} catch (Exception e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void changeValue(Annotation annotation,String name,Object value) {
|
||||
Map<String, Object> values = getValues(annotation);
|
||||
if(values!=null) {
|
||||
values.put(name,value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void changeValues(Annotation annotation,Map<String,Object> attrs) {
|
||||
Map<String, Object> values = getValues(annotation);
|
||||
if(values!=null) {
|
||||
values.putAll(attrs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Object parseValue(Object val) {
|
||||
if(environment==null) {
|
||||
return val;
|
||||
}
|
||||
if(val!=null && val instanceof String && RegexUtils.has(val.toString())) {
|
||||
String strVal=val.toString();
|
||||
List<String> names=RegexUtils.findPlaceholder(strVal);
|
||||
String[] values=new String[names.size()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String key=names.get(i);
|
||||
String[] keys=key.split(":");
|
||||
if(keys.length==2) {
|
||||
if(environment.containsProperty(keys[0])) {
|
||||
values[i]=environment.getProperty(keys[0]);
|
||||
}else {
|
||||
values[i]=keys[1];
|
||||
}
|
||||
}else {
|
||||
values[i] = environment.getProperty(key);
|
||||
}
|
||||
}
|
||||
return RegexUtils.replacePlaceholder(strVal, values);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
SpringAnnotationUtils.environment=environment;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* @Description springbean 工具类型
|
||||
* @author zhangfucai
|
||||
* @Date 2023年6月29日 下午3:47:01
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class SpringTools implements ApplicationContextAware,EnvironmentAware{
|
||||
|
||||
public static final String CONFIG_KEY_APPLICATION = "spring.application.name";
|
||||
|
||||
public static final String CONFIG_KEY_PROFILE = "spring.profiles.active";
|
||||
|
||||
public static final String CONFIG_PROD_VALUE = "prod";
|
||||
|
||||
private static ApplicationContext context;
|
||||
|
||||
private static Environment environment;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
SpringTools.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
SpringTools.environment = environment;
|
||||
}
|
||||
|
||||
|
||||
public static ConfigurableApplicationContext logStarter(Class<?> appClass,String[] args) {
|
||||
long start = System.currentTimeMillis();
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(appClass);
|
||||
return logStarter(start, builder.headless(false).run(args));
|
||||
}
|
||||
|
||||
public static ConfigurableApplicationContext logStarter(long start,ConfigurableApplicationContext context) {
|
||||
ConfigurableEnvironment env = context.getEnvironment();
|
||||
Integer _port = env.getProperty("server.port",int.class);
|
||||
int port = _port==null?8080:_port.intValue();
|
||||
String profile = env.getProperty(CONFIG_KEY_PROFILE,"dev");
|
||||
Map<String,String> values = new HashMap<String, String>();
|
||||
ServerProperties server = context.getBean(ServerProperties.class);
|
||||
String path = getContextPath(server.getServlet().getContextPath());
|
||||
String portPath = port==80?"":":"+port;
|
||||
values.put("${serverName}", env.getProperty(CONFIG_KEY_APPLICATION));
|
||||
values.put("${profiles}", profile);
|
||||
values.put("${time}",String.valueOf((System.currentTimeMillis()-start)/1000));
|
||||
values.put("${url}", "http://localhost"+portPath+path);
|
||||
printBanner(values);
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param values
|
||||
*/
|
||||
private static void printBanner(Map<String, String> values) {
|
||||
ScanFile.scan("t-banner.txt",new ScanFileFilter() {
|
||||
|
||||
private boolean ready = false;
|
||||
|
||||
@Override
|
||||
public void accept(InputStream in) {
|
||||
if(!ready) {
|
||||
ready = true;
|
||||
}else {
|
||||
return;
|
||||
}
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(in));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
for (String key : values.keySet()) {
|
||||
line = line.replace(key, values.get(key));
|
||||
}
|
||||
System.out.println(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}finally {
|
||||
IoUtils.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String getLocalIp() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException("获取本地ip异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getContextPath(String path) {
|
||||
if(!StringUtils.isEmpty(path)) {
|
||||
if(!path.startsWith("/")) {
|
||||
path = "/"+path;
|
||||
}
|
||||
if(path.endsWith("/")) {
|
||||
path = path.substring(0,path.length()-1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public static <T>T getBean(Class<T> clazz){
|
||||
return context.getBean(clazz);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>T getBean(String name){
|
||||
if(context.containsBean(name)) {
|
||||
return (T) context.getBean(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T>Map<String, T> getBeansOfType(Class<T> clazz){
|
||||
return context.getBeansOfType(clazz);
|
||||
}
|
||||
|
||||
public static <T>List<T> getBeans(Class<T> clazz){
|
||||
return getBeans(clazz, false);
|
||||
}
|
||||
|
||||
public static <T>List<T> getBeans(Class<T> clazz,boolean sort){
|
||||
List<T> beans = CollectionUtils.newArrayList();
|
||||
Map<String, T> maps = getBeansOfType(clazz);
|
||||
if(maps!=null && maps.isEmpty()==false) {
|
||||
beans = new ArrayList<T>(maps.values());
|
||||
if(sort) AnnotationAwareOrderComparator.sort(beans);
|
||||
}
|
||||
return beans;
|
||||
}
|
||||
|
||||
public static <T>T getProperty(String key,Class<T> targetType,T defaultValue) {
|
||||
return environment.getProperty(key, targetType, defaultValue);
|
||||
}
|
||||
|
||||
public static <T>T getProperty(String key,Class<T> targetType) {
|
||||
return environment.getProperty(key, targetType);
|
||||
}
|
||||
|
||||
public static String getProperty(String key) {
|
||||
return environment.getProperty(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
private StringUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String str) {
|
||||
if(str==null || "".equals(str.trim())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(String str) {
|
||||
return !isEmpty(str);
|
||||
}
|
||||
|
||||
public static String parseBytes(byte[] data,Charset charset) {
|
||||
return new String(data, charset);
|
||||
}
|
||||
|
||||
|
||||
public static String parseStream(InputStream in,Charset charset) throws IOException {
|
||||
return parseStream(new InputStreamReader(in, charset));
|
||||
}
|
||||
|
||||
public static String parseStream(Reader reader) throws IOException {
|
||||
try {
|
||||
StringBuilder source = new StringBuilder();
|
||||
BufferedReader buffered = new BufferedReader(reader);
|
||||
String line = buffered.readLine();
|
||||
|
||||
while (line != null) {
|
||||
source.append(line);
|
||||
source.append('\n');
|
||||
line = buffered.readLine();
|
||||
}
|
||||
return source.toString();
|
||||
} finally {
|
||||
IoUtils.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] toBytes(String str,Charset charset) {
|
||||
if(str==null) {
|
||||
return null;
|
||||
}
|
||||
return str.getBytes(charset);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream toInputStream(String str,Charset charset) {
|
||||
return new ByteArrayInputStream(toBytes(str,charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰命名的字符串转为下划线
|
||||
* */
|
||||
public static String convertHump(String str) {
|
||||
StringBuilder result=new StringBuilder();
|
||||
char[] chars=str.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
if(Character.isUpperCase(chars[i])) {
|
||||
if(i>0) {
|
||||
result.append('_');
|
||||
}
|
||||
result.append(Character.toLowerCase(chars[i]));
|
||||
continue;
|
||||
}
|
||||
result.append(chars[i]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String excludeEmpty(String val,String defVal) {
|
||||
if(isEmpty(val)) {
|
||||
return defVal;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public static String format(String str,Object... args) {
|
||||
if(str!=null && args !=null && args.length > 0) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
Object item = args[i];
|
||||
str = str.replace("{"+i+"}",item!=null?item.toString():"");
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String opt(String val,String defVal) {
|
||||
if(isEmpty(val)) {
|
||||
return defVal;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public static boolean eq(String val,String secondVal) {
|
||||
if(val==null && secondVal==null) {
|
||||
return true;
|
||||
}
|
||||
if(val!=null) {
|
||||
return val.equals(secondVal);
|
||||
}
|
||||
return secondVal.equals(val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 支持序列化的 Function
|
||||
*
|
||||
* @author miemie
|
||||
* @since 2018-05-12
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TFunction<T, R> extends Function<T, R>, Serializable {
|
||||
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
package com.pictc.utils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Description TODO(这里用一句话描述这个类的作用)
|
||||
* @author zhangfucai
|
||||
* @Date 2022年11月7日 下午11:30:00
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Getter
|
||||
public class TypeInfo {
|
||||
|
||||
private Type type;
|
||||
|
||||
private Class<?> klass;
|
||||
|
||||
private Type[] generics;
|
||||
|
||||
public TypeInfo(Type type) {
|
||||
super();
|
||||
this.type = type;
|
||||
if(type instanceof Class) {
|
||||
klass = (Class<?>)type;
|
||||
List<Type> types = CollectionUtils.newArrayList();
|
||||
addGenerics(types, klass.getGenericSuperclass());
|
||||
Type[] itypes = klass.getGenericInterfaces();
|
||||
if(itypes!=null) {
|
||||
for (int i = 0; i < itypes.length; i++) {
|
||||
addGenerics(types, itypes[i]);
|
||||
}
|
||||
}
|
||||
generics = ArrayUtils.ofCollection(types);
|
||||
}else if(type instanceof ParameterizedType) {
|
||||
ParameterizedType gtype = ((ParameterizedType)type);
|
||||
klass = (Class<?>) gtype.getRawType();
|
||||
generics = gtype.getActualTypeArguments();
|
||||
}
|
||||
}
|
||||
|
||||
private void addGenerics(List<Type> types,Type stype) {
|
||||
if(stype!=null && stype instanceof ParameterizedType) {
|
||||
ParameterizedType gtype = ((ParameterizedType)stype);
|
||||
Type[] sgs = gtype.getActualTypeArguments();
|
||||
if(sgs!=null) {
|
||||
for (Type _t : sgs) {
|
||||
types.add(_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeInfo valueOf(Type type) {
|
||||
return new TypeInfo(type);
|
||||
}
|
||||
|
||||
public boolean isGenerics() {
|
||||
return generics!=null;
|
||||
}
|
||||
|
||||
public Type getGenericType(int index) {
|
||||
if(!isGenerics()) {
|
||||
throw new RuntimeException("不是泛型,无法获取泛型类型");
|
||||
}
|
||||
return generics[index];
|
||||
}
|
||||
|
||||
public Type getCollectionType() {
|
||||
if(!isGenerics()) {
|
||||
throw new RuntimeException("不是泛型,无法获取泛型类型");
|
||||
}
|
||||
return generics[0];
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return klass.isArray();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return klass.isInterface();
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return ClassUtils.isPrimitive(klass);
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return klass.isEnum();
|
||||
}
|
||||
|
||||
public boolean isCollection() {
|
||||
return ClassUtils.isCollection(klass);
|
||||
}
|
||||
|
||||
public boolean isList() {
|
||||
return ClassUtils.isList(klass);
|
||||
}
|
||||
|
||||
public boolean isSet() {
|
||||
return ClassUtils.isSet(klass);
|
||||
}
|
||||
|
||||
public boolean isMap() {
|
||||
return ClassUtils.isMap(klass);
|
||||
}
|
||||
|
||||
public Class<?> getArrayType(){
|
||||
return klass.getComponentType();
|
||||
}
|
||||
|
||||
public <T>Collection<T> newCollection(){
|
||||
return isList()?newList():newSet();
|
||||
}
|
||||
|
||||
public <T>List<T> newList(){
|
||||
return ListUtils.getMapNewInstance(ListUtils.parseType(klass));
|
||||
}
|
||||
|
||||
public <T>Set<T> newSet(){
|
||||
return SetUtils.getMapNewInstance(SetUtils.parseType(klass));
|
||||
}
|
||||
|
||||
public <K,V>Map<K,V> newMap(){
|
||||
return MapUtils.getMapNewInstance(MapUtils.parseMapType(klass));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("Class:[%s],泛型:%s", klass.getName(),Arrays.toString(generics));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.xjrsoft.common;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.pictc.utils.DataLogTools;
|
||||
|
||||
@Service
|
||||
public class CommonEnhancedService {
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public <T>T insert(T entity) {
|
||||
return DataLogTools.insert(entity);
|
||||
}
|
||||
|
||||
|
||||
public <T>T updateById(T entity) {
|
||||
return DataLogTools.update(entity);
|
||||
}
|
||||
|
||||
public <T>T delete(T entity) {
|
||||
return DataLogTools.delete(entity);
|
||||
}
|
||||
|
||||
public <T>T deleteById(Class<T> klazz,long id) {
|
||||
return DataLogTools.deleteById(klazz, id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
package com.xjrsoft.module.datalog.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.pictc.common.mybatis.JsonTypeHandler;
|
||||
import com.xjrsoft.module.datalog.entity.json.FieldChange;
|
||||
import com.xjrsoft.module.datalog.vo.OperationType;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 数据变更日志实体类
|
||||
* 用于记录数据库字段修改和实体删除操作
|
||||
*/
|
||||
@ApiModel(value = "DataChangeLog对象", description = "数据变更日志")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataChangeLog implements Serializable{
|
||||
|
||||
/**
|
||||
* @Fields {todo}(用一句话描述这个变量表示什么)
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 日志ID(主键)
|
||||
*/
|
||||
@ApiModelProperty("主键")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 日志ID(主键)
|
||||
*/
|
||||
@ApiModelProperty("流水id")
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 父表ID,根节点#
|
||||
*/
|
||||
@ApiModelProperty("父表ID")
|
||||
private String pid = "#";
|
||||
|
||||
/**
|
||||
* 实体类名称(全类名)
|
||||
*/
|
||||
@ApiModelProperty("实体类名称(全类名)")
|
||||
private String entityClassName;
|
||||
|
||||
/**
|
||||
* 实体类简称(简单类名)
|
||||
*/
|
||||
@ApiModelProperty("业务名称")
|
||||
private String busName;
|
||||
|
||||
/**
|
||||
* 操作的实体ID(主键值)
|
||||
*/
|
||||
@ApiModelProperty("操作的实体ID(主键值)")
|
||||
private Long entityId;
|
||||
|
||||
/**
|
||||
* 字段变更详情
|
||||
* key: 字段名
|
||||
* value: 包含旧值和新值的Map
|
||||
*/
|
||||
@TableField(typeHandler = JsonTypeHandler.class)
|
||||
@ApiModelProperty("属性值记录")
|
||||
private List<FieldChange> fieldChanges = new ArrayList<FieldChange>();
|
||||
|
||||
/**
|
||||
* 操作类型:INSERT-新增,UPDATE-修改,DELETE-删除
|
||||
*/
|
||||
@ApiModelProperty("操作类型:INSERT-新增,UPDATE-修改,DELETE-删除")
|
||||
private OperationType operationType;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
@ApiModelProperty("操作人ID")
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
@ApiModelProperty("操作人姓名")
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
@ApiModelProperty("操作时间")
|
||||
private LocalDateTime operationTime;
|
||||
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
@ApiModelProperty("操作IP地址")
|
||||
private String operationIp;
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否有字段变更
|
||||
*/
|
||||
public boolean hasFieldChanges() {
|
||||
return !this.fieldChanges.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public void addFiledChnage(FieldChange change) {
|
||||
fieldChanges.add(change);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package com.xjrsoft.module.datalog.entity.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel(value = "FieldChange对象", description = "数据变更字段记录")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class FieldChange implements Serializable{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@ApiModelProperty("属性名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("属性")
|
||||
private String field;
|
||||
|
||||
/**
|
||||
* 旧值
|
||||
*/
|
||||
@ApiModelProperty("旧值")
|
||||
private String oldValue;
|
||||
|
||||
/**
|
||||
* 新值
|
||||
*/
|
||||
@ApiModelProperty("新值")
|
||||
private String newValue;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.xjrsoft.module.datalog.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.xjrsoft.module.datalog.entity.DataChangeLog;
|
||||
|
||||
public interface DatalogService {
|
||||
|
||||
public <T>T insert(T entity);
|
||||
|
||||
public <T>List<T> insertBatch(List<T> entity);
|
||||
|
||||
public <T>boolean updateById(T entity);
|
||||
|
||||
public <T>T delete(T entity);
|
||||
|
||||
public <T>T deleteById(Class<T> klazz,long id);
|
||||
|
||||
public <T>List<DataChangeLog> findByEntityId(Class<T> klazz,long id);
|
||||
|
||||
public <T>boolean deleteByIds(Class<T> class1, @Valid List<Long> ids);
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.xjrsoft.module.datalog.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.pictc.jdbc.model.ParamQueryBo;
|
||||
import com.pictc.jdbc.model.QueryParameter;
|
||||
|
||||
public interface QueryService {
|
||||
|
||||
public JSONArray queryList(QueryParameter param);
|
||||
|
||||
public IPage<JSONObject> queryPage(QueryParameter param);
|
||||
|
||||
public JSONArray queryParamsList(ParamQueryBo param);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.xjrsoft.module.datalog.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.google.api.client.util.Lists;
|
||||
import com.pictc.utils.DataLogTools;
|
||||
import com.xjrsoft.module.datalog.entity.DataChangeLog;
|
||||
import com.xjrsoft.module.datalog.service.DatalogService;
|
||||
|
||||
@Service
|
||||
public class DatalogServiceImpl implements DatalogService{
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> T insert(T entity) {
|
||||
return DataLogTools.insert(entity);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> List<T> insertBatch(List<T> entitys) {
|
||||
List<T> res = Lists.newArrayList();
|
||||
for (T entity : entitys) {
|
||||
res.add(DataLogTools.insert(entity));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> boolean updateById(T entity) {
|
||||
DataLogTools.update(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> T delete(T entity) {
|
||||
return DataLogTools.delete(entity);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> T deleteById(Class<T> klazz, long id) {
|
||||
return DataLogTools.deleteById(klazz, id);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public <T> boolean deleteByIds(Class<T> class1, @Valid List<Long> ids) {
|
||||
return DataLogTools.deleteByIds(class1, ids);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Override
|
||||
public <T> List<DataChangeLog> findByEntityId(Class<T> klazz, long dataId) {
|
||||
return DataLogTools.findLogsByEntityId(klazz, dataId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.xjrsoft.module.datalog.service.impl;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.pictc.jdbc.JdbcTools;
|
||||
import com.pictc.jdbc.SqlBuilder;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.pictc.jdbc.model.ParamItem;
|
||||
import com.pictc.jdbc.model.ParamQueryBo;
|
||||
import com.pictc.jdbc.model.QueryParameter;
|
||||
import com.pictc.utils.ListUtils;
|
||||
import com.xjrsoft.module.datalog.service.QueryService;
|
||||
|
||||
@Service
|
||||
public class QueryServiceImpl implements QueryService{
|
||||
|
||||
public static final String SQL_FIND_SQL = "select sql from lng_sql_rpt where id = ?";
|
||||
|
||||
public String getQuerySql(String queryId) {
|
||||
String sql= JdbcTools.queryPrimitive(SQL_FIND_SQL,String.class,ListUtils.ofArray(JdbcParam.of(Types.VARCHAR, String.class, queryId)));
|
||||
if(sql.contains("call")) {
|
||||
return sql;
|
||||
}
|
||||
return "SELECT * FROM ("+sql+") t";
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public JSONArray queryList(QueryParameter param) {
|
||||
return JdbcTools.query(getQuerySql(param.getQueryId()),param);
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public IPage<JSONObject> queryPage(QueryParameter param) {
|
||||
return JdbcTools.queryPage(getQuerySql(param.getQueryId()), param);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public JSONArray queryParamsList(ParamQueryBo param) {
|
||||
SqlBuilder sql = new SqlBuilder();
|
||||
sql.append(getQuerySql(param.getQueryId()));
|
||||
List<ParamItem> params2 = param.getParams();
|
||||
List<JdbcParam> params = new ArrayList<JdbcParam>();
|
||||
if(params2!=null && !params2.isEmpty()) {
|
||||
for (ParamItem item : params2) {
|
||||
params.add(item.toParam());
|
||||
}
|
||||
}
|
||||
return JdbcTools.queryArray(sql.toString(), params);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
# src/main/resources/META-INF/spring.factories
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.pictc.config.PcitcAutoConfig,\
|
||||
com.pictc.config.JdbcConfig
|
||||
@ -0,0 +1 @@
|
||||
component=com.pictc
|
||||
@ -0,0 +1,9 @@
|
||||
|
||||
███████ ██████ ██ ██████████ ██████
|
||||
░██░░░░██ ██░░░░██░██░░░░░██░░░ ██░░░░██
|
||||
░██ ░██ ██ ░░ ░██ ░██ ██ ░░ 服务名称:${serverName}
|
||||
░███████ ░██ ░██ ░██ ░██ 启动环境:${profiles}
|
||||
░██░░░░ ░██ ░██ ░██ ░██ 启动耗时:${time}s
|
||||
░██ ░░██ ██░██ ░██ ░░██ ██ 访问地址:${url}
|
||||
░██ ░░██████ ░██ ░██ ░░██████
|
||||
░░ ░░░░░░ ░░ ░░ ░░░░░░
|
||||
Reference in New Issue
Block a user