BATCH-1691: Implemented group by clause in paging queries
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -70,6 +71,7 @@ import org.springframework.util.ClassUtils;
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> implements InitializingBean {
|
||||
@@ -157,6 +159,7 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
|
||||
* Check mandatory properties.
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(dataSource);
|
||||
@@ -305,7 +308,13 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
|
||||
|
||||
private class PagingRowMapper implements RowMapper {
|
||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
startAfterValue = rs.getObject(queryProvider.getSortKeyWithoutAlias());
|
||||
if(StringUtils.hasText(queryProvider.getSortKey())) {
|
||||
startAfterValue = rs.getObject(queryProvider.getSortKey());
|
||||
}
|
||||
else {
|
||||
startAfterValue = rs.getObject(queryProvider.getSortKeyWithoutAlias());
|
||||
}
|
||||
|
||||
return rowMapper.mapRow(rs, rowNum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,6 +43,7 @@ import java.util.ArrayList;
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvider {
|
||||
@@ -54,12 +55,32 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
||||
private String whereClause;
|
||||
|
||||
private String sortKey;
|
||||
|
||||
private String groupClause;
|
||||
|
||||
private boolean ascending = true;
|
||||
|
||||
private int parameterCount;
|
||||
|
||||
private boolean usingNamedParameters;
|
||||
|
||||
/**
|
||||
* The setter for the group by clause
|
||||
*
|
||||
* @param SQL GROUP BY clause part of the SQL query string
|
||||
*/
|
||||
public void setGroupClause(String groupClause) {
|
||||
this.groupClause = groupClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* The getter for the group by clause
|
||||
*
|
||||
* @return SQL GROUP BY clause part of the SQL query string
|
||||
*/
|
||||
public String getGroupClause() {
|
||||
return this.groupClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param selectClause SELECT clause part of SQL query string
|
||||
@@ -194,6 +215,9 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
||||
if (whereClause != null) {
|
||||
sql.append(" WHERE ").append(whereClause);
|
||||
}
|
||||
if(groupClause != null) {
|
||||
sql.append(" GROUP BY ").append(groupClause);
|
||||
}
|
||||
List<String> namedParameters = new ArrayList<String>();
|
||||
parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);
|
||||
if (namedParameters.size() > 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,8 +18,12 @@ package org.springframework.batch.item.database.support;
|
||||
|
||||
/**
|
||||
* Postgres implementation of a {@link org.springframework.batch.item.database.PagingQueryProvider} using database specific features.
|
||||
*
|
||||
* When using the groupClause, this implementation expects all select fields not used in aggregate functions to be included in the
|
||||
* groupClause (the provider does not add them for you).
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public class PostgresPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,6 +44,7 @@ import org.springframework.util.StringUtils;
|
||||
* types are given by the {@link DatabaseType} enum.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
*/
|
||||
public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
|
||||
|
||||
@@ -56,6 +57,8 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
|
||||
private String whereClause;
|
||||
|
||||
private String selectClause;
|
||||
|
||||
private String groupClause;
|
||||
|
||||
private String sortKey;
|
||||
|
||||
@@ -76,6 +79,13 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
|
||||
providers.put(SQLSERVER,new SqlServerPagingQueryProvider());
|
||||
providers.put(SYBASE,new SybasePagingQueryProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SQL GROUP BY clause part of the SQL query string
|
||||
*/
|
||||
public void setGroupClause(String groupClause) {
|
||||
this.groupClause = groupClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param databaseType the databaseType to set
|
||||
@@ -154,6 +164,9 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
|
||||
if (StringUtils.hasText(selectClause)) {
|
||||
provider.setSelectClause(selectClause);
|
||||
}
|
||||
if(StringUtils.hasText(groupClause)) {
|
||||
provider.setGroupClause(groupClause);
|
||||
}
|
||||
|
||||
provider.init(dataSource);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility class that generates the actual SQL statements used by query
|
||||
* providers.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SqlPagingQueryUtils {
|
||||
@@ -42,6 +45,7 @@ public class SqlPagingQueryUtils {
|
||||
sql.append("SELECT ").append(provider.getSelectClause());
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
buildWhereClause(provider, remainingPageQuery, sql);
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
sql.append(" " + limitClause);
|
||||
@@ -65,6 +69,7 @@ public class SqlPagingQueryUtils {
|
||||
sql.append("SELECT ").append(topClause).append(" ").append(provider.getSelectClause());
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
buildWhereClause(provider, remainingPageQuery, sql);
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
|
||||
@@ -104,6 +109,7 @@ public class SqlPagingQueryUtils {
|
||||
sql.append("SELECT * FROM (SELECT ").append(selectClause).append(", ROWNUM as TMP_ROW_NUM");
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
buildWhereClause(provider, remainingPageQuery, sql);
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
sql.append(") WHERE ").append(rowNumClause);
|
||||
@@ -125,6 +131,7 @@ public class SqlPagingQueryUtils {
|
||||
.append(", ROWNUM as TMP_ROW_NUM");
|
||||
sql.append(" FROM (SELECT ").append(innerSelectClause).append(" FROM ").append(provider.getFromClause());
|
||||
buildWhereClause(provider, remainingPageQuery, sql);
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
sql.append(")) WHERE ").append(rowNumClause);
|
||||
@@ -146,6 +153,7 @@ public class SqlPagingQueryUtils {
|
||||
sql.append("SELECT ").append(provider.getSortKey()).append(" AS SORT_KEY");
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
sql.append(" " + limitClause);
|
||||
@@ -166,6 +174,7 @@ public class SqlPagingQueryUtils {
|
||||
sql.append("SELECT ").append(topClause).append(" ").append(provider.getSortKey()).append(" AS SORT_KEY");
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
||||
buildGroupByClause(provider, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKeyWithoutAlias());
|
||||
buildAscendingClause(provider, sql);
|
||||
|
||||
@@ -202,5 +211,12 @@ public class SqlPagingQueryUtils {
|
||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildGroupByClause(AbstractSqlPagingQueryProvider provider, StringBuilder sql) {
|
||||
if(StringUtils.hasText(provider.getGroupClause())) {
|
||||
sql.append(" GROUP BY ");
|
||||
sql.append(provider.getGroupClause());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
* Copyright 2006-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import org.springframework.util.StringUtils;
|
||||
* Apache Derby version 10.4.1.3
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
@@ -38,6 +39,7 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
sql.append(getOverSubstituteClauseStart());
|
||||
sql.append(" FROM ").append(getFromClause()).append(
|
||||
getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(getGroupClause() == null ? "" : " GROUP BY " + getGroupClause());
|
||||
sql.append(getOverSubstituteClauseEnd());
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ").append(extractTableAlias()).append(
|
||||
"ROW_NUMBER <= ").append(pageSize);
|
||||
@@ -79,6 +81,7 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
sql.append(" < ");
|
||||
}
|
||||
sql.append(getSortKeyPlaceHolder());
|
||||
sql.append(getGroupClause() == null ? "" : " GROUP BY " + getGroupClause());
|
||||
sql.append(getOverSubstituteClauseEnd());
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ").append(extractTableAlias()).append(
|
||||
"ROW_NUMBER <= ").append(pageSize);
|
||||
@@ -102,6 +105,7 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
sql.append(getOverSubstituteClauseStart());
|
||||
sql.append(" FROM ").append(getFromClause());
|
||||
sql.append(getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(getGroupClause() == null ? "" : " GROUP BY " + getGroupClause());
|
||||
sql.append(getOverSubstituteClauseEnd());
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ").append(extractTableAlias()).append(
|
||||
"ROW_NUMBER = ").append(lastRowNum);
|
||||
|
||||
Reference in New Issue
Block a user