Java JPA QueryBuilder (自己写的)

QueryBuilder

Class.createQueryBuilder(entityManager, originSql).build()

public static QueryBuilder createQueryBuilder(EntityManager entityManager, String originSql) {
        return new QueryBuilder(entityManager, originSql);
    }

    public static final class QueryBuilder {
        private EntityManager entityManager;
        private String originSql;
        private List queryParamList = new ArrayList<>();
        private List orderParamList = new ArrayList<>();

        private QueryBuilder(EntityManager entityManager, String originSql) {
            this.entityManager = entityManager;
            this.originSql = originSql;
        }

        public QueryBuilder equals(Object obj, String column) {
            QueryParam queryParam = new QueryParam(obj, column, EQUALS);
            queryParamList.add(queryParam);
            return this;
        }

        public QueryBuilder special(boolean when, String sql, String[] paramNames, Object[] values) {
            QueryParam queryParam = new QueryParam(when, sql, paramNames, values);
            queryParamList.add(queryParam);
            return this;
        }

        public QueryBuilder dateRange(DateRangeVO dateRangeVO, String column) {
            String[] paramNames = {"dateFromQ", "dateToQ"};
            Object[] values = {dateRangeVO.getDateFrom(), dateRangeVO.getDateTo()};
            String sql = " and " + column + " between :dateFromQ and :dateToQ ";
            return special(dateRangeVO.getDateFrom() != null && dateRangeVO.getDateTo() != null,
                    sql, paramNames, values);
        }

        public QueryBuilder like(String obj, String column) {
            QueryParam queryParam = new QueryParam(obj, column, LIKE);
            queryParamList.add(queryParam);
            return this;
        }

        public QueryBuilder doubleLike(String obj, String column) {
            QueryParam queryParam = new QueryParam(obj, column, DOUBLE_LIKE);
            queryParamList.add(queryParam);
            return this;
        }

        public QueryBuilder asc(String column, boolean needOrder) {
            QueryParam queryParam = new QueryParam(column, ORDER_ASC);
            if (needOrder) {
                orderParamList.add(queryParam);
            }
            return this;
        }

        public QueryBuilder desc(String column, boolean needOrder) {
            QueryParam queryParam = new QueryParam(column, ORDER_DESC);
            if (needOrder) {
                orderParamList.add(queryParam);
            }
            return this;
        }

        /*
        * to build sql
        */
        public Query build() {
            StringBuilder sqlBuilder = new StringBuilder(originSql);
            for (QueryParam queryParam : queryParamList) {
                // Check multipart condition
                if (queryParam.values != null && queryParam.paramNames != null) {
                    if (queryParam.values.length != queryParam.paramNames.length) {
                        throw new RuntimeException("Cannot build sql, Because the " +
                                "implanted field lengths do not match");
                    }
                    if (queryParam.type.equals(SPECIAL)) {
                        if (queryParam.specialCondition == null) {
                            throw new RuntimeException("Cannot build sql, Because the build type is SPECIAL but" +
                                    " condition is null");
                        }
                        if (queryParam.specialCondition) {
                            sqlBuilder.append(OpsuiConstant.SPACE_STR)
                                    .append(queryParam.sql)
                                    .append(OpsuiConstant.SPACE_STR);
                        }
                    }

                } else {
                    if (queryParam.value instanceof String) {
                        if (StringUtils.isNotEmpty((String) queryParam.value)) {
                            sqlBuilder.append(queryParam.sql);
                        }
                    } else {
                        if (queryParam.value != null) {
                            sqlBuilder.append(queryParam.sql);
                        }
                    }
                }
            }
            if (!orderParamList.isEmpty()) {
                sqlBuilder.append(" order by ");
                for (int i = 0; i < orderParamList.size(); i++) {
                    if (i == orderParamList.size() - 1) {
                        sqlBuilder.append(orderParamList.get(i).sql);
                    } else {
                        sqlBuilder.append(orderParamList.get(i).sql).append(", ");
                    }
                }
            }
            String completeSql = sqlBuilder.toString();
            LOG.info("SQLUtil: the automatic sql is: " + completeSql);
            Query query = entityManager.createNativeQuery(completeSql);
            for (QueryParam queryParam : queryParamList) {
                // setParameter for multipart situation
                if (queryParam.values != null && queryParam.paramNames != null) {
                    if (queryParam.values.length != queryParam.paramNames.length) {
                        throw new RuntimeException("Cannot build sql, Because the " +
                                "implanted field lengths do not match");
                    }
                    if (queryParam.type.equals(SPECIAL)) {
                        if (queryParam.specialCondition == null) {
                            throw new RuntimeException("Cannot build sql, Because the build type is SPECIAL but" +
                                    " condition is null");
                        }
                        if (queryParam.specialCondition) {
                            for (int i = 0; i < queryParam.values.length; i++) {
                                if (queryParam.values[i] instanceof Date) {
                                    query.setParameter(queryParam.paramNames[i],
                                            (Date) queryParam.values[i],
                                            TemporalType.DATE);
                                } else {
                                    query.setParameter(queryParam.paramNames[i], queryParam.values[i]);
                                }
                            }
                        }
                    }

                } else { // single situation
                    boolean cond;
                    if (queryParam.value instanceof String) {
                        cond = StringUtils.isNotEmpty((String) queryParam.value);
                    } else {
                        cond = queryParam.value != null;
                    }
                    if (cond) {
                        if (queryParam.value instanceof Date) {
                            query.setParameter(queryParam.paramName, (Date) queryParam.value, TemporalType.DATE);
                        } else {
                            Object value;
                            if (queryParam.type.equals(LIKE)) {
                                value = toLike((String) queryParam.value);
                            } else if (queryParam.type.equals(DOUBLE_LIKE)) {
                                value = toDoubleLike((String) queryParam.value);
                            } else {
                                value = queryParam.value;
                            }
                            query.setParameter(queryParam.paramName, value);
                        }
                    }
                }
            }
            return query;
        }
    } // inner class QueryBuilder

    private static final class QueryParam {
        Object value;
        Object[] values;
        String paramName;
        String[] paramNames;
        String sql;
        String type;
        String columnName;
        Boolean specialCondition;

        private QueryParam(Object value, String columnName, String type) {
            this.value = value;
            this.columnName = columnName;
            this.type = type;
            this.paramName = randomParamName(columnName);
            this.sql = buildSql(columnName, this.paramName, type);
        }

        /**
         * @param type only order_desc or order_asc
         */
        private QueryParam(String columnName, String type) {
            this.columnName = columnName;
            this.type = type;
            this.sql = buildOrderSql(columnName, type);
        }

        private QueryParam(boolean specialCondition, String sql, String[] paramNames, Object[] values) {
            this.specialCondition = specialCondition;
            this.type = SPECIAL;
            this.values = values;
            this.sql = sql;
            this.paramNames = paramNames;
        }

        private String randomParamName(String columnName) {
            String paramName = columnName.replaceAll("[._]", OpsuiConstant.EMPTY_STR);
            return paramName.toLowerCase() + RandomStringUtils.randomAlphabetic(3);
        }

        private String buildSql(String columnName, String paramName, String type) {
            switch (type) {
                case EQUALS:
                    return " and " + columnName + " = " + ":" + paramName;
                case LIKE:
                case DOUBLE_LIKE:
                    return " and " + columnName + " like " + ":" + paramName;
                default:
                    throw new RuntimeException("error occurs on SQLUtils: cannot buildSql for column : " + columnName);
            }
        }

        private String buildOrderSql(String columnName, String type) {
            switch (type) {
                case ORDER_ASC:
                    return " " + columnName + " asc ";
                case ORDER_DESC:
                    return " " + columnName + " desc ";
                default:
                    throw new RuntimeException("error occurs on SQLUtils: " +
                            "cannot buildOrderSql for column : " + columnName);
            }

        }

    } // inner class QueryParam

 

你可能感兴趣的:(后端)