Skip to content

Commit

Permalink
refactor: 优化构造SQL性能
Browse files Browse the repository at this point in the history
自定义条件时, 建议根据情况使用 `BatchSqlFragments`或者`SqlFragments#single,of` 或者 `SimpleSqlFragments.of`
  • Loading branch information
zhou-hao committed May 24, 2024
1 parent d77de93 commit ca2bb19
Show file tree
Hide file tree
Showing 48 changed files with 1,144 additions and 567 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.hswebframework.ezorm.core.FeatureType;

import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand Down
6 changes: 6 additions & 0 deletions hsweb-easy-orm-rdb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.0-jre</version>
</dependency>

</dependencies>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.hswebframework.ezorm.rdb.metadata;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
Expand Down Expand Up @@ -76,6 +77,19 @@ public AbstractTableOrViewMetadata() {

}

@Setter(AccessLevel.PRIVATE)
private String quoteName, fullName;

@Override
public String getQuoteName() {
return quoteName == null ? quoteName = TableOrViewMetadata.super.getQuoteName() : quoteName;
}

@Override
public String getFullName() {
return fullName == null ? fullName = TableOrViewMetadata.super.getFullName() : fullName;
}

public boolean isTable() {
return this instanceof RDBTableMetadata;
}
Expand Down Expand Up @@ -110,25 +124,25 @@ public void addColumn(RDBColumnMetadata column) {
@Override
public List<RDBColumnMetadata> getColumns() {
return new ArrayList<>(allColumns
.values()
.stream()
.sorted()
.collect(Collectors.toMap(RDBColumnMetadata::getName, Function.identity(), (_1, _2) -> _1, LinkedHashMap::new))
.values());
.values()
.stream()
.sorted()
.collect(Collectors.toMap(RDBColumnMetadata::getName, Function.identity(), (_1, _2) -> _1, LinkedHashMap::new))
.values());
}

@Override
public List<RDBColumnMetadata> findColumns() {
return allColumns
.values()
.values()
.stream()
.flatMap(c -> getForeignKey()
.stream()
.flatMap(c -> getForeignKey()
.stream()
.map(ForeignKeyMetadata::getTarget)
.map(TableOrViewMetadata::getColumns)
.flatMap(Collection::stream))
.sorted()
.collect(Collectors.toList());
.map(ForeignKeyMetadata::getTarget)
.map(TableOrViewMetadata::getColumns)
.flatMap(Collection::stream))
.sorted()
.collect(Collectors.toList());
}

@Override
Expand All @@ -142,9 +156,9 @@ public Optional<RDBColumnMetadata> getColumn(String name) {
@Override
public Optional<RDBColumnMetadata> findColumn(String name) {
return ofNullable(name)
.map(this::getColumn)
.filter(Optional::isPresent)
.orElseGet(() -> findNestColumn(name));
.map(this::getColumn)
.filter(Optional::isPresent)
.orElseGet(() -> findNestColumn(name));
}

private Optional<RDBColumnMetadata> findNestColumn(String name) {
Expand Down Expand Up @@ -183,9 +197,9 @@ public ForeignKeyMetadata addForeignKey(ForeignKeyBuilder builder) {
private Optional<RDBColumnMetadata> findColumnFromSchema(RDBSchemaMetadata schema, String tableName, String column) {
return of(schema.getTableOrView(tableName)
.flatMap(meta -> meta.getColumn(column)))
.filter(Optional::isPresent)
.orElseGet(() -> getForeignKey(tableName) //查找外键关联信息
.flatMap(key -> key.getTarget().getColumn(column)));
.filter(Optional::isPresent)
.orElseGet(() -> getForeignKey(tableName) //查找外键关联信息
.flatMap(key -> key.getTarget().getColumn(column)));
}

@Override
Expand All @@ -196,9 +210,9 @@ public List<ForeignKeyMetadata> getForeignKeys() {
@Override
public Optional<ForeignKeyMetadata> getForeignKey(String targetName) {
return foreignKey
.stream()
.filter(key -> key.getTarget().equalsNameOrAlias(targetName) || key.equalsNameOrAlias(targetName))
.findFirst();
.stream()
.filter(key -> key.getTarget().equalsNameOrAlias(targetName) || key.equalsNameOrAlias(targetName))
.findFirst();
}

public void addFeature(Feature feature) {
Expand All @@ -208,7 +222,7 @@ public void addFeature(Feature feature) {
@Override
public Dialect getDialect() {
return getSchema()
.getDialect();
.getDialect();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,23 @@ public class RDBColumnMetadata extends AbstractColumnMetadata implements ColumnM
*/
private String previousName;

@Setter(AccessLevel.PRIVATE)
private String quoteName, fullName, fullTableName;

public String getFullName() {
return fullName == null ? fullName = createFullName0(getOwner().getName()) : fullName;
}

public String getFullTableName() {
return fullTableName == null ? fullTableName = createFullName0(getOwner().getFullName()) : fullTableName;
}

public Dialect getDialect() {
return getOwner().getDialect();
}

public String getQuoteName() {
return getDialect().quote(getName());
return quoteName == null ? quoteName = getDialect().quote(getName()) : quoteName;
}

public void setJdbcType(SQLType jdbcType, Class<?> javaType) {
Expand Down Expand Up @@ -254,21 +264,20 @@ public List<Feature> findFeatures(Predicate<Feature> predicate) {
.collect(Collectors.toList());
}

public String createFullName0(String ownerName) {
return getDialect().buildColumnFullName(ownerName, getName());
}

public String getFullName(String ownerName) {
if (ownerName == null || ownerName.isEmpty()) {
ownerName = getOwner().getName();
}
if (Objects.equals(ownerName, getOwner().getName())) {
return getFullName();
}
return getDialect().buildColumnFullName(ownerName, getName());
}

public String getFullName() {
return getFullName(getOwner().getName());
}

public String getFullTableName() {
return getFullName(getOwner().getFullName());
}

public boolean ddlModifiable(RDBColumnMetadata after) {
if (!this.getName().equals(this.getPreviousName())) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,8 @@ protected Optional<SqlFragments> orderBy(QueryOperatorParameter parameter, Table
}

protected SqlFragments from(TableOrViewMetadata metadata, QueryOperatorParameter parameter) {
return PrepareSqlFragments
.of()
.addSql("from")
.addSql(metadata.getFullName())
.addSql(parameter.getFromAlias());
return SqlFragments
.of("from", metadata.getFullName(), parameter.getFromAlias());
}

protected Optional<SqlFragments> groupBy(QueryOperatorParameter parameter, TableOrViewMetadata metadata) {
Expand All @@ -75,7 +72,7 @@ protected Optional<SqlFragments> groupBy(QueryOperatorParameter parameter, Table
for (SelectColumn column : groupBy) {
if (column instanceof NativeSql) {
sql.addSql(((NativeSql) column).getSql())
.addParameter(((NativeSql) column).getParameters());
.addParameter(((NativeSql) column).getParameters());
} else {
RDBColumnMetadata columnMetadata = metadata
.getColumn(column.getColumn())
Expand All @@ -102,11 +99,17 @@ protected Optional<SqlFragments> groupBy(QueryOperatorParameter parameter, Table
return Optional.of(sql);
}

protected static final SqlFragments SELECT = SqlFragments.single("select");
protected static final SqlFragments WHERE = SqlFragments.single("where");
protected static final SqlFragments GROUP_BY = SqlFragments.single("group by");
protected static final SqlFragments ORDER_BY = SqlFragments.single("order by");
protected static final SqlFragments FOR_UPDATE = SqlFragments.single("for update");


protected SqlRequest build(TableOrViewMetadata metadata, QueryOperatorParameter parameter) {
BlockSqlFragments fragments = BlockSqlFragments.of();

fragments.addBlock(FragmentBlock.before, "select");
fragments.addBlock(FragmentBlock.before, SELECT);

fragments.addBlock(FragmentBlock.selectColumn, select(parameter, metadata)
.orElseGet(() -> PrepareSqlFragments.of().addSql("*")));
Expand All @@ -120,23 +123,23 @@ protected SqlRequest build(TableOrViewMetadata metadata, QueryOperatorParameter

where(parameter, metadata)
.ifPresent(where ->
fragments.addBlock(FragmentBlock.where, "where")
fragments.addBlock(FragmentBlock.where, WHERE)
.addBlock(FragmentBlock.where, where));

//group by
groupBy(parameter, metadata)
.ifPresent(groupBy ->
fragments.addBlock(FragmentBlock.groupBy, "group by")
fragments.addBlock(FragmentBlock.groupBy, GROUP_BY)
.addBlock(FragmentBlock.groupBy, groupBy));
//having

//order by
orderBy(parameter, metadata)
.ifPresent(order -> fragments.addBlock(FragmentBlock.orderBy, "order by")
.ifPresent(order -> fragments.addBlock(FragmentBlock.orderBy, ORDER_BY)
.addBlock(FragmentBlock.orderBy, order));

if (Boolean.TRUE.equals(parameter.getForUpdate())) {
fragments.addBlock(FragmentBlock.after, PrepareSqlFragments.of().addSql("for update"));
fragments.addBlock(FragmentBlock.after, FOR_UPDATE);
}
//分页
else if (parameter.getPageIndex() != null && parameter.getPageSize() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.hswebframework.ezorm.rdb.operator.builder.FragmentBlock;
import org.hswebframework.ezorm.rdb.utils.PropertiesUtils;

import java.util.Collections;
import java.util.List;

/**
Expand Down Expand Up @@ -46,10 +47,9 @@ private BlockSqlFragments createBlockFragments(T parameter, List<Term> terms) {
index++;
SqlFragments termFragments;
if (term instanceof SqlTerm) {
termFragments = PrepareSqlFragments
.of()
.addSql(((SqlTerm) term).getSql())
.addParameter(PropertiesUtils.convertList(term.getValue()));
termFragments = SimpleSqlFragments
.of(Collections.singletonList(((SqlTerm) term).getSql()),
PropertiesUtils.convertList(term.getValue()));
} else {
termFragments = term.getValue() == null ? EmptySqlFragments.INSTANCE : createTermFragments(parameter, term);
}
Expand Down Expand Up @@ -78,9 +78,9 @@ private BlockSqlFragments createBlockFragments(T parameter, List<Term> terms) {
if (termAvailable || lastTermAvailable) {
nestBlock.addBlock(FragmentBlock.before, term.getType().name());
}
nestBlock.addBlock(FragmentBlock.before, "(");
nestBlock.addBlock(FragmentBlock.before, SqlFragments.LEFT_BRACKET);
nestBlock.addBlock(FragmentBlock.term, nestFragments);
nestBlock.addBlock(FragmentBlock.after, ")");
nestBlock.addBlock(FragmentBlock.after, SqlFragments.RIGHT_BRACKET);

fragments.addBlock(FragmentBlock.term, nestBlock);
lastTermAvailable = true;
Expand All @@ -102,8 +102,8 @@ private BlockSqlFragments createBlockFragments(T parameter, List<Term> terms) {
* @return BlockSqlFragments
* @see PrepareSqlFragments
*/
private PrepareSqlFragments createPrepareFragments(T parameter, List<Term> terms) {
PrepareSqlFragments fragments = PrepareSqlFragments.of();
private SqlFragments createPrepareFragments(T parameter, List<Term> terms) {
BatchSqlFragments fragments = new BatchSqlFragments(terms.size() * 2, terms.size());

int index = 0;
boolean termAvailable;
Expand All @@ -113,10 +113,9 @@ private PrepareSqlFragments createPrepareFragments(T parameter, List<Term> terms
SqlFragments termFragments;
//原生SQL
if (term instanceof SqlTerm) {
termFragments = PrepareSqlFragments
.of()
.addSql(((SqlTerm) term).getSql())
.addParameter(PropertiesUtils.convertList(term.getValue()));
termFragments = SimpleSqlFragments
.of(Collections.singletonList(((SqlTerm) term).getSql()),
PropertiesUtils.convertList(term.getValue()));
} else {
//值为null时忽略条件
termFragments = term.getValue() == null ? EmptySqlFragments.INSTANCE : createTermFragments(parameter, term);
Expand All @@ -126,9 +125,11 @@ private PrepareSqlFragments createPrepareFragments(T parameter, List<Term> terms
if (termAvailable) {
if (index != 1 && lastTermAvailable) {
//and or
fragments.addSql(term.getType().name());
fragments.add(term.getType() == Term.Type.and
? SqlFragments.AND
: SqlFragments.OR);
}
fragments.addFragments(termFragments);
fragments.add(termFragments);
lastTermAvailable = termAvailable;
}

Expand All @@ -140,11 +141,13 @@ private PrepareSqlFragments createPrepareFragments(T parameter, List<Term> terms
if (nestFragments.isNotEmpty()) {
//and or
if (termAvailable || lastTermAvailable) {
fragments.addSql(term.getType().name());
fragments.add(term.getType() == Term.Type.and
? SqlFragments.AND
: SqlFragments.OR);
}
fragments.addSql("(");
fragments.addFragments(nestFragments);
fragments.addSql(")");
fragments.add(SqlFragments.LEFT_BRACKET);
fragments.add(nestFragments);
fragments.add(SqlFragments.RIGHT_BRACKET);
lastTermAvailable = true;
continue;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.hswebframework.ezorm.rdb.operator.builder.fragments;

import java.util.Collection;

public interface AppendableSqlFragments extends SqlFragments {

AppendableSqlFragments addSql(String... sql);

AppendableSqlFragments addSql(Collection<String> sql);

AppendableSqlFragments addParameter(Object... parameter);

AppendableSqlFragments addParameter(Collection<?> parameter);

AppendableSqlFragments addFragments(SqlFragments fragments);

default AppendableSqlFragments add(SqlFragments fragments) {
return addFragments(fragments);
}

}
Loading

0 comments on commit ca2bb19

Please sign in to comment.