mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-06-03 11:24:34 +08:00
refactor: 优化原生sql查询解析逻辑
This commit is contained in:
@@ -4,6 +4,8 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
|
||||
import org.hswebframework.ezorm.rdb.mapping.defaults.DefaultReactiveRepository;
|
||||
import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
|
||||
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
|
||||
import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -11,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
@Getter
|
||||
@Setter
|
||||
public class ReactiveRepositoryFactoryBean<E, PK>
|
||||
implements FactoryBean<ReactiveRepository<E, PK>> {
|
||||
implements FactoryBean<ReactiveRepository<E, PK>> {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperator operator;
|
||||
@@ -26,11 +28,13 @@ public class ReactiveRepositoryFactoryBean<E, PK>
|
||||
|
||||
@Override
|
||||
public ReactiveRepository<E, PK> getObject() {
|
||||
|
||||
return new DefaultReactiveRepository<>(operator,
|
||||
resolver.resolve(entityType),
|
||||
entityType,
|
||||
wrapperFactory.getWrapper(entityType));
|
||||
RDBTableMetadata table = resolver.resolve(entityType);
|
||||
String tableName = table.getName();
|
||||
return new DefaultReactiveRepository<>(
|
||||
operator,
|
||||
tableName,
|
||||
entityType,
|
||||
wrapperFactory.getWrapper(entityType));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -256,7 +256,7 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
} else {
|
||||
schemaMetadata = database.getMetadata().getCurrentSchema();
|
||||
if (!virtualTable.containsKey(name)) {
|
||||
tableName.setSchemaName(schemaMetadata.getName());
|
||||
tableName.setSchemaName(schemaMetadata.getQuoteName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
if (tableMetadata == null) {
|
||||
throw new IllegalStateException("table or view " + tableName.getName() + " not found in " + schemaMetadata.getName());
|
||||
}
|
||||
|
||||
tableName.setName(tableMetadata.getRealName());
|
||||
QueryAnalyzer.Table table = new QueryAnalyzer.Table(
|
||||
parsePlainName(alias),
|
||||
tableMetadata
|
||||
@@ -339,6 +339,7 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
}
|
||||
|
||||
view.setName(name);
|
||||
view.setRealName(name);
|
||||
view.setSchema(database.getMetadata().getCurrentSchema());
|
||||
view.setAlias(name);
|
||||
|
||||
@@ -403,7 +404,7 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
String alias = table == select.table ? column.getAlias() : table.alias + "." + column.getAlias();
|
||||
|
||||
container.add(new QueryAnalyzer.Column(
|
||||
column.getName(),
|
||||
column.getRealName(),
|
||||
alias,
|
||||
table.alias,
|
||||
column
|
||||
@@ -519,7 +520,7 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
throw new IllegalStateException("column [" + column.getColumnName() + "] not found in " + table.metadata.getName());
|
||||
}
|
||||
|
||||
select.columnList.add(new QueryAnalyzer.Column(metadata.getName(), aliasName, table.alias, metadata));
|
||||
select.columnList.add(new QueryAnalyzer.Column(metadata.getRealName(), aliasName, table.alias, metadata));
|
||||
|
||||
|
||||
}
|
||||
@@ -670,13 +671,15 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
metadata = table.metadata;
|
||||
}
|
||||
|
||||
String colName = col.metadata != null ? col.metadata.getName() : col.name;
|
||||
Column _col = col;
|
||||
Table _table = table;
|
||||
String colName = col.metadata != null ? col.metadata.getRealName() : col.name;
|
||||
String fullName = col.metadata != null
|
||||
? col.getMetadata().getFullName(table.alias)
|
||||
: table.alias + "." + dialect.quote(colName, false);
|
||||
|
||||
return metadata
|
||||
.findFeature(createFeatureId(term.getTermType()))
|
||||
.map(feature -> feature.createFragments(
|
||||
_table.alias + "." + dialect.quote(colName, _col.metadata != null), _col.metadata, term))
|
||||
fullName, col.metadata, term))
|
||||
.orElse(EmptySqlFragments.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -727,7 +730,9 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
continue;
|
||||
}
|
||||
|
||||
columns.append(column.owner).append('.').append(dialect.quote(column.name, column.metadata != null))
|
||||
columns.append(column.owner)
|
||||
.append('.')
|
||||
.append(dialect.quote(column.name, column.metadata != null && !column.metadata.realNameDetected()))
|
||||
.append(" as ")
|
||||
.append(dialect.quote(column.alias, false));
|
||||
}
|
||||
@@ -839,7 +844,8 @@ class QueryAnalyzerImpl implements FromItemVisitor, SelectItemVisitor, SelectVis
|
||||
|
||||
@Override
|
||||
public void visit(ValuesStatement aThis) {
|
||||
|
||||
PrepareStatementVisitor visitor = new PrepareStatementVisitor();
|
||||
aThis.accept(visitor);
|
||||
}
|
||||
|
||||
public Object[] getPrefixParameters(Object... args) {
|
||||
|
||||
@@ -6,6 +6,8 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.hswebframework.ezorm.core.param.Sort;
|
||||
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
|
||||
import org.hswebframework.ezorm.rdb.executor.SqlRequests;
|
||||
import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
|
||||
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
|
||||
import org.hswebframework.web.crud.entity.EventTestEntity;
|
||||
@@ -34,6 +36,39 @@ class DefaultQueryHelperTest {
|
||||
private DatabaseOperator database;
|
||||
|
||||
|
||||
@Test
|
||||
public void testLoadTable() {
|
||||
database
|
||||
.sql()
|
||||
.reactive()
|
||||
.execute(SqlRequests.of("create table \"NATIVE_TEST\"( " +
|
||||
"\"id\" varchar(32) primary key" +
|
||||
",name varchar(32)" +
|
||||
",\"testName\" varchar(32)" +
|
||||
")"))
|
||||
.as(StepVerifier::create)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
|
||||
DefaultQueryHelper helper = new DefaultQueryHelper(database);
|
||||
|
||||
database
|
||||
.dml()
|
||||
.insert("native_test")
|
||||
.value("id", "test")
|
||||
.value("NAME", "test")
|
||||
.value("testName", "test")
|
||||
.execute()
|
||||
.sync();
|
||||
|
||||
helper.select("select id,name,testName from native_test")
|
||||
.fetch()
|
||||
.doOnNext(System.out::println)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPage() {
|
||||
DefaultQueryHelper helper = new DefaultQueryHelper(database);
|
||||
@@ -97,15 +132,16 @@ class DefaultQueryHelperTest {
|
||||
.execute()
|
||||
.sync();
|
||||
|
||||
helper.select("select name as \"name\",count(1) totalResult from s_test group by name having count(1) > ? ", GroupResult::new, 0)
|
||||
.where(dsl -> dsl
|
||||
.is("age", "31")
|
||||
.orderByAsc(GroupResult::getTotalResult))
|
||||
.fetch()
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
helper
|
||||
.select("select name as \"name\",count(1) totalResult from s_test group by name having count(1) > ? ", GroupResult::new, 0)
|
||||
.where(dsl -> dsl
|
||||
.is("age", "31")
|
||||
.orderByAsc(GroupResult::getTotalResult))
|
||||
.fetch()
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,10 +182,10 @@ class DefaultQueryHelperTest {
|
||||
|
||||
helper.select("select age,count(1) c from ( select *,'1' as x from s_test ) a group by age ", 0)
|
||||
.where(dsl -> dsl
|
||||
.is("x", "1")
|
||||
.is("name", "inner")
|
||||
.is("a.testName", "inner")
|
||||
.is("age", 31))
|
||||
.is("x", "1")
|
||||
.is("name", "inner")
|
||||
.is("a.testName", "inner")
|
||||
.is("age", 31))
|
||||
.fetchPaged(0, 10)
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
@@ -170,12 +206,13 @@ class DefaultQueryHelperTest {
|
||||
.execute()
|
||||
.sync();
|
||||
|
||||
helper.select("select * from s_test t1 join (select * from s_test s where name = ? ) t2 on t2.id = t1.id ", "join_sub")
|
||||
.fetch()
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
helper
|
||||
.select("select * from s_test t1 join (select * from s_test s where name = ? ) t2 on t2.id = t1.id ", "join_sub")
|
||||
.fetch()
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@@ -204,11 +241,11 @@ class DefaultQueryHelperTest {
|
||||
|
||||
DefaultQueryHelper helper = new DefaultQueryHelper(database);
|
||||
QueryParamEntity param = QueryParamEntity
|
||||
.newQuery()
|
||||
.is("e.id", "helper_testNative")
|
||||
.is("t.age", "20")
|
||||
.orderByAsc("t.age")
|
||||
.getParam();
|
||||
.newQuery()
|
||||
.is("e.id", "helper_testNative")
|
||||
.is("t.age", "20")
|
||||
.orderByAsc("t.age")
|
||||
.getParam();
|
||||
|
||||
{
|
||||
Sort sortByValue = new Sort();
|
||||
@@ -225,8 +262,8 @@ class DefaultQueryHelperTest {
|
||||
|
||||
|
||||
helper.select("select t.*,e.*,e.name ename,e.id `x.id` from s_test t " +
|
||||
"left join s_test_event e on e.id = t.id " +
|
||||
"where t.age = ?", 20)
|
||||
"left join s_test_event e on e.id = t.id " +
|
||||
"where t.age = ?", 20)
|
||||
.logger(LoggerFactory.getLogger("org.hswebframework.test.native"))
|
||||
.where(param)
|
||||
.fetchPaged()
|
||||
@@ -236,10 +273,10 @@ class DefaultQueryHelperTest {
|
||||
.verifyComplete();
|
||||
|
||||
helper.select("select id,name from s_test t " +
|
||||
"union all select id,name from s_test_event")
|
||||
"union all select id,name from s_test_event")
|
||||
.where(dsl -> dsl
|
||||
.is("id", "helper_testNative")
|
||||
.orderByAsc("name"))
|
||||
.is("id", "helper_testNative")
|
||||
.orderByAsc("name"))
|
||||
.fetchPaged()
|
||||
.doOnNext(v -> System.out.println(JSON.toJSONString(v, SerializerFeature.PrettyFormat)))
|
||||
.as(StepVerifier::create)
|
||||
@@ -308,10 +345,10 @@ class DefaultQueryHelperTest {
|
||||
.from(TestEntity.class)
|
||||
.leftJoin(EventTestEntity.class,
|
||||
join -> join
|
||||
.alias("e1")
|
||||
.is(EventTestEntity::getId, TestEntity::getId)
|
||||
.alias("e1")
|
||||
.is(EventTestEntity::getId, TestEntity::getId)
|
||||
// .is(EventTestEntity::getName, TestEntity::getId)
|
||||
.notNull(EventTestEntity::getAge))
|
||||
.notNull(EventTestEntity::getAge))
|
||||
// .leftJoin(EventTestEntity.class,
|
||||
// join -> join
|
||||
// .alias("e2")
|
||||
|
||||
@@ -173,7 +173,7 @@ class QueryAnalyzerImplTest {
|
||||
void testValues(){
|
||||
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
|
||||
database,
|
||||
"select * from (values (1,2),(3,4)) t(a,b)");
|
||||
"select * from (values (1,2),(3,4)) t(\"a\",b)");
|
||||
|
||||
SqlRequest request = analyzer
|
||||
.refactor(QueryParamEntity.of().and("a","eq",1),1);
|
||||
|
||||
@@ -114,11 +114,11 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
}
|
||||
}
|
||||
return this == v
|
||||
|| getValue() == v
|
||||
|| Objects.equals(getValue(), v)
|
||||
|| Objects.equals(ordinal(), v)
|
||||
|| String.valueOf(getValue()).equalsIgnoreCase(String.valueOf(v))
|
||||
|| getText().equalsIgnoreCase(String.valueOf(v)
|
||||
|| getValue() == v
|
||||
|| Objects.equals(getValue(), v)
|
||||
|| Objects.equals(ordinal(), v)
|
||||
|| String.valueOf(getValue()).equalsIgnoreCase(String.valueOf(v))
|
||||
|| getText().equalsIgnoreCase(String.valueOf(v)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -183,8 +183,8 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
return Optional.empty();
|
||||
}
|
||||
return find(type, e -> e.getValue() == value || e.getValue().equals(value) || String
|
||||
.valueOf(e.getValue())
|
||||
.equalsIgnoreCase(String.valueOf(value)));
|
||||
.valueOf(e.getValue())
|
||||
.equalsIgnoreCase(String.valueOf(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,9 +358,9 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
if (value instanceof Map) {
|
||||
return (T) EnumDict.find(((Class) type), ((Map) value).get("value"))
|
||||
.orElseGet(() ->
|
||||
EnumDict
|
||||
.find(((Class) type), ((Map) value).get("text"))
|
||||
.orElse(null));
|
||||
EnumDict
|
||||
.find(((Class) type), ((Map) value).get("text"))
|
||||
.orElse(null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,14 +400,14 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
}
|
||||
Supplier<ValidationException> exceptionSupplier = () -> {
|
||||
List<Object> values = Stream
|
||||
.of(findPropertyType.getEnumConstants())
|
||||
.map(Enum.class::cast)
|
||||
.map(e -> {
|
||||
if (e instanceof EnumDict) {
|
||||
return ((EnumDict) e).getValue();
|
||||
}
|
||||
return e.name();
|
||||
}).collect(Collectors.toList());
|
||||
.of(findPropertyType.getEnumConstants())
|
||||
.map(Enum.class::cast)
|
||||
.map(e -> {
|
||||
if (e instanceof EnumDict) {
|
||||
return ((EnumDict) e).getValue();
|
||||
}
|
||||
return e.name();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return new ValidationException(currentName, "validation.parameter_does_not_exist_in_enums", currentName);
|
||||
};
|
||||
@@ -423,38 +423,38 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
}
|
||||
}
|
||||
return (EnumDict) EnumDict
|
||||
.findByValue(findPropertyType, value)
|
||||
.orElseThrow(exceptionSupplier);
|
||||
.findByValue(findPropertyType, value)
|
||||
.orElseThrow(exceptionSupplier);
|
||||
}
|
||||
if (node.isNumber()) {
|
||||
return (EnumDict) EnumDict
|
||||
.find(findPropertyType, node.numberValue())
|
||||
.orElseThrow(exceptionSupplier);
|
||||
.find(findPropertyType, node.numberValue())
|
||||
.orElseThrow(exceptionSupplier);
|
||||
}
|
||||
if (node.isTextual()) {
|
||||
return (EnumDict) EnumDict
|
||||
.find(findPropertyType, node.textValue())
|
||||
.orElseThrow(exceptionSupplier);
|
||||
.find(findPropertyType, node.textValue())
|
||||
.orElseThrow(exceptionSupplier);
|
||||
}
|
||||
return exceptionSupplier.get();
|
||||
}
|
||||
if (findPropertyType.isEnum()) {
|
||||
return Stream
|
||||
.of(findPropertyType.getEnumConstants())
|
||||
.filter(o -> {
|
||||
if (node.isTextual()) {
|
||||
return node.textValue().equalsIgnoreCase(((Enum) o).name());
|
||||
}
|
||||
if (node.isNumber()) {
|
||||
return node.intValue() == ((Enum) o).ordinal();
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.findAny()
|
||||
.orElseThrow(exceptionSupplier);
|
||||
.of(findPropertyType.getEnumConstants())
|
||||
.filter(o -> {
|
||||
if (node.isTextual()) {
|
||||
return node.textValue().equalsIgnoreCase(((Enum) o).name());
|
||||
}
|
||||
if (node.isNumber()) {
|
||||
return node.intValue() == ((Enum) o).ordinal();
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.findAny()
|
||||
.orElseThrow(exceptionSupplier);
|
||||
}
|
||||
|
||||
log.warn("unsupported deserialize enum json : {}", node);
|
||||
log.warn("unsupported deserialize enum json : {} for: {}@{}", node, currentName, currentValue);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -478,9 +478,9 @@ public interface EnumDict<V> extends JSONSerializable, Serializable {
|
||||
*/
|
||||
static EnumDict<String> create(String value, String text) {
|
||||
return DefaultItemDefine
|
||||
.builder()
|
||||
.value(value)
|
||||
.text(text)
|
||||
.build();
|
||||
.builder()
|
||||
.value(value)
|
||||
.text(text)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user