Skip to content

Commit

Permalink
fix: fix issue #4
Browse files Browse the repository at this point in the history
Fix when the column of db naming is not standard snake case,the sql query parse error.
  • Loading branch information
huangxiaohu committed Jun 18, 2022
1 parent af7a490 commit 6b86771
Show file tree
Hide file tree
Showing 26 changed files with 607 additions and 103 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ Maven Project
<dependency>
<groupId>com.sondertara</groupId>
<artifactId>joya</artifactId>
<version>0.0.7.209</version>
<version>0.1.1</version>
</dependency>
```

Gradle Project

```groovy
implementation 'com.sondertara:joya:0.0.7.209'
implementation 'com.sondertara:joya:0.1.1'
```

### 2.添加配置
Expand Down
12 changes: 10 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ allprojects {
def isRelease = false

group = 'com.sondertara'
version = '0.0.7.209'
version = '0.1.1'
archivesBaseName = 'joya'
sourceCompatibility = '1.8'

Expand Down Expand Up @@ -75,8 +75,16 @@ dependencies {
implementation 'com.sondertara:common-tara:0.1.0'
compileOnly 'org.projectlombok:lombok:1.18.24'
compileOnly 'com.oracle.database.jdbc:ojdbc8:21.5.0.0'

annotationProcessor 'org.projectlombok:lombok:1.18.24'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'

}

test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}


Expand Down
4 changes: 2 additions & 2 deletions docs/quick_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Maven Project
<dependency>
<groupId>com.sondertara</groupId>
<artifactId>joya</artifactId>
<version>0.0.7.209</version>
<version>0.1.1</version>
</dependency>
```

Gradle Project

```groovy
implementation 'com.sondertara:joya:0.0.7.209'
implementation 'com.sondertara:joya:0.1.1'
```

## 新项目集成 :id=new_project
Expand Down
237 changes: 237 additions & 0 deletions src/main/java/com/sondertara/joya/cache/TableClassCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package com.sondertara.joya.cache;

import com.google.common.collect.Maps;
import com.sondertara.common.exception.TaraException;
import com.sondertara.common.util.StringUtils;
import com.sondertara.joya.core.model.TableEntity;
import com.sondertara.joya.utils.cache.GuavaAbstractLoadingCache;
import com.sondertara.joya.utils.cache.ILocalCache;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;

/**
* @author skydu
*/
public class TableClassCache extends GuavaAbstractLoadingCache<Class<?>, Map<String, Field>> implements ILocalCache<Class<?>, Map<String, Field>> {

private static volatile TableClassCache cache = null;

private TableClassCache() {
setMaximumSize(1000);
setExpireAfterWriteDuration(60 * 60);
}


public synchronized static TableClassCache getInstance() {
if (null == cache) {
synchronized (TableClassCache.class) {
if (null == cache) {
cache = new TableClassCache();
}
}
}
return cache;
}

/**
* @return get current classloader
*/
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = TableClassCache.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with
// null...
}
}
}
return cl;
}

/**
* 获取类的所有字段(包括父类的)
*
* @param clazz class
* @return field
*/
public static Map<String, Field> getAllFields(Class<?> clazz) {
Map<String, Field> fields = Maps.newLinkedHashMap();
Set<String> filedNames = new HashSet<>();
for (Class<?> c = clazz; c != Object.class; c = c.getSuperclass()) {
try {
Field[] list = c.getDeclaredFields();
for (Field field : list) {
String name = field.getName();
if (filedNames.contains(name)) {
continue;
}
filedNames.add(field.getName());
fields.put(field.getName(), field);
}
} catch (Exception e) {
throw new TaraException(e);
}
}
return fields;
}


/**
* 获取一个实体类对应数据库字段
*
* @param bean java pojo
* @param <T> the class type of bean
* @return the table data
*/
public <T> TableEntity getTable(T bean, boolean readData) {
Map<String, Object> filedNames = new LinkedHashMap<>();
Map<String, String> relation = Maps.newHashMap();
Class<?> clazz = bean.getClass();
Table table = clazz.getAnnotation(Table.class);
String tableName = null;
if (null != table) {
tableName = table.name();
} else {
Entity entity = clazz.getAnnotation(Entity.class);
if (null != entity) {
tableName = entity.name();
}
}
if (null == tableName) {
throw new TaraException("No [@Table] or [@Entity] annotation found for class->" + clazz);
}
TableEntity tableDTO = new TableEntity();
tableDTO.setTableName(tableName);
Optional<Map<String, Field>> optional = get(clazz);
return optional.map(fields -> {
for (Field field : fields.values()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (field.isAnnotationPresent(Transient.class) || field.isAnnotationPresent(org.springframework.data.annotation.Transient.class)) {
continue;
}
String name = field.getName();
name = StringUtils.toUnderlineCase(name);
Column column = field.getAnnotation(Column.class);
if (null != column) {
name = column.name();
}
Id id = field.getAnnotation(Id.class);
if (null != id) {
tableDTO.setPrimaryKey(name);
tableDTO.setPrimaryKeyType(field.getType());
}
if (filedNames.containsKey(name)) {
continue;
}
if (readData) {
try {
Object o;
if (field.isAccessible()) {
o = field.get(bean);
} else {
field.setAccessible(true);
o = field.get(bean);
field.setAccessible(false);
}
filedNames.put(name, o);
} catch (Exception e) {
e.printStackTrace();
}
}
relation.put(name, field.getName());

}
tableDTO.setData(filedNames);
tableDTO.setRelation(relation);
return tableDTO;
}).orElseThrow(() -> new TaraException("Get Class definition error"));

}

/**
* @param clazz
* @return the super class
*/
public static Class<?> getSuperClassGenricType(Class<?> clazz) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
if (genType instanceof Class) {
return getSuperClassGenricType((Class<?>) genType);
}
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (params.length == 0) {
return Object.class;
}
return (Class<?>) params[0];
}


/**
* @param clazz the class
* @param fieldName field name
* @return the current Field
*/
public static Field getField(Class<?> clazz, String fieldName) {
Map<String, Field> map = getAllFields(clazz);
return map.get(fieldName);
}

public static Class<?> classForName(String name) throws ClassNotFoundException {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
return classLoader.loadClass(name);
}
} catch (Throwable ignore) {
}
return Class.forName(name);
}

@Override
protected Map<String, Field> fetchData(Class<?> key) {
return getAllFields(key);
}

@Override
public Optional<Map<String, Field>> get(Class<?> key) {
try {
return Optional.ofNullable(getValue(key));
} catch (ExecutionException e) {
throw new TaraException(e);
}
}

@Override
public void remove(Class<?> key) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public interface SelectBuilder {
/**
* sql select part
* <p>
* this function will query all columns (select *),you can use {@link #specificS} together to assign alias
* this function will query all columns (select *),you can use {@link #wrapColumn(String...)} together to assign alias
* <p>
* 查询表的全部列,对于联表查询 如果字段名字有重复,只保留前面一个字段,可以配置specificS来指定字段别名
*
Expand All @@ -43,7 +43,7 @@ public interface SelectBuilder {
* @param selectFields the special column,usually is the column alias
* @return this builder
*/
SelectBuilder specificS(String... selectFields);
SelectBuilder wrapColumn(String... selectFields);

/**
* select single column
Expand Down Expand Up @@ -117,7 +117,7 @@ public interface SelectBuilder {
<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> FromBuilder select(TaraFunction<T1, ?> f1, TaraFunction<T2, ?> f2, TaraFunction<T3, ?> f3, TaraFunction<T4, ?> f4, TaraFunction<T5, ?> f5, TaraFunction<T6, ?> f6, TaraFunction<T7, ?> f7, TaraFunction<T8, ?> f8, TaraFunction<T9, ?> f9, TaraFunction<T10, ?> f10, TaraFunction<T11, ?> f11, TaraFunction<T12, ?> f12);

/**
* the lambda select, use {@link #specificS(String...)} the resolve alias
* the lambda select, use {@link #wrapColumn(String...)} (String...)} the resolve alias
* lambda select 同样冲突字段需要调用specificS()
*
* @param func select field
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,4 @@ public interface WhereBuilder extends ExtPartBuilder {
*/
ExtPartBuilder where(UnaryOperator<WhereCriterion> func, boolean linkOr);

/**
* where 字段追加 一般用于特殊sql,如联表查询条件、特殊sql处理
* 指定字段的别名
*
* @param whereFields 特殊字段
* @return this builder
*/
WhereBuilder specificW(String... whereFields);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public List<TableStruct> load() {
}
field.setAccessible(true);
Column fieldAnnotation = field.getAnnotation(Column.class);
String columnName = Optional.ofNullable(fieldAnnotation).map(f -> StringUtils.toLowerCase(f.name())).orElse(StringUtils.toUnderlineCase(field.getName()));
String columnName = Optional.ofNullable(fieldAnnotation).map(f -> StringUtils.isBlank(f.name()) ? StringUtils.toUnderlineCase(field.getName()) : StringUtils.toLowerCase(f.name())).orElse(StringUtils.toUnderlineCase(field.getName()));
fieldNames.put(field.getName(), columnName);
field.setAccessible(false);
}
Expand Down
Loading

0 comments on commit 6b86771

Please sign in to comment.