From 90488eb5d879d9340f86b8d91bf4da2300065483 Mon Sep 17 00:00:00 2001 From: Alvari Date: Tue, 28 Jan 2025 13:16:52 +1300 Subject: [PATCH] refactored ParserUtil to use a stringbuilder when concatenating a string within a loop. Also added miussing override annotations to align with codestyle conventions --- .../main/java/io/xream/sqli/builder/QB.java | 993 +++++++++--------- .../java/io/xream/sqli/util/ParserUtil.java | 755 +++++++------ 2 files changed, 885 insertions(+), 863 deletions(-) diff --git a/sqli-builder/src/main/java/io/xream/sqli/builder/QB.java b/sqli-builder/src/main/java/io/xream/sqli/builder/QB.java index 93a95a5..fb91f6d 100644 --- a/sqli-builder/src/main/java/io/xream/sqli/builder/QB.java +++ b/sqli-builder/src/main/java/io/xream/sqli/builder/QB.java @@ -23,7 +23,6 @@ import io.xream.sqli.parser.Parser; import io.xream.sqli.util.BeanUtil; import io.xream.sqli.util.SqliStringUtil; - import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -33,578 +32,608 @@ */ public class QB extends CondBuilder { - private Q q; - private PageBuilder pageBuilder; - protected Froms fromsTemp; + private Q q; + private PageBuilder pageBuilder; + protected Froms fromsTemp; + + public QB routeKey(Object routeKey) { + this.q.setRouteKey(routeKey); + return this; + } - public QB routeKey(Object routeKey) { - this.q.setRouteKey(routeKey); - return this; + public QB paged(Pageable pageable) { + if (this.pageBuilder != null) { + pageable.buildBy(pageBuilder); + return this; } + this.pageBuilder = + new PageBuilder() { - public QB paged(Pageable pageable) { - if (this.pageBuilder != null) { - pageable.buildBy(pageBuilder); + @Override + public PageBuilder ignoreTotalRows() { + q.setTotalRowsIgnored(true); return this; - } - this.pageBuilder = new PageBuilder() { + } - @Override - public PageBuilder ignoreTotalRows() { - q.setTotalRowsIgnored(true); - return this; - } + @Override + public PageBuilder ignoreTotalRows(boolean ignored) { + q.setTotalRowsIgnored(ignored); + return this; + } - @Override - public PageBuilder ignoreTotalRows(boolean ignored) { - q.setTotalRowsIgnored(ignored); - return this; - } + @Override + public PageBuilder rows(int rows) { + q.setRows(rows); + return this; + } - @Override - public PageBuilder rows(int rows) { - q.setRows(rows); - return this; - } + @Override + public PageBuilder page(int page) { + q.setPage(page); + return this; + } - @Override - public PageBuilder page(int page) { - q.setPage(page); - return this; + @Override + public PageBuilder last(long last) { + q.setLast(last); + return this; + } + }; + pageable.buildBy(pageBuilder); + return this; + } + + public QB sortIn(String porperty, List inList) { + if (Objects.nonNull(inList) && inList.size() > 0) { + KV kv = KV.of(porperty, inList); + List fixedSortList = q.getFixedSortList(); + if (fixedSortList == null) { + fixedSortList = new ArrayList<>(); + q.setFixedSortList(fixedSortList); + } + fixedSortList.add(kv); + } + return this; + } + + public QB sort(String orderBy, Direction direction) { + if (SqliStringUtil.isNullOrEmpty(orderBy)) return this; + List sortList = q.getSortList(); + if (sortList == null) { + sortList = new ArrayList<>(); + q.setSortList(sortList); + } + Sort sort = new Sort(orderBy, direction); + sortList.add(sort); + return this; + } + + private QB(Q q) { + super(q.getBbs()); + this.q = q; + } + + public static QB of(Class clz) { + Q q = new Q(); + q.setClzz(clz); + QB QB = new QB(q); + + if (q.getParsed() == null) { + Parsed parsed = Parser.get(clz); + q.setParsed(parsed); + } + + return QB; + } + + public static X x() { + Q.X xq = new Q.X(); + return new X(xq); + } + + public Class getClz() { + return this.q.getClzz(); + } + + protected Q get() { + return this.q; + } + + @Override + public Q build() { + this.q.setAbort(isAbort); + return this.q; + } + + @Override + public QB eq(String property, Object value) { + return (QB) super.eq(property, value); + } + + @Override + public QB gt(String property, Object value) { + return (QB) super.gt(property, value); + } + + @Override + public QB gte(String property, Object value) { + return (QB) super.gte(property, value); + } + + @Override + public QB lt(String property, Object value) { + return (QB) super.lt(property, value); + } + + @Override + public QB lte(String property, Object value) { + return (QB) super.lte(property, value); + } + + @Override + public QB ne(String property, Object value) { + return (QB) super.ne(property, value); + } + + @Override + public QB like(String property, String value) { + return (QB) super.like(property, value); + } + + @Override + public QB likeLeft(String property, String value) { + return (QB) super.likeLeft(property, value); + } + + @Override + public QB notLike(String property, String value) { + return (QB) super.notLike(property, value); + } + + @Override + public QB in(String property, List list) { + return (QB) super.in(property, list); + } + + @Override + public QB inRequired(String property, List list) { + return (QB) super.inRequired(property, list); + } + + @Override + public QB nin(String property, List list) { + return (QB) super.nin(property, list); + } + + @Override + public QB nonNull(String property) { + return (QB) super.nonNull(property); + } + + @Override + public QB isNull(String property) { + return (QB) super.isNull(property); + } + + public QB x(String sqlSegment) { + return (QB) super.x(sqlSegment); + } + + @Override + public QB x(String sqlSegment, Object... values) { + return (QB) super.x(sqlSegment, values); + } + + @Override + public QB and(SubCond sub) { + return (QB) super.and(sub); + } + + @Override + public QB or(SubCond sub) { + return (QB) super.or(sub); + } + + @Override + public QB bool(Bool cond, Then then) { + return (QB) super.bool(cond, then); + } + + @Override + public QB any(Any any) { + return (QB) super.any(any); + } + + @Override + public QB or() { + return (QB) super.or(); + } + + public QB last(String lastSqlSegment) { + this.q.setLastSqlSegment(lastSqlSegment); + return this; + } + + public void clear() { + this.q = null; + } + + public static final class X extends QB { + + private FromBuilder fb = + new FromBuilder() { + + @Override + public FromBuilder of(Class clz) { + return of(clz, null); + } + + @Override + public FromBuilder of(Class clz, String alia) { + if (get().getSourceScripts().isEmpty()) { + sourceScript(); } + fromsTemp.setAlia(alia); + fromsTemp.setSource(BeanUtil.getByFirstLower(clz.getSimpleName())); + return this; + } + + @Override + public FromBuilder sub(Sub sub, String alia) { + sourceScript(); + fromsTemp.setAlia(alia); + + X subBuilder = QB.x(); + sub.buildBy(subBuilder); + Q.X xq = subBuilder.build(); + fromsTemp.setSubQ(xq); + subBuilder.clear(); + return this; + } - @Override - public PageBuilder last(long last) { - q.setLast(last); - return this; - } + @Override + public FromBuilder with(Sub sub, String alia) { + sub(sub, alia); + fromsTemp.setWith(true); + return this; + } + @Override + public FromBuilder JOIN(JoinType joinType) { + sourceScript(); + JOIN join = JOIN(); + join.setJoin(joinType); + return this; + } - }; - pageable.buildBy(pageBuilder); - return this; - } + @Override + public FromBuilder JOIN(String joinStr) { + sourceScript(); + JOIN join = JOIN(); + join.setJoin(joinStr); + return this; + } + + @Override + public FromBuilder on(String onSql) { + + return on(onSql, null); + } - public QB sortIn(String porperty, List inList) { - if (Objects.nonNull(inList) && inList.size() > 0) { - KV kv = KV.of(porperty, inList); - List fixedSortList = q.getFixedSortList(); - if (fixedSortList == null) { - fixedSortList = new ArrayList<>(); - q.setFixedSortList(fixedSortList); + @Override + public FromBuilder on(String onSql, On on) { + + JOIN join = JOIN(); + ON onE = join.getOn(); + if (onE == null) { + + onE = new ON(); + join.setOn(onE); + CondBuilder cb = new CondBuilder(onE.getBbs()); + onE.setBuilder(cb); + onE.getBbs().add(Bb.of(Op.NONE, Op.X, onSql, null)); + + if (on != null) { + on.buildBy(cb); + } + } else { + onE.getBbs().add(Bb.of(Op.AND, Op.X, onSql, null)); } - fixedSortList.add(kv); - } - return this; - } - public QB sort(String orderBy, Direction direction) { - if (SqliStringUtil.isNullOrEmpty(orderBy)) return this; - List sortList = q.getSortList(); - if (sortList == null) { - sortList = new ArrayList<>(); - q.setSortList(sortList); - } - Sort sort = new Sort(orderBy, direction); - sortList.add(sort); - return this; - } - - private QB(Q q) { - super(q.getBbs()); - this.q = q; - } + } - public static QB of(Class clz) { - Q q = new Q(); - q.setClzz(clz); - QB QB = new QB(q); + private JOIN JOIN() { + JOIN join = fromsTemp.getJoin(); + if (join == null) { + join = new JOIN(); + fromsTemp.setJoin(join); + } + return join; + } + }; - if (q.getParsed() == null) { - Parsed parsed = Parser.get(clz); - q.setParsed(parsed); - } + private X instance; - return QB; + private void sourceScript() { + fromsTemp = new Froms(); + get().getSourceScripts().add(fromsTemp); } - public static X x() { - Q.X xq = new Q.X(); - return new X(xq); + public X from(Class clz) { + get().setSourceScript(BeanUtil.getByFirstLower(clz.getSimpleName())); + return this; } - public Class getClz() { - return this.q.getClzz(); + public X fromX(FromX x) { + x.buildBy(fb); + return this; } - protected Q get() { - return this.q; + public X withoutOptimization() { + get().setWithoutOptimization(true); + return this; } - public Q build() { - this.q.setAbort(isAbort); - return this.q; + @Override + protected Q.X get() { + return (Q.X) super.get(); } - public QB eq(String property, Object value) { - return (QB) super.eq(property, value); + @Override + public Q.X build() { + return (Q.X) super.build(); } - public QB gt(String property, Object value) { - return (QB) super.gt(property, value); + private X(Q q) { + super(q); + instance = this; } - public QB gte(String property, Object value) { - return (QB) super.gte(property, value); + private X select0(String resultKey) { + if (SqliStringUtil.isNullOrEmpty(resultKey)) return this; + get().getResultKeyList().add(resultKey); + return this; } - public QB lt(String property, Object value) { - return (QB) super.lt(property, value); + public X select(String... resultKeys) { + if (resultKeys == null) return this; + for (String resultKey : resultKeys) { + select0(resultKey); + } + return this; } - public QB lte(String property, Object value) { - return (QB) super.lte(property, value); + /** + * @param resultKey + * @param alia + * @return resultKey set by framework, not alia, (temporaryRepository.findToCreate) + */ + public X selectWithAlia(String resultKey, String alia) { + if (SqliStringUtil.isNullOrEmpty(resultKey)) return this; + Objects.requireNonNull(alia, "resultKeyAssignedAlia(), alia can not null"); + get().getResultKeyAssignedAliaList().add(KV.of(resultKey, alia)); + return this; } - public QB ne(String property, Object value) { - return (QB) super.ne(property, value); + public X resultWithDottedKey() { + get().setResultWithDottedKey(true); + return this; } - public QB like(String property, String value) { - return (QB) super.like(property, value); + /** + * @param functionScript FUNCTION(?,?) + * @param values "test", 1000 + */ + public X selectWithFunc(ResultKeyAlia resultKeyAlia, String functionScript, String... values) { + if (SqliStringUtil.isNullOrEmpty(functionScript) || values == null) return this; + Objects.requireNonNull(resultKeyAlia, "function no alia"); + Objects.requireNonNull(resultKeyAlia.getAlia()); + FunctionResultKey functionResultKey = new FunctionResultKey(); + functionResultKey.setScript(functionScript); + functionResultKey.setAlia(resultKeyAlia.getAlia()); + functionResultKey.setValues(values); + get().getResultFunctionList().add(functionResultKey); + return this; } - public QB likeLeft(String property, String value) { - return (QB) super.likeLeft(property, value); + public X from(String fromSql, Object... vs) { + if (SqliStringUtil.isNullOrEmpty(fromSql)) return this; + fromSql = normalizeSql(fromSql); + get().setSourceScript(fromSql); + get().setSourceScriptValueList(vs); + return this; } - public QB notLike(String property, String value) { - return (QB) super.notLike(property, value); + public X distinct(String... objs) { + if (objs == null) throw new IllegalArgumentException("distinct non resultKey"); + Q.X xq = get(); + Distinct distinct = xq.getDistinct(); + if (Objects.isNull(distinct)) { + distinct = new Distinct(); + xq.setDistinct(distinct); + } + for (String obj : objs) { + distinct.add(obj); + } + return this; } - public QB in(String property, List list) { - return (QB) super.in(property, list); + public X groupBy(String property) { + get().setGroupBy(property); + return this; } - public QB inRequired(String property, List list) { - return (QB) super.inRequired(property, list); + public X xAggr(String function, Object... values) { + List list = get().getAggrList(); + if (list == null) { + list = new ArrayList<>(); + get().setAggrList(list); + } + Bb bb = new Bb(); + bb.setKey(function); + bb.setValue(values); + bb.setP(Op.X_AGGR); + list.add(bb); + return this; } - public QB nin(String property, List list) { - return (QB) super.nin(property, list); + public X having(Having having) { + CondBuilder cb = new CondBuilder(get().getHavingList()); + having.buildBy(cb); + return this; } - public QB nonNull(String property) { - return (QB) super.nonNull(property); + public X reduce(ReduceType type, String property) { + Reduce reduce = new Reduce(); + reduce.setType(type); + reduce.setProperty(property); + get().getReduceList().add(reduce); + return this; } - public QB isNull(String property) { - return (QB) super.isNull(property); + @Override + public X sort(String orderBy, Direction direction) { + return (X) super.sort(orderBy, direction); } - public QB x(String sqlSegment) { - return (QB) super.x(sqlSegment); + /** + * @param type + * @param property + * @param havingBb paged().totalRowsIgnored(true), if isTotalRowsIgnored == false,will throw + * Exception + */ + public X reduce(ReduceType type, String property, Bb havingBb) { + Reduce reduce = new Reduce(); + reduce.setType(type); + reduce.setProperty(property); + reduce.setHaving(havingBb); + get().getReduceList().add(reduce); + return this; } - public QB x(String sqlSegment, Object... values) { - return (QB) super.x(sqlSegment, values); + @Override + public X eq(String property, Object value) { + return (X) super.eq(property, value); } - public QB and(SubCond sub) { - return (QB) super.and(sub); + @Override + public X gt(String property, Object value) { + return (X) super.gt(property, value); } - public QB or(SubCond sub) { - return (QB) super.or(sub); + @Override + public X gte(String property, Object value) { + return (X) super.gte(property, value); } - public QB bool(Bool cond, Then then) { - return (QB) super.bool(cond, then); + @Override + public X lt(String property, Object value) { + return (X) super.lt(property, value); } - public QB any(Any any) { - return (QB)super.any(any); + @Override + public X lte(String property, Object value) { + return (X) super.lte(property, value); } - public QB or() { - return (QB) super.or(); + @Override + public X ne(String property, Object value) { + return (X) super.ne(property, value); } - public QB last(String lastSqlSegment) { - this.q.setLastSqlSegment(lastSqlSegment); - return this; + @Override + public X like(String property, String value) { + return (X) super.like(property, value); } - - public void clear() { - this.q = null; + @Override + public X likeLeft(String property, String value) { + return (X) super.likeLeft(property, value); } + @Override + public X notLike(String property, String value) { + return (X) super.notLike(property, value); + } - public static final class X extends QB { - - private FromBuilder fb = new FromBuilder() { - - @Override - public FromBuilder of(Class clz) { - return of(clz, null); - } - - @Override - public FromBuilder of(Class clz, String alia) { - if (get().getSourceScripts().isEmpty()) { - sourceScript(); - } - fromsTemp.setAlia(alia); - fromsTemp.setSource(BeanUtil.getByFirstLower(clz.getSimpleName())); - return this; - } - - @Override - public FromBuilder sub(Sub sub, String alia) { - sourceScript(); - fromsTemp.setAlia(alia); - - X subBuilder = QB.x(); - sub.buildBy(subBuilder); - Q.X xq = subBuilder.build(); - fromsTemp.setSubQ(xq); - subBuilder.clear(); - return this; - } - - @Override - public FromBuilder with(Sub sub, String alia) { - sub(sub, alia); - fromsTemp.setWith(true); - return this; - } - - @Override - public FromBuilder JOIN(JoinType joinType) { - sourceScript(); - JOIN join = JOIN(); - join.setJoin(joinType); - return this; - } - - @Override - public FromBuilder JOIN(String joinStr) { - sourceScript(); - JOIN join = JOIN(); - join.setJoin(joinStr); - return this; - } - - @Override - public FromBuilder on(String onSql) { - - return on(onSql, null); - } - - @Override - public FromBuilder on(String onSql, On on) { - - JOIN join = JOIN(); - ON onE = join.getOn(); - if (onE == null) { - - onE = new ON(); - join.setOn(onE); - CondBuilder cb = new CondBuilder(onE.getBbs()); - onE.setBuilder(cb); - onE.getBbs().add(Bb.of(Op.NONE,Op.X,onSql,null)); - - if (on != null) { - on.buildBy(cb); - } - }else { - onE.getBbs().add(Bb.of(Op.AND,Op.X,onSql,null)); - } - - - return this; - } - - private JOIN JOIN() { - JOIN join = fromsTemp.getJoin(); - if (join == null) { - join = new JOIN(); - fromsTemp.setJoin(join); - } - return join; - } - }; - - private X instance; - - - private void sourceScript() { - fromsTemp = new Froms(); - get().getSourceScripts().add(fromsTemp); - } - - public X from(Class clz) { - get().setSourceScript(BeanUtil.getByFirstLower(clz.getSimpleName())); - return this; - } - - public X fromX(FromX x) { - x.buildBy(fb); - return this; - } - - public X withoutOptimization() { - get().setWithoutOptimization(true); - return this; - } - - @Override - protected Q.X get() { - return (Q.X) super.get(); - } - - @Override - public Q.X build() { - return (Q.X) super.build(); - } - - private X(Q q) { - super(q); - instance = this; - } - - private X select0(String resultKey) { - if (SqliStringUtil.isNullOrEmpty(resultKey)) - return this; - get().getResultKeyList().add(resultKey); - return this; - } - - - public X select(String... resultKeys) { - if (resultKeys == null) - return this; - for (String resultKey : resultKeys) { - select0(resultKey); - } - return this; - } - - /** - * @param resultKey - * @param alia - * @return resultKey set by framework, not alia, (temporaryRepository.findToCreate) - */ - public X selectWithAlia(String resultKey, String alia) { - if (SqliStringUtil.isNullOrEmpty(resultKey)) - return this; - Objects.requireNonNull(alia, "resultKeyAssignedAlia(), alia can not null"); - get().getResultKeyAssignedAliaList().add(KV.of(resultKey, alia)); - return this; - } - - public X resultWithDottedKey() { - get().setResultWithDottedKey(true); - return this; - } - - /** - * @param functionScript FUNCTION(?,?) - * @param values "test", 1000 - */ - public X selectWithFunc(ResultKeyAlia resultKeyAlia, String functionScript, String... values) { - if (SqliStringUtil.isNullOrEmpty(functionScript) || values == null) - return this; - Objects.requireNonNull(resultKeyAlia, "function no alia"); - Objects.requireNonNull(resultKeyAlia.getAlia()); - FunctionResultKey functionResultKey = new FunctionResultKey(); - functionResultKey.setScript(functionScript); - functionResultKey.setAlia(resultKeyAlia.getAlia()); - functionResultKey.setValues(values); - get().getResultFunctionList().add(functionResultKey); - return this; - } - - public X from(String fromSql, Object... vs) { - if (SqliStringUtil.isNullOrEmpty(fromSql)) - return this; - fromSql = normalizeSql(fromSql); - get().setSourceScript(fromSql); - get().setSourceScriptValueList(vs); - return this; - } - - public X distinct(String... objs) { - if (objs == null) - throw new IllegalArgumentException("distinct non resultKey"); - Q.X xq = get(); - Distinct distinct = xq.getDistinct(); - if (Objects.isNull(distinct)) { - distinct = new Distinct(); - xq.setDistinct(distinct); - } - for (String obj : objs) { - distinct.add(obj); - } - return this; - } - - public X groupBy(String property) { - get().setGroupBy(property); - return this; - } - - public X xAggr(String function, Object... values) { - List list = get().getAggrList(); - if (list == null) { - list = new ArrayList<>(); - get().setAggrList(list); - } - Bb bb = new Bb(); - bb.setKey(function); - bb.setValue(values); - bb.setP(Op.X_AGGR); - list.add(bb); - return this; - } - - public X having(Having having) { - CondBuilder cb = new CondBuilder(get().getHavingList()); - having.buildBy(cb); - return this; - } - - public X reduce(ReduceType type, String property) { - Reduce reduce = new Reduce(); - reduce.setType(type); - reduce.setProperty(property); - get().getReduceList().add(reduce); - return this; - } - - @Override - public X sort(String orderBy, Direction direction) { - return (X) super.sort(orderBy, direction); - } - - /** - * @param type - * @param property - * @param havingBb paged().totalRowsIgnored(true), if isTotalRowsIgnored == false,will throw Exception - */ - public X reduce(ReduceType type, String property, Bb havingBb) { - Reduce reduce = new Reduce(); - reduce.setType(type); - reduce.setProperty(property); - reduce.setHaving(havingBb); - get().getReduceList().add(reduce); - return this; - } - - - public X eq(String property, Object value) { - return (X) super.eq(property, value); - } - - public X gt(String property, Object value) { - return (X) super.gt(property, value); - } - - public X gte(String property, Object value) { - return (X) super.gte(property, value); - } - - public X lt(String property, Object value) { - return (X) super.lt(property, value); - } - - public X lte(String property, Object value) { - return (X) super.lte(property, value); - } - - public X ne(String property, Object value) { - return (X) super.ne(property, value); - } - - public X like(String property, String value) { - return (X) super.like(property, value); - } - - public X likeLeft(String property, String value) { - return (X) super.likeLeft(property, value); - } - - public X notLike(String property, String value) { - return (X) super.notLike(property, value); - } - - public X in(String property, List list) { - return (X) super.in(property, list); - } - - public X inRequired(String property, List list) { - return (X) super.inRequired(property, list); - } - - public X nin(String property, List list) { - return (X) super.nin(property, list); - } - - public X nonNull(String property) { - return (X) super.nonNull(property); - } + @Override + public X in(String property, List list) { + return (X) super.in(property, list); + } - public X isNull(String property) { - return (X) super.isNull(property); - } + @Override + public X inRequired(String property, List list) { + return (X) super.inRequired(property, list); + } - public X x(String sqlSegment) { - return (X) super.x(sqlSegment); - } + @Override + public X nin(String property, List list) { + return (X) super.nin(property, list); + } - public X x(String sqlSegment, Object... values) { - return (X) super.x(sqlSegment, values); - } + @Override + public X nonNull(String property) { + return (X) super.nonNull(property); + } - public X and(SubCond sub) { - return (X) super.and(sub); - } + @Override + public X isNull(String property) { + return (X) super.isNull(property); + } - public X or(SubCond sub) { - return (X) super.or(sub); - } + @Override + public X x(String sqlSegment) { + return (X) super.x(sqlSegment); + } - public X bool(Bool cond, Then then) { - return (X) super.bool(cond, then); - } + @Override + public X x(String sqlSegment, Object... values) { + return (X) super.x(sqlSegment, values); + } - public X any(Any any) { - return (X) super.any(any); - } + @Override + public X and(SubCond sub) { + return (X) super.and(sub); + } + @Override + public X or(SubCond sub) { + return (X) super.or(sub); + } - public X or() { - return (X) super.or(); - } + @Override + public X bool(Bool cond, Then then) { + return (X) super.bool(cond, then); + } - public void clear() { - super.clear(); - } + @Override + public X any(Any any) { + return (X) super.any(any); + } - public X paged(Pageable pageable) { + @Override + public X or() { + return (X) super.or(); + } - super.paged(pageable); + @Override + public void clear() { + super.clear(); + } - return this; - } + @Override + public X paged(Pageable pageable) { - public X last(String lastSqlSegment) { - super.last(lastSqlSegment); - return this; - } + super.paged(pageable); + return this; } + @Override + public X last(String lastSqlSegment) { + super.last(lastSqlSegment); + return this; + } + } } diff --git a/sqli-builder/src/main/java/io/xream/sqli/util/ParserUtil.java b/sqli-builder/src/main/java/io/xream/sqli/util/ParserUtil.java index 98ac4ad..3497fb0 100644 --- a/sqli-builder/src/main/java/io/xream/sqli/util/ParserUtil.java +++ b/sqli-builder/src/main/java/io/xream/sqli/util/ParserUtil.java @@ -24,7 +24,6 @@ import io.xream.sqli.parser.BeanElement; import io.xream.sqli.parser.Parsed; import io.xream.sqli.parser.Parser; - import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -36,458 +35,452 @@ import java.time.LocalDateTime; import java.util.*; - /** * @author Sim */ public final class ParserUtil { - public final static String SQL_KEYWORD_MARK = "`"; + public static final String SQL_KEYWORD_MARK = "`"; - private ParserUtil() { - super(); - } + private ParserUtil() { + super(); + } - private static void parseFieldsOfElementList(Class clz, Map filterMap, Map allMap) { + private static void parseFieldsOfElementList( + Class clz, Map filterMap, Map allMap) { - List fl = new ArrayList<>(); - - if (clz.getSuperclass() != Object.class) { - fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields())); - } - fl.addAll(Arrays.asList(clz.getDeclaredFields())); + List fl = new ArrayList<>(); - /* - * 排除transient - */ - for (Field f : fl) { - allMap.put(f.getName(), f); + if (clz.getSuperclass() != Object.class) { + fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields())); + } + fl.addAll(Arrays.asList(clz.getDeclaredFields())); + + /* + * 排除transient + */ + for (Field f : fl) { + allMap.put(f.getName(), f); + + if (f.getModifiers() >= 128) { + filterMap.put(f.getName(), f); + } + + /* + * ignored anno + */ + X.Ignore p = f.getAnnotation(X.Ignore.class); + if (p != null) { + filterMap.put(f.getName(), f); + } + } + } - if (f.getModifiers() >= 128) { - filterMap.put(f.getName(), f); - } + private static void parseMethodsOfElementList( + Class clz, Set mns, List methodList) { + if (clz.getSuperclass() != Object.class) { + methodList.addAll(Arrays.asList(clz.getSuperclass().getDeclaredMethods())); + } + methodList.addAll(Arrays.asList(clz.getDeclaredMethods())); // 仅仅XxxMapped子类 - /* - * ignored anno - */ - X.Ignore p = f.getAnnotation(X.Ignore.class); - if (p != null) { - filterMap.put(f.getName(), f); + for (Method m : methodList) { + mns.add(m.getName()); + } + } + + private static void parseFilterListOfElementList( + List filterList, Set mns, List ml, Map allMap) { + + for (Method m : ml) { + String name = m.getName(); + if (!(name.startsWith("set") || name.startsWith("get") || name.startsWith("is"))) continue; + + String key = BeanUtil.getProperty(name); + BeanElement be = null; + for (BeanElement b : filterList) { + if (key.startsWith("is")) { + if (!allMap.containsKey(key)) { + String noIs = BeanUtil.getBooleanPropertyNoIs(key); + if (allMap.containsKey(noIs)) { + key = noIs; } + } } - } - - private static void parseMethodsOfElementList(Class clz, Set mns, List methodList) { - if (clz.getSuperclass() != Object.class) { - methodList.addAll(Arrays.asList(clz.getSuperclass().getDeclaredMethods())); + if (b.getProperty().equals(key)) { + be = b; + break; } - methodList.addAll(Arrays.asList(clz.getDeclaredMethods())); // 仅仅XxxMapped子类 - - for (Method m : methodList) { - mns.add(m.getName()); + } + if (be == null) { + be = new BeanElement(); + be.setProperty(key); + filterList.add(be); + } + if (name.startsWith("set")) { + be.setSetter(name); + } else if (name.startsWith("get")) { + be.setGetter(name); + be.setClz(m.getReturnType()); + } else if (name.startsWith("is")) { + be.setGetter(name); + be.setClz(m.getReturnType()); + // be.setProperty(name); + String setter = BeanUtil.getSetter(name); // FIXME 可能有BUG + if (mns.contains(setter)) { + be.setSetter(setter); } + } } - - private static void parseFilterListOfElementList(List filterList, - Set mns, - List ml, - Map allMap) { - - for (Method m : ml) { - String name = m.getName(); - if (!(name.startsWith("set") || name.startsWith("get") || name.startsWith("is"))) - continue; - - String key = BeanUtil.getProperty(name); - BeanElement be = null; - for (BeanElement b : filterList) { - if (key.startsWith("is")){ - if (!allMap.containsKey(key)){ - String noIs = BeanUtil.getBooleanPropertyNoIs(key); - if (allMap.containsKey(noIs)){ - key = noIs; - } - } - } - if (b.getProperty().equals(key)) { - be = b; - break; - } - } - if (be == null) { - be = new BeanElement(); - be.setProperty(key); - filterList.add(be); - } - if (name.startsWith("set")) { - be.setSetter(name); - } else if (name.startsWith("get")) { - be.setGetter(name); - be.setClz(m.getReturnType()); - } else if (name.startsWith("is")) { - be.setGetter(name); - be.setClz(m.getReturnType()); -// be.setProperty(name); - String setter = BeanUtil.getSetter(name); // FIXME 可能有BUG - if (mns.contains(setter)) { - be.setSetter(setter); - } - } - } + } + + private static void filterElementList( + List filterList, Map filterMap) { + /* + * 找出有setter 和 getter的一对 + */ + Iterator ite = filterList.iterator(); + while (ite.hasNext()) { // BUG, 这里去掉了boolen属性 + BeanElement be = ite.next(); + if (!be.isPair()) { + ite.remove(); + } } - private static void filterElementList(List filterList, Map filterMap) { - /* - * 找出有setter 和 getter的一对 - */ - Iterator ite = filterList.iterator(); - while (ite.hasNext()) {// BUG, 这里去掉了boolen属性 - BeanElement be = ite.next(); - if (!be.isPair()) { - ite.remove(); - } - } - - /* - * 去掉transient - */ - for (String key : filterMap.keySet()) { - Iterator beIte = filterList.iterator(); - while (beIte.hasNext()) { - BeanElement be = beIte.next(); - if (be.getProperty().equals(key)) { - beIte.remove(); - break; - } - } + /* + * 去掉transient + */ + for (String key : filterMap.keySet()) { + Iterator beIte = filterList.iterator(); + while (beIte.hasNext()) { + BeanElement be = beIte.next(); + if (be.getProperty().equals(key)) { + beIte.remove(); + break; } + } } - - private static List buildElementList(Class clz, List filterList, Map allMap) { - List list = new ArrayList(); - - for (BeanElement element : filterList) { - - parseAnno(clz, element, allMap.get(element.getProperty())); - - Class ec = element.getClz(); - if (element.getSqlType() == null) { - if (ec == long.class || ec == Long.class) { - element.setSqlType(SqlFieldType.LONG); - element.setLength(13); - } else if (ec == int.class || ec == Integer.class) { - element.setSqlType(SqlFieldType.INT); - element.setLength(11); - } else if (ec == BigInteger.class) { - element.setSqlType(SqlFieldType.BIG_INTEGER); - element.setLength(20); - } else if (ec == double.class || ec == Double.class) { - element.setSqlType(SqlFieldType.DOUBLE); - element.setLength(13); - } else if (ec == float.class || ec == Float.class) { - element.setSqlType(SqlFieldType.FLOAT); - element.setLength(13); - } else if (ec == boolean.class || ec == Boolean.class) { - element.setSqlType(SqlFieldType.BYTE); - element.setLength(1); - } else if (ec == String.class) { - element.setSqlType(SqlFieldType.VARCHAR); - if (element.getLength() == 0) - element.setLength(60); - } else if (ec == BigDecimal.class) { - element.setSqlType(SqlFieldType.DECIMAL); - } else if (ec == LocalDateTime.class || ec == LocalDate.class || ec == Date.class || ec == java.sql.Date.class || ec == Timestamp.class ) { - element.setSqlType(SqlFieldType.DATE); - } else if (EnumUtil.isEnum(ec)) { - element.setSqlType(SqlFieldType.VARCHAR); - if (element.getLength() == 0) - element.setLength(20); - } else { - element.setJson(true); - if (ec == List.class) { - Field field = null; - try { - field = clz.getDeclaredField(element.getProperty()); - } catch (Exception e) { - e.printStackTrace(); - } - ParameterizedType pt = (ParameterizedType) field.getGenericType(); - - Class geneType = (Class) pt.getActualTypeArguments()[0]; - element.setGeneType(geneType); - } - element.setSqlType(SqlFieldType.VARCHAR); - if (element.getLength() == 0) - element.setLength(512); - } - } else if (element.getSqlType().contains(SqlFieldType.TEXT)) { - element.setLength(0); - } else { - element.setSqlType(SqlFieldType.VARCHAR); + } + + private static List buildElementList( + Class clz, List filterList, Map allMap) { + List list = new ArrayList(); + + for (BeanElement element : filterList) { + + parseAnno(clz, element, allMap.get(element.getProperty())); + + Class ec = element.getClz(); + if (element.getSqlType() == null) { + if (ec == long.class || ec == Long.class) { + element.setSqlType(SqlFieldType.LONG); + element.setLength(13); + } else if (ec == int.class || ec == Integer.class) { + element.setSqlType(SqlFieldType.INT); + element.setLength(11); + } else if (ec == BigInteger.class) { + element.setSqlType(SqlFieldType.BIG_INTEGER); + element.setLength(20); + } else if (ec == double.class || ec == Double.class) { + element.setSqlType(SqlFieldType.DOUBLE); + element.setLength(13); + } else if (ec == float.class || ec == Float.class) { + element.setSqlType(SqlFieldType.FLOAT); + element.setLength(13); + } else if (ec == boolean.class || ec == Boolean.class) { + element.setSqlType(SqlFieldType.BYTE); + element.setLength(1); + } else if (ec == String.class) { + element.setSqlType(SqlFieldType.VARCHAR); + if (element.getLength() == 0) element.setLength(60); + } else if (ec == BigDecimal.class) { + element.setSqlType(SqlFieldType.DECIMAL); + } else if (ec == LocalDateTime.class + || ec == LocalDate.class + || ec == Date.class + || ec == java.sql.Date.class + || ec == Timestamp.class) { + element.setSqlType(SqlFieldType.DATE); + } else if (EnumUtil.isEnum(ec)) { + element.setSqlType(SqlFieldType.VARCHAR); + if (element.getLength() == 0) element.setLength(20); + } else { + element.setJson(true); + if (ec == List.class) { + Field field = null; + try { + field = clz.getDeclaredField(element.getProperty()); + } catch (Exception e) { + e.printStackTrace(); } + ParameterizedType pt = (ParameterizedType) field.getGenericType(); - list.add(element); + Class geneType = (Class) pt.getActualTypeArguments()[0]; + element.setGeneType(geneType); + } + element.setSqlType(SqlFieldType.VARCHAR); + if (element.getLength() == 0) element.setLength(512); } - return list; + } else if (element.getSqlType().contains(SqlFieldType.TEXT)) { + element.setLength(0); + } else { + element.setSqlType(SqlFieldType.VARCHAR); + } + + list.add(element); } + return list; + } - private static void initMethodCache(Class clz, List list) { + private static void initMethodCache(Class clz, List list) { + try { + for (BeanElement be : list) { try { - for (BeanElement be : list) { - try { - be.setSetMethod(clz.getDeclaredMethod(be.getSetter(), be.getClz())); - } catch (NoSuchMethodException e) { - be.setSetMethod(clz.getSuperclass().getDeclaredMethod(be.getSetter(), be.getClz())); - } - try { - be.setGetMethod(clz.getDeclaredMethod(be.getGetter())); - } catch (NoSuchMethodException e) { - be.setGetMethod(clz.getSuperclass().getDeclaredMethod(be.getGetter())); - } - } - } catch (Exception e) { - e.printStackTrace(); + be.setSetMethod(clz.getDeclaredMethod(be.getSetter(), be.getClz())); + } catch (NoSuchMethodException e) { + be.setSetMethod(clz.getSuperclass().getDeclaredMethod(be.getSetter(), be.getClz())); + } + try { + be.setGetMethod(clz.getDeclaredMethod(be.getGetter())); + } catch (NoSuchMethodException e) { + be.setGetMethod(clz.getSuperclass().getDeclaredMethod(be.getGetter())); } + } + } catch (Exception e) { + e.printStackTrace(); } + } - @SuppressWarnings("rawtypes") - public static List parseElementList(Class clz) { + @SuppressWarnings("rawtypes") + public static List parseElementList(Class clz) { - Map filterMap = new HashMap<>(); - Map allMap = new HashMap<>(); - parseFieldsOfElementList(clz, filterMap, allMap); //Step 1 + Map filterMap = new HashMap<>(); + Map allMap = new HashMap<>(); + parseFieldsOfElementList(clz, filterMap, allMap); // Step 1 - Set mns = new HashSet<>(); - List ml = new ArrayList<>(); - parseMethodsOfElementList(clz, mns, ml); + Set mns = new HashSet<>(); + List ml = new ArrayList<>(); + parseMethodsOfElementList(clz, mns, ml); + List filterList = new ArrayList<>(); + parseFilterListOfElementList(filterList, mns, ml, allMap); + filterElementList(filterList, filterMap); - List filterList = new ArrayList<>(); - parseFilterListOfElementList(filterList, mns, ml,allMap); - filterElementList(filterList, filterMap); + List list = buildElementList(clz, filterList, allMap); - List list = buildElementList(clz, filterList, allMap); + initMethodCache(clz, list); - initMethodCache(clz, list); + return list; + } - return list; + public static void parseCacheableAnno(Class clz, Parsed parsed) { + X.NoCache p = (X.NoCache) clz.getAnnotation(X.NoCache.class); + if (p != null) { + parsed.setNoCache(true); } + } - public static void parseCacheableAnno(Class clz, Parsed parsed) { - X.NoCache p = (X.NoCache) clz.getAnnotation(X.NoCache.class); - if (p != null) { - parsed.setNoCache(true); - } - } + @SuppressWarnings({"rawtypes", "unchecked"}) + private static void parseAnno(Class clz, BeanElement ele, Field f) { + Method m = null; + try { + m = clz.getDeclaredMethod(ele.getGetter()); + } catch (NoSuchMethodException e) { - @SuppressWarnings({"rawtypes", "unchecked"}) - private static void parseAnno(Class clz, BeanElement ele, Field f) { - - Method m = null; - try { - m = clz.getDeclaredMethod(ele.getGetter()); - } catch (NoSuchMethodException e) { - - } - if (m != null) { - X p = m.getAnnotation(X.class); - if (p != null) { - ele.setLength(p.length()); - } - } - - if (f != null) { - X p = f.getAnnotation(X.class); - if (p != null) { - ele.setLength(p.length()); - } - - X.Mapping mapping = f.getAnnotation(X.Mapping.class); - if (mapping != null && SqliStringUtil.isNotNull(mapping.value())) { - ele.setMapper(mapping.value()); - } + } + if (m != null) { + X p = m.getAnnotation(X.class); + if (p != null) { + ele.setLength(p.length()); + } + } - } + if (f != null) { + X p = f.getAnnotation(X.class); + if (p != null) { + ele.setLength(p.length()); + } + X.Mapping mapping = f.getAnnotation(X.Mapping.class); + if (mapping != null && SqliStringUtil.isNotNull(mapping.value())) { + ele.setMapper(mapping.value()); + } } + } - @SuppressWarnings({"rawtypes"}) - public static void parseKey(Parsed parsed, Class clz) { + @SuppressWarnings({"rawtypes"}) + public static void parseKey(Parsed parsed, Class clz) { - List list = new ArrayList<>(); + List list = new ArrayList<>(); - try { + try { - list.addAll(Arrays.asList(clz.getDeclaredFields())); - Class sc = clz.getSuperclass(); - if (sc != Object.class) { - list.addAll(Arrays.asList(sc.getDeclaredFields())); - } - } catch (Exception e) { + list.addAll(Arrays.asList(clz.getDeclaredFields())); + Class sc = clz.getSuperclass(); + if (sc != Object.class) { + list.addAll(Arrays.asList(sc.getDeclaredFields())); + } + } catch (Exception e) { - } + } - for (Field f : list) { - X.Key a = f.getAnnotation(X.Key.class); - if (a != null) { - f.setAccessible(true); - parsed.setKeyField(f); - break; - }else { - for (Annotation anno :f.getAnnotations()){ - String annoName = anno.annotationType().getName(); - if (annoName.endsWith(".Id") || annoName.endsWith(".ID") || annoName.endsWith(".TableId")){ - f.setAccessible(true); - parsed.setKeyField(f); - break; - } - } - if (SqliStringUtil.isNotNull(parsed.getKey())){ - break; - } - } + for (Field f : list) { + X.Key a = f.getAnnotation(X.Key.class); + if (a != null) { + f.setAccessible(true); + parsed.setKeyField(f); + break; + } else { + for (Annotation anno : f.getAnnotations()) { + String annoName = anno.annotationType().getName(); + if (annoName.endsWith(".Id") + || annoName.endsWith(".ID") + || annoName.endsWith(".TableId")) { + f.setAccessible(true); + parsed.setKeyField(f); + break; + } + } + if (SqliStringUtil.isNotNull(parsed.getKey())) { + break; } + } } + } - public static void parseTagAndSub(Parsed parsed, Class clz) { + public static void parseTagAndSub(Parsed parsed, Class clz) { - List list = new ArrayList<>(); + List list = new ArrayList<>(); - try { - list.addAll(Arrays.asList(clz.getDeclaredFields())); - Class sc = clz.getSuperclass(); - if (sc != Object.class) { - list.addAll(Arrays.asList(sc.getDeclaredFields())); - } - } catch (Exception e) { - - } + try { + list.addAll(Arrays.asList(clz.getDeclaredFields())); + Class sc = clz.getSuperclass(); + if (sc != Object.class) { + list.addAll(Arrays.asList(sc.getDeclaredFields())); + } + } catch (Exception e) { - for (Field f : list) { - X.Tag t = f.getAnnotation(X.Tag.class); - if (t != null) { - f.setAccessible(true); - parsed.getTagFieldList().add(f); - } - X.TagTarget tt = f.getAnnotation(X.TagTarget.class); - if (tt != null) { - f.setAccessible(true); - if (parsed.getTagKeyField() != null) - throw new ParsingException("find another annotation: X.TagTarget, class: " + clz); - parsed.setTagKeyField(f); - } - } } - public static String filterSQLKeyword(String mapper) { - for (String keyWord : SqlScript.KEYWORDS) { - if (keyWord.equalsIgnoreCase(mapper)) { - return SQL_KEYWORD_MARK + mapper + SQL_KEYWORD_MARK; - } - } - return mapper; + for (Field f : list) { + X.Tag t = f.getAnnotation(X.Tag.class); + if (t != null) { + f.setAccessible(true); + parsed.getTagFieldList().add(f); + } + X.TagTarget tt = f.getAnnotation(X.TagTarget.class); + if (tt != null) { + f.setAccessible(true); + if (parsed.getTagKeyField() != null) + throw new ParsingException("find another annotation: X.TagTarget, class: " + clz); + parsed.setTagKeyField(f); + } } + } - public static String getClzName(String alia, Map aliaMap) { - if (aliaMap == null) - throw new ParsingException("QB.of(Class) not support the key contains '.'"); - String a = aliaMap.get(alia); - if (SqliStringUtil.isNotNull(a)) - return a; - return alia; + public static String filterSQLKeyword(String mapper) { + for (String keyWord : SqlScript.KEYWORDS) { + if (keyWord.equalsIgnoreCase(mapper)) { + return SQL_KEYWORD_MARK + mapper + SQL_KEYWORD_MARK; + } } + return mapper; + } - public static Object tryToGetId(T t, Parsed parsed) { + public static String getClzName(String alia, Map aliaMap) { + if (aliaMap == null) + throw new ParsingException("QB.of(Class) not support the key contains '.'"); + String a = aliaMap.get(alia); + if (SqliStringUtil.isNotNull(a)) return a; + return alia; + } - Field f = parsed.getKeyField(); - Object id = null; - try { - id = f.get(t); - } catch (Exception e) { - - } - if (id == null) - throw new IllegalArgumentException("obj keyOne = " + id + ", " + t); - return id; - } + public static Object tryToGetId(T t, Parsed parsed) { - public static String getCacheKey(Object obj, Parsed parsed) { - try { - Object keyOneObj = tryToGetId(obj, parsed); - if (keyOneObj != null) - return keyOneObj.toString(); + Field f = parsed.getKeyField(); + Object id = null; + try { + id = f.get(t); + } catch (Exception e) { - } catch (Exception e) { - } - return null; } + if (id == null) throw new IllegalArgumentException("obj keyOne = " + id + ", " + t); + return id; + } + public static String getCacheKey(Object obj, Parsed parsed) { + try { + Object keyOneObj = tryToGetId(obj, parsed); + if (keyOneObj != null) return keyOneObj.toString(); - public static String getMapper(String property) { - - String AZ = "AZ"; - int min = AZ.charAt(0) - 1; - int max = AZ.charAt(1) + 1; - - try { - String spec = Parser.mappingSpec; - if (SqliStringUtil.isNotNull(spec)) { - char[] arr = property.toCharArray(); - int length = arr.length; - List list = new ArrayList(); - StringBuilder temp = new StringBuilder(); - for (int i = 0; i < length; i++) { - char c = arr[i]; - if (c > min && c < max) { - String ts = temp.toString(); - if (SqliStringUtil.isNotNull(ts)) { - list.add(temp.toString()); - } - temp = new StringBuilder(); - String s = String.valueOf(c); - temp.append(s.toLowerCase()); - } else { - temp = temp.append(c); - } - - if (i == length - 1) { - list.add(temp.toString()); - } - - } - - String str = ""; - - int size = list.size(); - for (int i = 0; i < size; i++) { - String s = list.get(i); - str += s; - if (i < size - 1) { - str += "_"; - } - } - return str; + } catch (Exception e) { + } + return null; + } + + public static String getMapper(String property) { + + String AZ = "AZ"; + int min = AZ.charAt(0) - 1; + int max = AZ.charAt(1) + 1; + + try { + String spec = Parser.mappingSpec; + if (SqliStringUtil.isNotNull(spec)) { + char[] arr = property.toCharArray(); + int length = arr.length; + List list = new ArrayList(); + StringBuilder temp = new StringBuilder(); + for (int i = 0; i < length; i++) { + char c = arr[i]; + if (c > min && c < max) { + String ts = temp.toString(); + if (SqliStringUtil.isNotNull(ts)) { + list.add(temp.toString()); } + temp = new StringBuilder(); + String s = String.valueOf(c); + temp.append(s.toLowerCase()); + } else { + temp = temp.append(c); + } + + if (i == length - 1) { + list.add(temp.toString()); + } + } - } catch (Exception e) { + StringBuilder str = new StringBuilder(); + int size = list.size(); + for (int i = 0; i < size; i++) { + String s = list.get(i); + str.append(s); + if (i < size - 1) { + str.append("_"); + } } - return property; - } - - public interface SqlFieldType { + return str.toString(); + } - String TEXT = "text"; - String VARCHAR = "varchar"; - String DATE = "timestamp"; - String INT = "int"; - String LONG = "bigint"; - String BYTE = "tinyint"; - String DOUBLE = "float";//float - String FLOAT = "float";//real - String DECIMAL = "decimal"; + } catch (Exception e) { - String BIG_INTEGER = "bigint unsigned"; } + return property; + } + + public interface SqlFieldType { + + String TEXT = "text"; + String VARCHAR = "varchar"; + String DATE = "timestamp"; + String INT = "int"; + String LONG = "bigint"; + String BYTE = "tinyint"; + String DOUBLE = "float"; // float + String FLOAT = "float"; // real + String DECIMAL = "decimal"; + + String BIG_INTEGER = "bigint unsigned"; + } }