Para mim, o SQL é uma parte fundamental (em muitos casos, a maioria) do código de lógica de negócios. Se você tentar separá-lo do código que opera nos dados retornados, é mais provável que você desequilibre a compreensibilidade e a capacidade de manutenção do código.
Na minha opinião, ler dados, processar dados, gravar dados, pesquisar dados ... são todas operações semelhantes e devem ser mantidas no mesmo local.
Se você começar a perceber uma duplicação de esforços nas consultas, talvez seja necessário uma visualização do banco de dados ou um objeto que possa encapsular esse aspecto do acesso ao banco de dados.
Outra dica é realmente ter um bom método de consulta ao banco de dados. No software que escrevo (PostgreSQL, MySQL, SQL Server), assegurei que a maior parte das minhas operações de consulta pudesse ocorrer como uma única declaração de código.
GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])
Essas são (aproximadamente) as principais chamadas de função que eu garanto que fazem parte do meu "objeto de conexão". Depende da linguagem, o que você realmente implementa, mas meu objetivo é mantê-la realmente, realmente simples e indolor.
Em resumo, trate o SQL como parte nativa da programação e não faça abstrações por abstração.