Tienes diferentes formas de organizar las consultas, para tomar una decisión ten en mente factores como: código legible, mantenimiento, seguridad, escalabilidad, etc. En resumen, las opciones son:
1. Sentencias sql dentro del código de la aplicación construidas en forma dinámica (con vistas o tablas). Esta opción es la más común en la comunidad open source, ya que si codificas las consultas en ANSI SQL puedes tener, a bajo costo, un sistema que funcione en diferentes motores. Lo malo es que es un diseño viejo, en general no se recomienda por ser difícil de leer, costosa en mantenimiento y tiende a producir errores por consultas mal formadas, problema que no se detecta hasta que el sistema está en producción.
Código:
private String getEmpleadoById(int empId, String orderBy) {
StringBuilder query = new StringBuilder();
query.append("SELECT * FROM empleados ");
if(empId != null) {
query.append(" WHERE id=" + empId);
}
if(orderBy != null) {
query.append(" ORDER BY " + orderBy);
}
return query.toString();
}
//llamada al método que devuelve la consulta sql
getEmpleadoById(4,null); //un empleado
getEmpleadoById(null,"apellido"); //todos los empleados ordenados por apellido
2. Sentencias sql dentro de procedimientos almacenados (con o sin sql dinámico). Puede que sea la opción más utilizada, es fácil de leer, mantener, óptima en rendimiento y muy ordenada porque separa claramente la capa de datos. Tiene dos problemas fundamentales, es dependiente de la base de datos, si se quiere migrar el sistema a otro motor hay que recodificar todos los procedimientos, y por otro lado, te limita a elegir un motor que soporte procedimientos, inviable si trabajas con aplicaciones que necesitan motores como SQLite (ej: firefox).
Código:
create procedure getEmpleadoById(@empId numeric(8))
as
select *
from empleados
where id = @empId or @empId is null
go
exec getEmpleadoById 4 --un empleado
exec getEmpleadoById null --todos los empleados
3. Por último, un ORM, esto te permite hacer un mapeo de clases de lenguajes orientados a objetos hacia tablas en motores relacionales y así generar en forma automática las consultas sql. Con esta opción codificas una sola vez y el ORM se encarga de adaptar las consultas en función del motor al que está conectado (diferentes ORMs soportan diferentes motores) lo que te da portabilidad en forma inmediata, también separa claramente la capa de datos, tiene buen rendimiento porque genera buenas consultas, y en parte libera al programador de tener que saber SQL. En general, la contra está en aprender cómo funcionan, en la instalación y deploy, pueden tener limitaciones y no resolver consultas complejas, están ligados al lenguaje de programación (Doctrine para php, Hibernate para java, Entity Framework para .net, etc) y al haber varias opciones para cada uno, el análisis de cual implementar puede ser complejo.
Código:
private String getEmpleadoById(int empId, String orderBy) {
SelectBuilder query = new SelectBuilder();
query.select("*").from("empleados");
if(empId != null) {
query.where().and("id=#",empId);
}
if(orderBy != null){
query.orderBy(orderBy);
}
return query.toSql();
}
//llamada al método que devuelve la consulta sql
getEmpleadoById(4,null); //un empleado
getEmpleadoById(null,"apellido"); //todos los empleados ordenados por apellido
No hay receta única, mejor o peor, tendrás que evaluar pros y contra, hacer pruebas y ver que alternativa te da mejores resultados.
Saludos