Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(关系): 优化固定值的判断 #313

Merged
merged 8 commits into from
Jun 6, 2023
Prev Previous commit
Next Next commit
feat(查询条件): 添加设备查询条件构造器 (#260)
  • Loading branch information
bestfeng1020 authored Apr 7, 2023
commit b7dffda0bc50dad03ecb5cf265b1c6b970b86dd8
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.jetlinks.community.device.service.term;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
* 根据产品分类查询与产品关联的数据,如: 查询某个分类下的产品列表.
* <p>
* <b>
* 注意: 查询时指定列名是和产品ID关联的列或者实体类属性名.
* 如: 查询设备列表时则使用productId.
* 此条件仅支持关系型数据库中的查询.
* </b>
* <p>
* 在通用查询接口中可以使用动态查询参数中的<code>term.termType</code>来使用此功能.
* <a href="https://doc.jetlinks.cn/interface-guide/query-param.html">查看动态查询参数说明</a>
* <p>
* 在内部通用条件中,可以使用DSL方式创建条件,例如:
* <pre>
* createQuery()
* .where()
* .and("productId","dev-prod-cat",cateId)
* .fetch()
* </pre>
*
* @author zhouhao
* @since 1.3
*/
@Component
public class DeviceCategoryTerm extends AbstractTermFragmentBuilder {

public DeviceCategoryTerm() {
super("dev-prod-cat", "按产品品类查询");
}

@Override
public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {

PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();

List<Object> idList = convertList(column, term);

sqlFragments.addSql("exists(select 1 from dev_product prod where prod.id =", columnFullName);

sqlFragments.addSql("and exists(select 1 from dev_product_category g where g.id = prod.classified_id and ");
sqlFragments.addSql(
idList
.stream()
.map(r -> "path like (select concat(path,'%') from dev_product_category g2 where g2.id = ?)")
.collect(Collectors.joining(" or ", "(", ")"))
, ")")
.addParameter(idList);

sqlFragments.addSql(")");

return sqlFragments;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.jetlinks.community.device.service.term;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.*;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.jetlinks.community.utils.ConverterUtils;
import org.springframework.stereotype.Component;

import java.util.List;


/**
* 根据设备查询.
* <p>
* 将设备信息的条件嵌套到此条件中
* <p>
* <pre>
* "terms": [
* {
* "column": "device_id$dev-instance",
* "value": [
* {
* "column": "product_id",
* "termType": "eq",
* "value": "1"
* }
* ]
* }
* ],
* </pre>
*
* @author zhouhao
* @since 1.6
*/
@Component
public class DeviceInstanceTerm extends AbstractTermFragmentBuilder {

public static final String termType = "dev-instance";

public DeviceInstanceTerm() {
super(termType, "根据设备信息查询");
}

@Override
public SqlFragments createFragments(String columnFullName,
RDBColumnMetadata column,
Term term) {
List<Term> terms = ConverterUtils.convertTerms(term.getValue());
PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
if (term.getOptions().contains("not")) {
sqlFragments.addSql("not");
}
sqlFragments.addSql("exists(select 1 from ", getTableName("dev_device_instance", column), " _dev where _dev.id = ", columnFullName);

RDBTableMetadata metadata = column
.getOwner()
.getSchema()
.getTable("dev_device_instance")
.orElseThrow(() -> new UnsupportedOperationException("unsupported dev_device_instance"));

SqlFragments where = builder.createTermFragments(metadata, terms);
if (!where.isEmpty()) {
sqlFragments.addSql("and")
.addFragments(where);
}
sqlFragments.addSql(")");
return sqlFragments;
}


static DeviceTermsBuilder builder = new DeviceTermsBuilder();

static class DeviceTermsBuilder extends AbstractTermsFragmentBuilder<TableOrViewMetadata> {

@Override
protected SqlFragments createTermFragments(TableOrViewMetadata parameter,
List<Term> terms) {
return super.createTermFragments(parameter, terms);
}

@Override
protected SqlFragments createTermFragments(TableOrViewMetadata table,
Term term) {
if (term.getValue() instanceof NativeSql) {
NativeSql sql = ((NativeSql) term.getValue());
return PrepareSqlFragments.of(sql.getSql(), sql.getParameters());
}
return table
.getColumn(term.getColumn())
.flatMap(column -> table
.findFeature(TermFragmentBuilder.createFeatureId(term.getTermType()))
.map(termFragment -> termFragment.createFragments(column.getFullName("_dev"), column, term)))
.orElse(EmptySqlFragments.INSTANCE);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.jetlinks.community.device.service.term;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.*;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.jetlinks.community.utils.ConverterUtils;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* 根据设备产品信息查询设备数据
*
* @author bestfeng
* @since 2.0
*/
@Component
public class DeviceProductInfoTermBuilder extends AbstractTermFragmentBuilder {

public static final String termType = "product-info";

public DeviceProductInfoTermBuilder() {
super(termType, "根据产品信息查询设备数据");
}


@SuppressWarnings("all")
public static List<Term> convertTerms(Object value) {
return ConverterUtils.convertTerms(value);
}


@Override
public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {
List<Term> terms = convertTerms(term.getValue());
PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
if(term.getOptions().contains("not")){
sqlFragments.addSql("not");
}
sqlFragments
.addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = ", columnFullName);

RDBTableMetadata metadata = column
.getOwner()
.getSchema()
.getTable("dev_product")
.orElseThrow(() -> new UnsupportedOperationException("unsupported dev_product"));

SqlFragments where = builder.createTermFragments(metadata, terms);
if (!where.isEmpty()) {
sqlFragments.addSql("and")
.addFragments(where);
}
sqlFragments.addSql(")");
return sqlFragments;
}


static ProductTermBuilder builder = new ProductTermBuilder();

static class ProductTermBuilder extends AbstractTermsFragmentBuilder<TableOrViewMetadata> {

@Override
protected SqlFragments createTermFragments(TableOrViewMetadata parameter, List<Term> terms) {
return super.createTermFragments(parameter, terms);
}

@Override
protected SqlFragments createTermFragments(TableOrViewMetadata table, Term term) {
if (term.getValue() instanceof NativeSql) {
NativeSql sql = ((NativeSql) term.getValue());
return PrepareSqlFragments.of(sql.getSql(), sql.getParameters());
}
return table
.getColumn(term.getColumn())
.flatMap(column -> table
.findFeature(TermFragmentBuilder.createFeatureId(term.getTermType()))
.map(termFragment -> termFragment.createFragments(column.getFullName("_product"), column, term)))
.orElse(EmptySqlFragments.INSTANCE);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.jetlinks.community.device.service.term;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.springframework.stereotype.Component;

import java.util.List;


@Component
public class DeviceProtocolTerm extends AbstractTermFragmentBuilder {
public DeviceProtocolTerm() {
super("dev-protocol", "按协议查询设备");
}

@Override
public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {
PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
List<Object> idList = convertList(column, term);
if (term.getOptions().contains("not")) {
sqlFragments.addSql("not");
}
sqlFragments
.addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = " + columnFullName);
sqlFragments
.addSql(" and _product.message_protocol = ?");
sqlFragments.addSql(")").addParameter(idList);

return sqlFragments;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.jetlinks.community.device.service.term;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;


@Component
public class DeviceTypeTerm extends AbstractTermFragmentBuilder {
public DeviceTypeTerm() {
super("dev-device-type", "按设备类型查询设备");
}

@Override
public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {
PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
List<Object> idList = convertList(column, term);
if (term.getOptions().contains("not")) {
sqlFragments.addSql("not");
}
sqlFragments
.addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = " + columnFullName);
sqlFragments
.addSql(" and _product.device_type in(");
sqlFragments.addSql(idList.stream().map(str -> "?").collect(Collectors.joining(",")))
.addParameter(idList)
.addSql("))");

return sqlFragments;
}
}