动态SQL与静态SQL
一、静态SQL
1.静态SQL的定义
静态SQL是指在程序编译时就确定了的SQL语句,通常直接嵌入在应用程序代码中。
2.静态SQL的特点
- 在编译时就已经确定了SQL语句的结构
- 通常使用预编译方式执行
- SQL语句中的表和列名在编写时就已经固定
- 参数可以使用占位符(如?或:param),但整体结构不变
3.静态SQL的优点
-
性能较高(数据库可以预编译和缓存执行计划)
-
安全性好(不易受SQL注入攻击)
-
开发工具支持良好(语法检查、自动完成等)
-
易于调试和维护
4.静态SQL的缺点
-
灵活性差,无法根据运行时条件动态改变SQL结构
-
需要提前知道所有可能的查询形式
示例:
// JDBC静态SQL JAVA代码示例
String sql = ‘SELECT * FROM employees WHERE department_id = ?’;
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, deptId); # 第一个占位符的参数
ResultSet rs = stmt.executeQuery();
二、动态SQL
1.动态SQL的定义
动态SQL是指在程序运行时根据条件动态构建的SQL语句,其结构和内容可以在运行时变化。
2.动态SQL的特点
- SQL语句在运行时动态生成
- 可以根据应用程序的逻辑和用户输入构建不同的查询
- 通常通过字符串拼接方式构建SQL
3.动态SQL的优点
-
灵活性高,可以构建复杂的条件查询
-
能够适应多变的业务需求
-
可以实现通用数据访问层
4.动态SQL的缺点:
-
性能较低(每次可能需要重新编译SQL)
-
存在SQL注入的安全风险
-
调试和维护较困难
-
可能产生大量相似的SQL语句,影响数据库缓存效率
示例:
// 动态SQL示例
StringBuilder sql = new StringBuilder("SELECT * FROM employees WHERE 1=1 ");
if (deptId != null){sql.append("AND department_id = ").append(deptId);
}
if (salaryMin != null){sql.append(" And salary >= ").append(salaryMin);
}
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
三、使用场景对比
1.使用静态SQL的场景:
-
查询结构固定的CRUD操作
-
性能要求高的核心业务
-
安全性要求高的场景
-
简单的报表查询
2.使用动态SQL的场景:
-
复杂条件查询(如高级搜索功能)
-
通用数据访问框架
-
需要根据用户选择构建不同查询的应用
-
元数据驱动的应用
四、安全注意事项
动态SQL特别需要注意防范SQL注入攻击,应:
-
优先使用参数化查询
-
避免直接拼接用户输入
-
使用ORM框架提供的安全机制
-
对输入进行严格的验证和转义
现代ORM框架(如MyBatis、Hibernate)通常提供了安全的动态SQL构建方式,如MyBatis的、等标签。